// menuBuilderProbe.c - Phase 4.1 smoke test.
//
// Builds a minimal Apple+File menu bar via the uiBuilder surface,
// installs it, runs the event loop, then sets $70=0x99 when the
// File>Quit (or cmd-Q) handler fires.  Verifies:
//   - uiBuilderMenuBytes emits a byte stream NewMenu accepts.
//   - uiBuilderInstallMenuBar drives DrawMenuBar without hanging.
//   - uiBuilderDispatch routes the menu pick to the right handler.
//   - Cmd-Q keystroke wakes the loop within the test.sh timeout.

#include "iigs/toolbox.h"
#include "iigs/desktop.h"
#include "iigs/eventLoop.h"
#include "iigs/uiBuilder.h"

#include <stdint.h>


#define CMD_ABOUT  257
#define CMD_QUIT   256


static volatile uint16_t gIdleTicks;


static void onIdle(void) {
    if (++gIdleTicks > 2000) {
        iigsEventLoopQuit();
    }
}


static void onAbout(uint16_t cmdId) {
    (void)cmdId;
    // Mark "About picked" at $71.  Test reads this if it wants to
    // confirm the dispatcher fired for a non-Quit item.
    *(volatile unsigned char *)0x71 = 0xAB;
}


static void onQuit(uint16_t cmdId) {
    (void)cmdId;
    // Mark "Quit picked" at $72, then ask the loop to exit.
    *(volatile unsigned char *)0x72 = 0xCD;
    iigsEventLoopQuit();
}


static const UiCmdHandlerT gCmdTable[] = {
    { CMD_ABOUT, onAbout },
    { CMD_QUIT,  onQuit  },
};


static const UiMenuItemT gAppleItems[] = {
    { CMD_ABOUT, "About Menu Probe", 0, 0 },
};

static const UiMenuItemT gFileItems[] = {
    { CMD_QUIT, "Quit", 'Q', 0 },
};

static const UiMenuT gMenus[] = {
    { 1, "Apple", MN_APPLE, 1, gAppleItems },
    { 2, "File",  0,        1, gFileItems  },
};


static void myOnMenu(uint16_t menuId, uint16_t itemId) {
    (void)menuId;
    uiBuilderDispatch(itemId, gCmdTable, (uint16_t)(sizeof gCmdTable / sizeof gCmdTable[0]));
}


int main(void) {
    unsigned short userId = startdesk(640);
    (void)userId;

    paintDesktopBackdrop();
    uiBuilderInstallMenuBar(gMenus, (uint16_t)(sizeof gMenus / sizeof gMenus[0]));
    ShowCursor();

    // Marker: init complete.  Even if no menu pick comes in, this
    // proves the builder + DrawMenuBar got through.
    *(volatile unsigned char *)0x70 = 0x55;

    IigsEventCallbacksT cb;
    {
        unsigned char *p = (unsigned char *)&cb;
        for (uint16_t i = 0; i < sizeof cb; i++) {
            p[i] = 0;
        }
    }
    cb.onMenu = myOnMenu;
    // Watchdog so the headless test exits even if no key injection
    // reaches the menu pick: count idle ticks and quit after ~2000.
    cb.onIdle = onIdle;
    iigsEventLoop(&cb);

    // Final marker: loop exited cleanly.
    *(volatile unsigned char *)0x70 = 0x99;
    return 0;
}
