// The MIT License (MIT)
//
// Copyright (C) 2026 Scott Duensing
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.

// basEvents.h  -- canonical list of BASIC event suffixes
//
// A procedure whose name ends with one of these suffixes is treated as an
// event handler (Ctrl_Load, Form_Click, etc).  Referenced by the stripper
// (to retain handlers in release builds), the obfuscator (to preserve event
// naming in rewritten forms), and the IDE (to populate the Object/Event
// dropdowns and generate handler stubs).  Keep them in one place so adding
// a new event only touches one file.
//
// BAS_EVENT_LIST is the master table.  Each entry carries:
//   suffix   -- the event name appended after "_" in the handler name
//   scope    -- BasEventScopeE flags: which Object kinds fire it
//   params   -- the handler's parameter list exactly as the runtime
//               passes it (formrt.c fireCtrlEvent / FireEventWithCancel),
//               "" for events with no arguments.  Control-array handlers
//               receive an extra leading "Index As Integer".
// Consumers expand it with an X macro so no parallel list can drift.

#ifndef BAS_EVENTS_H
#define BAS_EVENTS_H

#include <stdbool.h>
#include <stdint.h>

typedef enum {
    BAS_EVT_SCOPE_CTRL = 1 << 0,   // fired on controls (widgets, Timer)
    BAS_EVT_SCOPE_FORM = 1 << 1    // fired on the form itself
} BasEventScopeE;

#define BAS_EVT_SCOPE_BOTH (BAS_EVT_SCOPE_CTRL | BAS_EVT_SCOPE_FORM)

// Event names.  The runtime fires events by these names and the table
// below is built from them, so a rename touches one line.
#define BAS_EVT_LOAD        "Load"
#define BAS_EVT_UNLOAD      "Unload"
#define BAS_EVT_QUERYUNLOAD "QueryUnload"
#define BAS_EVT_RESIZE      "Resize"
#define BAS_EVT_ACTIVATE    "Activate"
#define BAS_EVT_DEACTIVATE  "Deactivate"
#define BAS_EVT_CLICK       "Click"
#define BAS_EVT_DBLCLICK    "DblClick"
#define BAS_EVT_CHANGE      "Change"
#define BAS_EVT_TIMER       "Timer"
#define BAS_EVT_GOTFOCUS    "GotFocus"
#define BAS_EVT_LOSTFOCUS   "LostFocus"
#define BAS_EVT_KEYPRESS    "KeyPress"
#define BAS_EVT_KEYDOWN     "KeyDown"
#define BAS_EVT_KEYUP       "KeyUp"
#define BAS_EVT_MOUSEDOWN   "MouseDown"
#define BAS_EVT_MOUSEUP     "MouseUp"
#define BAS_EVT_MOUSEMOVE   "MouseMove"
#define BAS_EVT_SCROLL      "Scroll"
#define BAS_EVT_REPOSITION  "Reposition"
#define BAS_EVT_VALIDATE    "Validate"

#define BAS_EVENT_LIST(X) \
    X(BAS_EVT_LOAD,        BAS_EVT_SCOPE_FORM, "") \
    X(BAS_EVT_UNLOAD,      BAS_EVT_SCOPE_FORM, "") \
    X(BAS_EVT_QUERYUNLOAD, BAS_EVT_SCOPE_FORM, "Cancel As Integer") \
    X(BAS_EVT_RESIZE,      BAS_EVT_SCOPE_FORM, "") \
    X(BAS_EVT_ACTIVATE,    BAS_EVT_SCOPE_FORM, "") \
    X(BAS_EVT_DEACTIVATE,  BAS_EVT_SCOPE_FORM, "") \
    X(BAS_EVT_CLICK,       BAS_EVT_SCOPE_CTRL, "") \
    X(BAS_EVT_DBLCLICK,    BAS_EVT_SCOPE_CTRL, "") \
    X(BAS_EVT_CHANGE,      BAS_EVT_SCOPE_CTRL, "") \
    X(BAS_EVT_TIMER,       BAS_EVT_SCOPE_CTRL, "") \
    X(BAS_EVT_GOTFOCUS,    BAS_EVT_SCOPE_CTRL, "") \
    X(BAS_EVT_LOSTFOCUS,   BAS_EVT_SCOPE_CTRL, "") \
    X(BAS_EVT_KEYPRESS,    BAS_EVT_SCOPE_BOTH, "KeyAscii As Integer") \
    X(BAS_EVT_KEYDOWN,     BAS_EVT_SCOPE_BOTH, "KeyCode As Integer, Shift As Integer") \
    X(BAS_EVT_KEYUP,       BAS_EVT_SCOPE_BOTH, "KeyCode As Integer, Shift As Integer") \
    X(BAS_EVT_MOUSEDOWN,   BAS_EVT_SCOPE_BOTH, "Button As Integer, X As Integer, Y As Integer") \
    X(BAS_EVT_MOUSEUP,     BAS_EVT_SCOPE_BOTH, "Button As Integer, X As Integer, Y As Integer") \
    X(BAS_EVT_MOUSEMOVE,   BAS_EVT_SCOPE_BOTH, "Button As Integer, X As Integer, Y As Integer") \
    X(BAS_EVT_SCROLL,      BAS_EVT_SCOPE_CTRL, "Delta As Integer") \
    X(BAS_EVT_REPOSITION,  BAS_EVT_SCOPE_CTRL, "") \
    X(BAS_EVT_VALIDATE,    BAS_EVT_SCOPE_CTRL, "Cancel As Integer")

// One row of BAS_EVENT_LIST, for consumers that want a runtime table
// (e.g. `static const BasEventInfoT sEvents[] = { BAS_EVENT_LIST(BAS_EVENT_ROW) };`).
typedef struct {
    const char *suffix;
    uint8_t     scope;     // BasEventScopeE flags
    const char *params;    // handler parameter list, "" when none
} BasEventInfoT;

#define BAS_EVENT_ROW(suffix, scope, params) { suffix, scope, params },

// Expands to just the suffix string followed by a comma, for a plain
// NULL-terminated const char *[] view of the list.
#define BAS_EVENT_SUFFIX(suffix, scope, params) suffix,

// NULL-terminated list of event suffixes (BAS_EVENT_LIST order).
// Case-insensitive match.  Declared extern here, defined once in strip.c.
extern const char *basEventSuffixes[];

// True when suffix case-insensitively equals one of basEventSuffixes.
// Defined once in strip.c (the owner of basEventSuffixes).
bool basEventSuffixMatch(const char *suffix);

#endif // BAS_EVENTS_H
