/*
 * gfx_demo — exercises the libc/gfx primitives.  Shows:
 *   1. accelerator-backed gfx_clear256 / gfx_hline256 / gfx_vline256 / gfx_fill_rect256
 *   2. gfx_rect256 outline, gfx_line256 diagonals (Bresenham via putpixel)
 *   3. a grey-ramp palette
 *
 * Press a key to advance through each stage.
 */

#include <stdio.h>
#include <conio.h>
#include <gfx.h>
#include <stdint.h>

static uint8_t palette_data[256 * 4];

static void wait_key(void)
{
    __asm
        ld    c, #0x30
        rst   #0x10
    __endasm;
}

int main(void)
{
    /* Grey ramp: (B=i, G=i, R=i, 0). */
    for (int i = 0; i < 256; i++) {
        palette_data[i * 4 + 0] = (uint8_t)i;
        palette_data[i * 4 + 1] = (uint8_t)i;
        palette_data[i * 4 + 2] = (uint8_t)i;
        palette_data[i * 4 + 3] = 0;
    }

    uint8_t prev = gfx_init(GFX_MODE_320x256x256, 0);
    gfx_pal_load(0, 0, 0, palette_data);

    /* --- Stage 1: orthogonal frame via hline / vline ----------------- */
    gfx_clear256(0x40);
    gfx_hline256(1,             1,             GFX_WIDTH  - 2, 0xFF);
    gfx_hline256(1,             GFX_HEIGHT - 2, GFX_WIDTH - 2, 0xFF);
    gfx_vline256(1,             2,             GFX_HEIGHT - 4, 0xFF);
    gfx_vline256(GFX_WIDTH - 2, 2,             GFX_HEIGHT - 4, 0xFF);
    wait_key();

    /* --- Stage 2: nested rectangles -------------------------------- */
    gfx_clear256(0x20);
    for (int i = 0; i < 16; i++)
        gfx_rect256(i * 10, i * 8,
                 GFX_WIDTH  - i * 20,
                 GFX_HEIGHT - i * 16,
                 (uint8_t)(0x40 + i * 8));
    wait_key();

    /* --- Stage 3: filled-rect colour bars --------------------------- */
    gfx_clear256(0);
    /* Tall-narrow rects (w=20, h=128) — heuristic picks vertical orient. */
    for (int i = 0; i < 16; i++) {
        gfx_fill_rect256(i * 20,         0, 20, 128, (uint8_t)(i * 16));
        gfx_fill_rect256(i * 20 + 0,   128, 20, 128, (uint8_t)(255 - i * 16));
    }
    wait_key();

    /* --- Stage 3b: wide-short rects + a grid of small squares -------- */
    gfx_clear256(0x08);
    /* Wide-short stripes (w=320, h=16) — heuristic picks horizontal. */
    for (int i = 0; i < 8; i++)
        gfx_fill_rect256(0, i * 32, GFX_WIDTH, 16, (uint8_t)(0x40 + i * 24));
    /* 8×8 small squares grid (w=h, heuristic picks either — same cost). */
    for (int row = 0; row < 4; row++)
        for (int col = 0; col < 16; col++)
            gfx_fill_rect256(col * 20 + 4, 256 - 80 + row * 20, 12, 12,
                          (uint8_t)((row * 16 + col) * 4));
    wait_key();

    /* --- Stage 4: diagonal lines via Bresenham ---------------------- */
    gfx_clear256(0x18);
    /* "Star" of lines from centre to a circle of endpoints. */
    int cx = GFX_WIDTH / 2, cy = GFX_HEIGHT / 2;
    for (int i = 0; i < 16; i++) {
        int ex = i * (GFX_WIDTH - 1) / 15;
        gfx_line256(cx, cy, ex, 0,              0xFF);
        gfx_line256(cx, cy, ex, GFX_HEIGHT - 1, 0xC0);
    }
    for (int i = 0; i < 16; i++) {
        int ey = i * (GFX_HEIGHT - 1) / 15;
        gfx_line256(cx, cy, 0,             ey, 0x80);
        gfx_line256(cx, cy, GFX_WIDTH - 1, ey, 0x40);
    }
    /* Box outline using gfx_line256. */
    gfx_line256(0,             0,             GFX_WIDTH - 1, 0,             0xFF);
    gfx_line256(0,             GFX_HEIGHT - 1, GFX_WIDTH - 1, GFX_HEIGHT - 1, 0xFF);
    gfx_line256(0,             0,             0,             GFX_HEIGHT - 1, 0xFF);
    gfx_line256(GFX_WIDTH - 1, 0,             GFX_WIDTH - 1, GFX_HEIGHT - 1, 0xFF);
    wait_key();

    gfx_done(prev);
    puts("done");
    return 0;
}
