#include <lib/console.h>

#include <lib/font.h>
#include <drivers/vga/vga.h>

static psf_font_t* font;

static uint32_t console_row;
static uint32_t console_col;
static uint32_t console_text_color;
static uint32_t console_backgrnd_color;

static uint32_t console_total_rows;
static uint32_t console_total_cols;

static void write_vga_char(char c) {
    uint32_t vga_pitch = vga_get_pitch();
    uint8_t* glyph = (uint8_t*)font->glyphs + (c * font->hdr->charsz);

    for (uint32_t y = 0; y < font->hdr->charsz; y++) {
        uint8_t bits = glyph[y];
        uint32_t* row = (uint32_t*)((uintptr_t)VGA_FRAMEBUFFER + ((console_row + y) * vga_pitch));
        for (int x = 0; x < 8; x++) {
            if (bits & (0b10000000 >> x)) {
                row[console_col + x] = console_text_color;
            }
        }
    }
}

void set_console_font(const char* path) {
    font = load_font(path);

    uint32_t scrn_height = vga_get_height();
    uint32_t scrn_width = vga_get_width();
    if (scrn_width == 0 || scrn_height == 0) return;

    console_total_rows = scrn_height / font->hdr->charsz;
    console_total_cols = scrn_width / 8;
}

void set_console_fg(uint32_t color) {
    console_text_color = color;
}

void set_console_bg(uint32_t color) {
    console_backgrnd_color = color;
}

void console_init() {
    console_row = 0;
    console_col = 0;
    set_console_fg(0xFFFFFFFF);
    set_console_bg(0x000000FF);
    vga_clear_scrn(console_backgrnd_color);
}

void console_putchar(char c) {
    switch (c) {
    case '\n':
        console_row++;
        console_col = 0;

        if (console_row >= console_total_rows) console_row = 0;
        return;
    }

    write_vga_char(c);

    console_col++;
    if (console_col >= console_total_cols) console_row++; console_col = 0;
    if (console_row >= console_total_rows) console_row = 0;
}