/*************************
 * Owen Sullivan
 * CPSC 2310 Fall 22
 * Lab 8
 * Username: opsulli
 * Instructor: Dr. Yvon Feaster
*************************/

#include "functions.h"

/* Parameters: inFile - FILE pointer that points to all of the image data
                        in the input PPM file
 * Return:     header - header_t object containing header data
 * This function reads the header data from the input PPM file and returns
 * a struct with all the header data (minus removed comments).
*/
header_t readHeader(FILE *inFile) {

    buffer_t buffer;
    
    // Read the first line (until a new line) and store as type buffer
    fscanf(inFile, " %[^\n]*c", buffer.type);

    // Read the next line (until a new line) and store as width buffer
    fscanf(inFile, " %[^\n]*c", buffer.width);
    // If the first character in the width buffer is not a digit, read
    // the next line (assuming last read line is entirely a comment)
    while (!isdigit(buffer.width[0])) {

        // Skip one place ahead in the input file
        fseek(inFile, 1, SEEK_CUR);
        fscanf(inFile, " %[^\n]%*c", buffer.width);

    }

    // Read the next line (until a new line) and store as height buffer
    fscanf(inFile, " %[^\n]*c", buffer.height);
    // If the first character in the height buffer is not a digit, read
    // the next line (assuming last read line is entirely a comment)
    while (!isdigit(buffer.height[0])) {

        // Skip one place ahead in the input file
        fseek(inFile, 1, SEEK_CUR);
        fscanf(inFile, " %[^\n]%*c", buffer.height);

    }

    // Read the next line (until a new line) and store as maxColor buffer
    fscanf(inFile, " %[^\n]*c", buffer.maxColor);
    // If the first character in the maxColor buffer is not a digit, read
    // the next line (assuming last read line is entirely a comment)
    while (!isdigit(buffer.maxColor[0])) {

        // Skip one place ahead in the input file
        fseek(inFile, 1, SEEK_CUR);
        fscanf(inFile, " %[^\n]%*c", buffer.maxColor);

    }
    
    // Create a header_t object and set it to the return value
    // of discardComments
    header_t header = discardComments(buffer);

    return header;

}

/* Parameters: outFile - FILE pointer that points to the new PPM image being
                         created
               header - header_t object containing header data
 * Return:     N/A - function is of type void
 * This function writes the header data from the input PPM file (minus removed
 * comments) to a new PPM file.
*/
void writeHeader(FILE *outFile, header_t header) {

    // Print each value in header to the output file
    fprintf(outFile, "%s\n", header.type);
    fprintf(outFile, "%d\n", header.width);
    fprintf(outFile, "%d\n", header.height);
    fprintf(outFile, "%d\n", header.maxColor);

}

/* Parameters: comments - buffer_t object containing input header data which
                          may include comments
 * Return:     header - header_t object containing input header data (minus
                        removed comments)
 * This function finds and removes comments from PPM header data.
*/
header_t discardComments(buffer_t comments) {

    buffer_t noComments;
    header_t header;

    // Loop through the characters in type buffer
    for (int i = 0; i < strlen(comments.type); i++) {

        // Break when a comment has been found
        if (comments.type[i] == '#' || isspace(comments.type[i])) {

            break;

        }

        // Update noComments buffer with current character
        noComments.type[i] = comments.type[i];

    }
    // Append the null character to noComments type buffer
    noComments.type[2] = '\0';
    // Copy the noComments type buffer to the header type
    strcpy(header.type, noComments.type);

    // Loop through the characters in width buffer
    for (int i = 0; i < strlen(comments.width); i++) {

        // Break when a comment has been found
        if (comments.width[i] == '#' || isspace(comments.width[i])) {

            break;

        }

        // Update noComments buffer with current character
        noComments.width[i] = comments.width[i];

    }
    // Set the header width to the converted integer of the
    // noComments width buffer
    header.width = atoi(noComments.width);

    // Loop through the characters in height buffer
    for (int i = 0; i < strlen(comments.height); i++) {

        // Break when a comment has been found
        if (comments.height[i] == '#' || isspace(comments.height[i])) {

            break;

        }

        // Update noComments buffer with current character
        noComments.height[i] = comments.height[i];

    }
    // Set the header width to the converted integer of the
    // noComments height buffer
    header.height = atoi(noComments.height);

    // Loop through the characters in maxColor buffer
    for (int i = 0; i < strlen(comments.maxColor); i++) {

        // Break when a comment has been found
        if (comments.maxColor[i] == '#' || isspace(comments.maxColor[i])) {

            break;

        }

        // Update noComments buffer with current character
        noComments.maxColor[i] = comments.maxColor[i];

    }
    // Set the header width to the converted integer of the
    // noComments maxColor buffer
    header.maxColor = atoi(noComments.maxColor);

    return header;

}