// iigs/eventLoop.h - curated event loop for desktop apps.
//
// Wraps TaskMaster in a "register callbacks, call run, get out when
// you signal quit" pattern.  Saves writing the same 30-line dispatch
// switch in every demo.  Built on the existing toolbox bindings —
// you can still drive TaskMaster directly for anything this header
// doesn't expose.
//
// Lifecycle:
//   1. startdesk(640)  (from iigs/desktop.h)
//   2. Build menus + windows.
//   3. Fill an IigsEventCallbacksT.
//   4. iigsEventLoop(&cb)  — runs until iigsEventLoopQuit() is called
//                             from inside a callback.
//   5. enddesk(userId).
#ifndef IIGS_EVENT_LOOP_H
#define IIGS_EVENT_LOOP_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>


// EventRecord layout (per Apple GS/OS toolbox reference).  Exposed
// here so callbacks can inspect the raw event when they need more
// than the dispatched arguments give them.
typedef struct {
    uint16_t what;         // event code
    uint32_t message;      // event-specific payload
    uint32_t when;         // tick count
    int16_t  whereX;       // mouse X at event time
    int16_t  whereY;       // mouse Y at event time
    uint16_t modifiers;    // key + button modifier state
    uint16_t taskData;     // TaskMaster scratch
    uint16_t taskMask;
    uint32_t window;       // affected window (close box, content click, etc.)
    uint32_t reserved[4];
} IigsEventT;


// Callback table.  Any field may be NULL — the dispatch skips it and
// returns the event to TaskMaster's default handler.
typedef struct {
    // Fired when the user clicks a window's close box.  Argument is
    // the window pointer; the callback should call CloseWindow on it
    // and (if it was the last window) iigsEventLoopQuit().
    void (*onClose)(uint32_t windowPtr);

    // Fired when a menu item is picked (return value of MenuKey or
    // MenuSelect).  Arg layout: high 16 = menu ID, low 16 = item ID.
    // The callback should HiliteMenu(0) when done with menu state.
    void (*onMenu)(uint16_t menuId, uint16_t itemId);

    // Fired for keystrokes that weren't a menu shortcut.  Low 8 of
    // arg is the character; modifiers are in the event record passed
    // in `ev`.
    void (*onKey)(uint8_t ch, const IigsEventT *ev);

    // Fired for mouse clicks not consumed by TaskMaster (content
    // clicks inside your window, drag-region clicks, etc.).
    void (*onMouse)(const IigsEventT *ev);

    // Called once per loop iteration when no event was pending.
    // Use sparingly — this fires ~60 Hz and competes with WM redraw.
    void (*onIdle)(void);
} IigsEventCallbacksT;


// Run the event loop until iigsEventLoopQuit() is called.  TaskMaster
// is invoked with the standard `everyEvent` mask + all task masks
// enabled (drag bar, close box, zoom box, etc.).
void iigsEventLoop(const IigsEventCallbacksT *cb);


// Signal the running event loop to exit.  Safe to call from any
// callback; takes effect after the current event is fully dispatched.
void iigsEventLoopQuit(void);


#ifdef __cplusplus
}
#endif

#endif  // IIGS_EVENT_LOOP_H
