#include <graphics/draw.h>

// --- Global (framebuffer) ---

void global_draw_pixel(SUINT32 x, SUINT32 y, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) {
    EFI_GRAPHICS_OUTPUT_BLT_PIXEL *p = g_gfx.base + (g_gfx.hr * y) + x;
    p->Blue = color.Blue;
    p->Green = color.Green;
    p->Red = color.Red;
    p->Reserved = color.Reserved;
}

void global_draw_rect(SUINT32 bx, SUINT32 by, SUINT32 ex, SUINT32 ey,
    EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) {
    for (SUINT32 x = bx; x <= ex; x++)
        for (SUINT32 y = by; y <= ey; y++)
            global_draw_pixel(x, y, color);
}

// --- Current target buffer ---

void draw_pixel(SUINT32 x, SUINT32 y, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) {
    if (x >= g_draw_target.w || y >= g_draw_target.h) return;
    EFI_GRAPHICS_OUTPUT_BLT_PIXEL *p = g_draw_target.buf + (g_draw_target.w * y) + x;
    p->Blue = color.Blue;
    p->Green = color.Green;
    p->Red = color.Red;
    p->Reserved = color.Reserved;
}

void draw_rect(SUINT32 bx, SUINT32 by, SUINT32 ex, SUINT32 ey,
    EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) {
    for (SUINT32 x = bx; x <= ex; x++)
        for (SUINT32 y = by; y <= ey; y++)
            draw_pixel(x, y, color);
}

void draw_pixel_alpha(SUINT32 x, SUINT32 y, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color, SUINT8 alpha) {
    if (x >= g_draw_target.w || y >= g_draw_target.h) return;
    if (alpha == 0) return;
    EFI_GRAPHICS_OUTPUT_BLT_PIXEL *p = g_draw_target.buf + (g_draw_target.w * y) + x;
    if (alpha == 255) {
        p->Blue = color.Blue;
        p->Green = color.Green;
        p->Red = color.Red;
        p->Reserved = color.Reserved;
        return;
    }
    SUINT32 inv = 255 - alpha;
    p->Blue  = (SUINT8)((color.Blue  * alpha + p->Blue  * inv) / 255);
    p->Green = (SUINT8)((color.Green * alpha + p->Green * inv) / 255);
    p->Red   = (SUINT8)((color.Red   * alpha + p->Red   * inv) / 255);
    p->Reserved = color.Reserved;
}
