/*
    * libhello.cpp
    * Sample shared GUI library for MontaukOS
    * Creates a window and renders text as a demo of the shared library + GUI system
    * Copyright (c) 2026 Daniel Hammer
*/

#include <montauk/syscall.h>
#include <gui/truetype.hpp>

// Heap allocation test - allocates, writes, reads, frees
// Returns 0 on success, -1 on failure
extern "C" int hello_malloc_test() {
    // Test 1: Allocate 256 bytes
    void* buf = montauk::malloc(256);
    if (!buf) {
        montauk::print("  [libhello] malloc(256) failed\n");
        return -1;
    }

    // Test 2: Write a pattern and verify it
    uint8_t* bytes = (uint8_t*)buf;
    for (int i = 0; i < 256; i++) {
        bytes[i] = (uint8_t)(i & 0xFF);
    }
    for (int i = 0; i < 256; i++) {
        if (bytes[i] != (uint8_t)(i & 0xFF)) {
            montauk::print("  [libhello] read verification failed\n");
            montauk::mfree(buf);
            return -1;
        }
    }

    montauk::mfree(buf);
    return 0;
}

extern "C" int hello_run() {
    // Create window
    static constexpr int kInitialWidth = 320;
    static constexpr int kInitialHeight = 200;
    static constexpr uint32_t kBackgroundColor = 0xFFFFFFFF;
    Montauk::WinCreateResult wres;
    if (montauk::win_create("libhello Demo", kInitialWidth, kInitialHeight, &wres) < 0 || wres.id < 0) {
        return -1;
    }

    int winId = wres.id;
    uint32_t* pixels = (uint32_t*)(uintptr_t)wres.pixelVa;
    int width = kInitialWidth;
    int height = kInitialHeight;

    gui::TrueTypeFont* font = (gui::TrueTypeFont*)montauk::malloc(sizeof(gui::TrueTypeFont));
    if (!font) {
        montauk::win_destroy(winId);
        return -1;
    }
    montauk::memset(font, 0, sizeof(gui::TrueTypeFont));
    if (!font->init("0:/fonts/Roboto-Medium.ttf")) {
        montauk::mfree(font);
        montauk::win_destroy(winId);
        return -1;
    }

    // Simple render - fill with a color pattern
    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            pixels[y * width + x] = kBackgroundColor;
        }
    }

    // Render text using TrueType
    gui::Color text_color;
    text_color.r = 0x11;
    text_color.g = 0x11;
    text_color.b = 0x11;
    text_color.a = 255;
    font->draw_to_buffer(pixels, width, height, 20, 20, "Hello from libhello!", text_color, 16);

    // Present the initial frame
    montauk::win_present(winId);

    // Event loop
    while (true) {
        Montauk::WinEvent ev;
        int r = montauk::win_poll(winId, &ev);

        if (r < 0) {
            break;
        }
        if (r == 0) {
            montauk::sleep_ms(16);
            continue;
        }

        if (ev.type == 3) {  // close
            break;
        }
        if (ev.type == 2) {  // resize
            width = ev.resize.w;
            height = ev.resize.h;
            pixels = (uint32_t*)(uintptr_t)montauk::win_resize(winId, width, height);

            // Re-render on resize
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    pixels[y * width + x] = kBackgroundColor;
                }
            }
            font->draw_to_buffer(pixels, width, height, 20, 20, "Hello from libhello!", text_color, 16);
            montauk::win_present(winId);
        }
    }

    montauk::win_destroy(winId);
    montauk::mfree(font);
    return 0;
}
