// eventLoop.c - implementation of iigs/eventLoop.h.
//
// TaskMaster returns an event-code that already encodes "this was a
// close-box click / menu pick / drag-region click / ..." so the loop
// body is a switch on the return code, not a manual GetNextEvent.
#include "iigs/eventLoop.h"
#include "iigs/toolbox.h"


static int gShouldQuit = 0;


// TaskMaster return codes (subset — see TB Vol.2 ch.5).
enum {
    EV_NULL          = 0,
    EV_MOUSE_DOWN    = 1,
    EV_MOUSE_UP      = 2,
    EV_KEY_DOWN      = 3,
    EV_AUTO_KEY      = 5,
    EV_UPDATE        = 6,
    EV_ACTIVATE      = 8,
    EV_SWITCH        = 9,
    EV_MENU_PICK     = 17,
    EV_CLOSE_CLICK   = 22,
    EV_ZOOM_CLICK    = 23,
    EV_GROW_CLICK    = 24
};


void iigsEventLoopQuit(void) {
    gShouldQuit = 1;
}


void iigsEventLoop(const IigsEventCallbacksT *cb) {
    static IigsEventT ev;       // static so we don't blow the stack each call
    gShouldQuit = 0;
    while (!gShouldQuit) {
        uint16_t code = TaskMaster(0xFFFF, &ev);
        switch (code) {
            case EV_NULL:
                if (cb && cb->onIdle) {
                    cb->onIdle();
                }
                break;
            case EV_CLOSE_CLICK:
                if (cb && cb->onClose) {
                    cb->onClose(ev.window);
                }
                break;
            case EV_MENU_PICK: {
                uint16_t menuId = (uint16_t)(ev.message >> 16);
                uint16_t itemId = (uint16_t)(ev.message & 0xFFFFu);
                if (cb && cb->onMenu) {
                    cb->onMenu(menuId, itemId);
                }
                HiliteMenu(0, menuId);
                break;
            }
            case EV_KEY_DOWN:
            case EV_AUTO_KEY:
                if (cb && cb->onKey) {
                    cb->onKey((uint8_t)(ev.message & 0xFFu), &ev);
                }
                break;
            case EV_MOUSE_DOWN:
                if (cb && cb->onMouse) {
                    cb->onMouse(&ev);
                }
                break;
            default:
                // TaskMaster handled it internally (drag/zoom/grow/
                // update/activate dispatch).  No callback for these
                // in the current surface; add later if needed.
                break;
        }
    }
}
