#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <assert.h>
#include <math.h>
/* 
// A DECOMMENTER POUR L'INTERFACE 
#include <raylib.h>
*/

unsigned int renverse(unsigned int a)
{
    // TODO
}

struct data {
    int class;
    unsigned char pixels[784]; // 28 * 28
};
typedef struct data data;

struct dataset {
    int nimages;
    data *images;
};
typedef struct dataset dataset;

dataset read_dataset(char *images_file, char *labels_file)
{
    // TODO
}

double distance(data d1, data d2)
{
    // TODO
}

int *k_voisins(int k, dataset dt, data d)
{
    // TODO
}

int k_plus_proches_aux(int k, dataset dt, int *proches)
{
    // TODO
}

int k_plus_proches(int k, dataset dt, data d)
{
    // TODO
}

int main(void) 
{
    dataset training = read_dataset(
        "data/train-images-idx3-ubyte",
        "data/train-labels-idx1-ubyte");
    dataset tests = read_dataset(
        "data/t10k-images-idx3-ubyte",
        "data/t10k-labels-idx1-ubyte");

    int classe = k_plus_proches(5, training, tests.images[0]);
    printf("On a reconnu la classe %d, on aurait du avoir %d\n",
        classe, tests.images[0].class);

    // TODO des print des valeurs ou des images ici
    
    /*
    // A DECOMMENTER POUR L'INTERFACE 

    data scribble;
    memset(scribble.pixels, 0, 28 * 28);

    const int screenWidth = 800;
    const int screenHeight = 800;

    InitWindow(screenWidth, screenHeight, "KNN");

    Vector2 ballPosition = { -100.0f, -100.0f };
    Color ballColor = DARKBLUE;

    int current_test = 0;

    int k = 3;
    int *voisins = malloc(sizeof(data) * k);

    for(int i = 0; i < k; i++) {
        voisins[i] = i;
    }

    SetTargetFPS(60);               // Set our game to run at 60 frames-per-second
    //---------------------------------------------------------------------------------------

    while (!WindowShouldClose())    // Detect window close button or ESC key
    {
        ballPosition = GetMousePosition();

        int x = ((int)ballPosition.x - 28 * 4) / 20;
        int y = ((int)ballPosition.y) / 20;

        if (0 <= x && x < 28 && 0 <= y && y < 28)
        {
            if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) 
                for(int dx = 0; dx < 2; dx++)
                    for(int dy = 0; dy < 2; dy++)
                        if (0 <= x+dx && x+dx < 28 && 0 <= y+dy && y+dy < 28)
                            scribble.pixels[(y+dy) * 28 + x + dx] = 255;
            if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT)) 
                scribble.pixels[y * 28 + x] = 0;
        }

        if (IsKeyPressed(KEY_R)) {
            free(voisins);
            voisins = k_voisins(k, training, scribble);
        }
        if (IsKeyPressed(KEY_C)) {
            memset(scribble.pixels, 0, 28 * 28);
            free(voisins);
            voisins = k_voisins(k, training, scribble);
        }
        if (IsKeyPressed(KEY_T)) {
            memcpy(scribble.pixels, tests.images[current_test].pixels,
                    28 * 28);
            free(voisins);
            voisins = k_voisins(k, training, scribble);
            current_test++;
        }

        // Draw
        //----------------------------------------------------------------------------------
        BeginDrawing();

            ClearBackground(RAYWHITE);

            for(int x = 0; x < 28; x++) {
                for(int y = 0; y < 28; y++) {
                    char v = 255 - scribble.pixels[y * 28 + x];
                    Color c = (Color){ v, v, v, 255 };
                    DrawRectangle(28 * 4 + 20*x, 20*y, 
                        20, 20, c);
                }
            }

            for(int i = 0; i < k; i++) {
                data im = training.images[voisins[i]];
                for(int x = 0; x < 28; x++) {
                    for(int y = 0; y < 28; y++) {
                        int v1 = scribble.pixels[y * 28 + x];
                        int v2 = im.pixels[y * 28 + x];
                        int dv = abs(v1 - v2) / 2;
                        Color c = (Color){ v2, dv, 0, 255 };
                        DrawRectangle(4*x, 4*(y+i*28), 4, 4, c);
                    }
                }
            }

            DrawCircleV(ballPosition, 5, ballColor);

            char buf[1000];
            sprintf(buf, 
                "Voisins %d (%f) [%d], %d (%f) [%d], %d (%f) [%d]",
                training.images[voisins[0]].class,
                distance(training.images[voisins[0]], scribble),
                voisins[0],
                training.images[voisins[1]].class,
                distance(training.images[voisins[1]], scribble),
                voisins[1],
                training.images[voisins[2]].class,
                distance(training.images[voisins[2]], scribble),
                voisins[2]);
            DrawText(buf, 10, 28 * 20 + 10, 20, DARKGRAY);
            sprintf(buf,
                    "C'est un %d !",
                    k_plus_proches_aux(k, training, voisins));
            DrawText(buf, 10, 28 * 20 + 30, 50, DARKGRAY);

        EndDrawing();
    }

    CloseWindow();
    */
}
