// Copyright (c) 2023-2026 Chris (boreddevnl)
// This software is released under the GNU General Public License v3.0. See LICENSE file for details.
// This header needs to maintain in any file it is present in, as per the GPL license terms.
#include "syscall.h"
#include "libui.h"
#include <stddef.h>

static uint32_t ansi_to_boredos_color(int code) {
    uint32_t default_color = 0xFFFFFFFF;

    switch (code) {
        case 0: return default_color;
        case 30: return 0xFF000000; // Black
        case 31: return 0xFFFF4444; // Red
        case 32: return 0xFF6A9955; // Green
        case 33: return 0xFFFFFF00; // Yellow
        case 34: return 0xFF569CD6; // Blue
        case 35: return 0xFFB589D6; // Magenta
        case 36: return 0xFF4EC9B0; // Cyan
        case 37: return 0xFFCCCCCC; // White
        case 90: return 0xFF808080; // Bright Black (Gray)
        case 91: return 0xFFFF6B6B; // Bright Red
        case 92: return 0xFF78DE78; // Bright Green
        case 93: return 0xFFFFFF55; // Bright Yellow
        case 94: return 0xFF87CEEB; // Bright Blue
        case 95: return 0xFFFF77FF; // Bright Magenta
        case 96: return 0xFF66D9EF; // Bright Cyan
        case 97: return 0xFFFFFFFF; // Bright White
        default: return default_color;
    }
}

static void draw_ansi_string(ui_window_t win, int x, int y, const char *str) {
    uint32_t current_color = 0xFFFFFFFF;
    int current_x = x;
    char segment[256];
    int seg_idx = 0;

    while (*str) {
        if (*str == '\033' && *(str + 1) == '[') {
            if (seg_idx > 0) {
                segment[seg_idx] = 0;
                ui_draw_string(win, current_x, y, segment, current_color);
                current_x += seg_idx * 8;
                seg_idx = 0;
            }

            str += 2;
            int code = 0;
            while (*str >= '0' && *str <= '9') {
                code = code * 10 + (*str - '0');
                str++;
            }
            if (*str == 'm') {
                current_color = ansi_to_boredos_color(code);
                str++;
            }
        } else {
            segment[seg_idx++] = *str++;
        }
    }

    if (seg_idx > 0) {
        segment[seg_idx] = 0;
        ui_draw_string(win, current_x, y, segment, current_color);
    }
}

static void draw_ascii_logo(ui_window_t win, int x, int y) {
    const char *logo[] = {
        "\033[35m==================== \033[97m__    ____  ____ \033[0m",
        "\033[35m=================== \033[97m/ /_  / __ \\/ ___\\\033[0m",
        "\033[34m================== \033[97m/ __ \\/ / / /\\___ \\\033[0m",
        "\033[34m================= \033[97m/ /_/ / /_/ /____/ /\033[0m",
        "\033[36m================ \033[97m/_.___/\\____//_____/ \033[0m",
        "\033[36m===============                       \033[0m",
        NULL
    };

    for (int i = 0; logo[i] != NULL; i++) {
        draw_ansi_string(win, x, y + (i * 10), logo[i]);
    }
}

static void about_paint(ui_window_t win) {
    int w = 340;
    int h = 240;
    
    
    int offset_x = 15;
    int offset_y = 35;
    
    draw_ascii_logo(win, 14, offset_y);
    
    // Version info
    ui_draw_string(win, offset_x, offset_y + 105, "BoredOS 'Retrowave'", 0xFFFFFFFF);
    ui_draw_string(win, offset_x, offset_y + 120, "BoredOS Version 1.65", 0xFFFFFFFF);
    ui_draw_string(win, offset_x, offset_y + 135, "Kernel Version 3.0.1", 0xFFFFFFFF);
    
    // Copyright
    ui_draw_string(win, offset_x, offset_y + 150, "(C) 2026 boreddevnl.", 0xFFFFFFFF);
    ui_draw_string(win, offset_x, offset_y + 165, "All rights reserved.", 0xFFFFFFFF);
    
    ui_mark_dirty(win, 0, 0, w, h);
}

int main(void) {
    ui_window_t win_about = ui_window_create("About BoredOS", 250, 180, 340, 240);
    
    about_paint(win_about);
    
    gui_event_t ev;
    while (1) {
        if (ui_get_event(win_about, &ev)) {
            if (ev.type == GUI_EVENT_PAINT) {
                about_paint(win_about);
            } else if (ev.type == GUI_EVENT_CLOSE) {
                sys_exit(0);
            }
        } else {
            // Avoid high CPU usage
            for(volatile int i=0; i<10000; i++);
        }
    }
    
    return 0;
}
