#include <stdlib.h>
#include <stdio.h>

#include "canvas.h"

Canvas* canvas_create(int width, int height) {
    Canvas* c = calloc(1, sizeof(Canvas));

    c->width  = width;
    c->height = height;
    
    c->cells  = calloc(height+1, sizeof(char*));
    for (int row = 0; row < height; row++) {
        c->cells[row] = calloc(width+1, sizeof(char));
    }

    canvas_clear(c);

    return c;
}

void canvas_destroy(Canvas* canvas) {
    for (int row = 0; row < canvas->height; row++) {
        free(canvas->cells[row]);
    }
    free(canvas->cells);
    free(canvas);
}

void canvas_clear(Canvas* canvas) {
    for (int row = 0; row < canvas->height; row++) {
        for (int col = 0; col < canvas->width; col++) {
            canvas->cells[row][col] = ' ';
        }
    }
}

void canvas_present(Canvas* canvas) {
    clear_screen();

    for (int row = 0; row < canvas->height; row++) {
        printf("%s\n", canvas->cells[row]);
    }
}

void canvas_cell(Canvas* canvas, int x, int y, char c) {
    if (0 <= x && x < canvas->width) {
        if (0 <= y && y < canvas->height) {
            canvas->cells[y][x] = c;
        } else {
            printf("ERROR: (%d, %d) goes outside height of canvas which is %d.\n", x, y, canvas->height);
            exit(1);
        }
    } else {
        printf("ERROR: (%d, %d) goes outside width of canvas which is %d.\n", x, y, canvas->width);
        exit(1);
    }
}

void canvas_text(Canvas* canvas, int x, int y, char* string) {
    if (!string) return;
    char c;
    while ((c = *string) != '\0') {
        canvas_cell(canvas, x, y, c);
        x++;
        string++;
    }
}

void canvas_rect(Canvas* canvas, int x, int y, int w, int h) {
    for (int row = y; row < y + h; row++) {
        canvas_cell(canvas, x,   row, '|');
        canvas_cell(canvas, x+w, row, '|');
    }
    for (int col = x; col < x + w; col++) {
        canvas_cell(canvas, col, y,   '-');
        canvas_cell(canvas, col, y+h, '-');
    }
    canvas_cell(canvas, x,   y, '+');
    canvas_cell(canvas, x+w, y, '+');
    canvas_cell(canvas, x,   y+h, '+');
    canvas_cell(canvas, x+w, y+h, '+');
}



// Animation

void clear_screen() {
#if defined(LINUX) || defined(__linux__) || defined(UNIX) || defined(unix)
    // Print clear-screen-character
    printf("\033[H\033[J");
#elif defined(OS_WINDOWS) || defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__) || defined(__MINGW64)
    // Call external program 'cls'
    system("cls");
#else
    // Fallback: Clear the screen with newlines
    for (int i = 0; i < CLEAR_HEIGHT; i++) {
        printf("\n");
    }
#endif
}
