#include <graphics.h>
#include <js.h>
#include <stdint.h>
#include <stdlib.h>
#include <time.h>

#define WIDTH 512
#define HEIGHT 512

static uint8_t* field;
static uint8_t* next_field;
static image_data_t image_data;

static int count_neighbours(int x, int y);

GRAPHICS_FRAME {
    for (int y = 0; y < HEIGHT; y++) {
        for (int x = 0; x < WIDTH; x++) {
            int count = count_neighbours(x, y);
            uint8_t current_cell = field[x + y * WIDTH];
            uint8_t next_cell = current_cell;
            // if (current_cell && count < 2) {
            //     next_cell = 0;
            // } else if (current_cell && count > 3) {
            //     next_cell = 0;
            // } else if (!current_cell && count == 3) {
            //     next_cell = 1;
            // }

            next_cell = (count + current_cell) >= 5;

            next_field[x + y * WIDTH] = next_cell;
        }
    }

    for (int i = 0; i < WIDTH * HEIGHT; i++) {
        field[i] = next_field[i];
        uint8_t px = (!field[i]) * 255;

        image_data.pixels[i].r = px;
        image_data.pixels[i].g = px;
        image_data.pixels[i].b = px;
    }
}

static int count_neighbours(int x, int y) {
    int count = 0;
    for (int i = -1; i <= 1; i++) {
        for (int j = -1; j <= 1; j++) {
            if (i == 0 && j == 0) {
                continue;
            }

            int xx = (x + i + WIDTH) % WIDTH;
            int yy = (y + j + HEIGHT) % HEIGHT;

            if (field[xx + yy * WIDTH]) {
                count++;
            }
        }
    }
    return count;
}

GRAPHICS_INIT {
    srand((uint32_t)time(NULL));
    field = malloc(WIDTH * HEIGHT);
    next_field = malloc(WIDTH * HEIGHT);
    image_data = image_create(WIDTH, HEIGHT);

    for (int i = 0; i < WIDTH * HEIGHT; i++) {
        field[i] = rand() & 1;
    }

    return &image_data;
}
