/************************* 
 * Owen Sullivan
 * CPSC 2310-002
 * opsulli@clemson.edu
*************************/

#include "ppm.h"

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);

    // 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])) {

        fscanf(inFile, " %[^ ,^\n]*c", buffer.width);

    }

    // 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])) {

        fscanf(inFile, " %[^ ,^\n]*c", buffer.height);

    }

    // 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])) {

        fscanf(inFile, " %[^ ,^\n]*c", buffer.maxColor);

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

    // Read the remaining characters up till a new line, in case there is 
    // a bad comment preventing the pixel data from being read
    char remaining[100];
    fscanf(inFile, "%[^\n]*c", remaining);

    return header;

}

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);

}

header_t convertHeader(buffer_t buffer) {

    header_t header;

    // Copy the type buffer to the header type
    strcpy(header.type, buffer.type);

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

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

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

    return header;

}

pixel_t **allocateMemory(int width, int height) {

    // Create a double pointer
    pixel_t **ptr = malloc(height * sizeof(pixel_t *));

    for (int i = 0; i < height; i++) {

        // Allocate memory for each single pointer index
        ptr[i] = malloc(width * sizeof(pixel_t));

    }

    return ptr;

}

void freeMemory(pixel_t **ptr, int height) {

    for (int i = 0; i < height; i++) {

        // Free each single pointer index
        free(ptr[i]);

    }

    // Free the main double pointer
    free(ptr);

}

void readImage(FILE *inFile, pixel_t **image, int width, int height) {

    // Move file pointer forward by one character to account for
    // new line after maxColor header value
    fseek(inFile, 1, SEEK_CUR);

    // Loop for every row of pixels
    for (int i = 0; i < height; i++) {

        // Loop for every column of pixels
        for (int j = 0; j < width; j++) {

            // Read r, g, and b value as an unsigned char to the next index
            // in the pixel pointer array
            fread(&image[i][j].r, sizeof(unsigned char), 1, inFile);
            fread(&image[i][j].g, sizeof(unsigned char), 1, inFile);
            fread(&image[i][j].b, sizeof(unsigned char), 1, inFile);

        }

    }

}

void writeImage(FILE *outFile, pixel_t **image, int width, int height) {

    // Loop for every row of pixels
    for (int i = 0; i < height; i++) {

        // Loop for every column of pixels
        for (int j = 0; j < width; j++) {

            // Print each r, g, and b value to the output file
            fprintf(outFile, "%c", image[i][j].r);
            fprintf(outFile, "%c", image[i][j].g);
            fprintf(outFile, "%c", image[i][j].b);

        }

    }

}