#include <devices/cursor.h>
#include <devices/mouse.h>
#include <graphics/draw.h>
#include <graphics/context.h>
#include <memory/heap.h>
#include <common.h>

// 经典箭头光标位图 (12x16)
// 0=透明, 1=白色填充, 2=黑色轮廓
static const SUINT8 g_cursor_bitmap[CURSOR_H][CURSOR_W] = {
    {2,0,0,0,0,0,0,0,0,0,0,0},
    {2,2,0,0,0,0,0,0,0,0,0,0},
    {2,1,2,0,0,0,0,0,0,0,0,0},
    {2,1,1,2,0,0,0,0,0,0,0,0},
    {2,1,1,1,2,0,0,0,0,0,0,0},
    {2,1,1,1,1,2,0,0,0,0,0,0},
    {2,1,1,1,1,1,2,0,0,0,0,0},
    {2,1,1,1,1,1,1,2,0,0,0,0},
    {2,1,1,1,1,1,1,1,2,0,0,0},
    {2,1,1,1,1,1,1,1,1,2,0,0},
    {2,1,1,1,1,1,2,2,2,2,2,0},
    {2,1,1,2,1,2,0,0,0,0,0,0},
    {2,1,2,0,0,2,0,0,0,0,0,0},
    {2,2,0,0,0,0,2,0,0,0,0,0},
    {2,0,0,0,0,0,2,0,0,0,0,0},
    {0,0,0,0,0,0,0,0,0,0,0,0},
};

static layer_t* g_cursor_layer = NULL;

void cursor_init(void) {
    g_cursor_layer = layer_create("cursor", LAYER_TYPE_MOUSE, CURSOR_W, CURSOR_H);
    if (!g_cursor_layer) return;

    layer_set_z(g_cursor_layer, 9999);

    // 将位图写入图层缓冲区，Reserved 用作 alpha（0=透明, 255=不透明）
    EFI_GRAPHICS_OUTPUT_BLT_PIXEL* buf = g_cursor_layer->buffer;
    for (UINT32 y = 0; y < CURSOR_H; y++) {
        for (UINT32 x = 0; x < CURSOR_W; x++) {
            EFI_GRAPHICS_OUTPUT_BLT_PIXEL* dst = &buf[y * CURSOR_W + x];
            SUINT8 px = g_cursor_bitmap[y][x];
            if (px == 1) {
                dst->Blue = 255; dst->Green = 255; dst->Red = 255; dst->Reserved = 255;
            } else if (px == 2) {
                dst->Blue = 0; dst->Green = 0; dst->Red = 0; dst->Reserved = 255;
            } else {
                dst->Blue = 0; dst->Green = 0; dst->Red = 0; dst->Reserved = 0;
            }
        }
    }

    // 初始位置：屏幕中心
    layer_set_pos(g_cursor_layer,
        (SSINT32)(g_gfx.hr / 2),
        (SSINT32)(g_gfx.vr / 2));
}

void cursor_update(void) {
    if (!g_cursor_layer) return;

    SSINT32 cx = (SSINT32)(g_gfx.hr / 2) + mouse_get_x();
    SSINT32 cy = (SSINT32)(g_gfx.vr / 2) + mouse_get_y();

    if (cx < 0) cx = 0;
    if (cy < 0) cy = 0;
    if (cx + (SSINT32)CURSOR_W > (SSINT32)g_gfx.hr) cx = (SSINT32)g_gfx.hr - CURSOR_W;
    if (cy + (SSINT32)CURSOR_H > (SSINT32)g_gfx.vr) cy = (SSINT32)g_gfx.vr - CURSOR_H;

    layer_set_pos(g_cursor_layer, cx, cy);
}

layer_t* cursor_get_layer(void) {
    return g_cursor_layer;
}
