#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "imageInput.h"

#define BUFFER_SIZE 100
#define FILE_HEADER_STRING "__info2_image_file_format__"

// Funktionen müssen noch auf Teilfunktionen 
// übersichtlich aufgeteilt werden!

// TODO Implementieren Sie geeignete Hilfsfunktionen für das Lesen der Bildserie aus einer Datei
int readStatusInfo(FILE **source, char *const headerString, unsigned int *const imageCount, int *const imageWidth, int *const imageHeight, int const amountToRead);
void readImagedata(FILE **source, char *const imageBuffer, char *const labelBuffer,int const imageCount ,int const amountToRead);


// TODO Vervollständigen Sie die Funktion readImages unter Benutzung Ihrer Hilfsfunktionen
GrayScaleImageSeries *readImages(const char *path)
{
    GrayScaleImageSeries *series = NULL;

    // selbst geschriebene Variablen
    FILE                    *readSource;
    int                     i                           = 0;
    unsigned int            numberOfBytesToRead         = 0;
    const unsigned int      amountOfStatusInfoToRead    = 1;
    char                    headerString[sizeof("__info2_image_file_format__")];


    readSource = fopen(path, "rb");

    if (readSource != NULL)
    {

        numberOfBytesToRead = readStatusInfo(&readSource, headerString, &series->count, &series->images->width, &series->images->height, amountOfStatusInfoToRead);
        
        series->images->buffer  = calloc((series->count) * numberOfBytesToRead, sizeof(GrayScalePixelType));
        series->labels          = calloc((series->count),                       sizeof(&(series->labels)));

        readImagedata(&readSource, series->images->buffer, series->labels, series->count, numberOfBytesToRead);
    }

    fclose(readSource);
    

    return series;
}

// TODO Vervollständigen Sie die Funktion clearSeries, welche eine Bildserie vollständig aus dem Speicher freigibt
void clearSeries(GrayScaleImageSeries *series)
{
    int i = 0;


    // Write NULL into all memory spaces
    for (i = 0; i < ((series->count) * (series->images->width) * (series->images->height)); i++)
    {
        *(series->images->buffer + i * (series->images->width) * (series->images->height)) = '\0';
    }
    for (i = 0; i < (series->count); i++)
    {
        *(series->labels + i) = '\0';
    }
    series->count           = 0;
    series->images->width   = 0;
    series->images->height  = 0;

    // Closse all allocated memory
    // AND write NULL into every pointer
    // so they can't be accessed
    free(series->images->buffer);
    free(series->labels);
    series->images->buffer  = NULL;
    series->images          = NULL;
    series->labels          = NULL;
    free(series);
    series                  = NULL;

}


//  reads string, pictureCount, pictureWidth, pictureHight
int readStatusInfo(FILE **source, char *const headerString, unsigned int *const imageCount, int *const imageWidth, int *const imageHeight, int const amountToRead)
{
    int bytesToRead = 0;

    fread(headerString, sizeof(*headerString),   amountToRead, *source);
    fread(imageCount,   sizeof(*imageCount),     amountToRead, *source);
    fread(imageWidth,   sizeof(*imageWidth),     amountToRead, *source);
    fread(imageHeight,  sizeof(*imageHeight),    amountToRead, *source);

    bytesToRead = (*imageWidth) * (*imageHeight);

    return bytesToRead;
}

//  reads the imagebytes and the label of all images
void readImagedata(FILE **source, char *const imageBuffer, char *const labelBuffer,int const imageCount ,  int const amountOfBytes)
{
    int i = 0;

    for (i = 0; i <= imageCount; i++)
    {
    fread((imageBuffer + i * amountOfBytes),    sizeof(&(imageBuffer)), amountOfBytes,  *source);
    fread((labelBuffer + i),                    sizeof(&(labelBuffer)), 1,              *source);
    }
}

