// formrt.h -- DVX BASIC form runtime
//
// Bridges BASIC programs to the DVX widget system. Control types
// are resolved dynamically via WgtIfaceT interface descriptors
// registered by .wgt DXE files. Properties and methods are
// dispatched generically through descriptors. Events fire by
// looking up ControlName_EventName in the compiled module's
// procedure table and calling into the VM.

#ifndef DVXBASIC_FORMRT_H
#define DVXBASIC_FORMRT_H

#include "../runtime/vm.h"
#include "../runtime/values.h"
#include "dvxApp.h"
#include "dvxWidget.h"

// ============================================================
// Forward declarations
// ============================================================

typedef struct BasFormT BasFormT;
typedef struct BasControlT BasControlT;

// ============================================================
// Limits
// ============================================================

#define BAS_MAX_CTRL_NAME    32

// ============================================================
// Menu ID to name mapping for event dispatch
// ============================================================

typedef struct {
    int32_t id;
    char    name[BAS_MAX_CTRL_NAME];
} BasMenuIdMapT;

// ============================================================
// Control instance (a widget on a form)
// ============================================================

#define BAS_MAX_TEXT_BUF  256

typedef struct BasControlT {
    char              name[BAS_MAX_CTRL_NAME];     // VB control name (e.g. "Command1")
    char              typeName[BAS_MAX_CTRL_NAME]; // VB type name (e.g. "CommandButton")
    int32_t           index;                       // control array index (-1 = not in array)
    WidgetT          *widget;                      // the DVX widget
    BasFormT         *form;                        // owning form
    const WgtIfaceT  *iface;                       // interface descriptor (from .wgt)
    char              textBuf[BAS_MAX_TEXT_BUF];    // persistent text for Caption/Text
    char              dataSource[BAS_MAX_CTRL_NAME]; // name of Data control for binding
    char              dataField[BAS_MAX_CTRL_NAME];  // column name for binding
} BasControlT;

// ============================================================
// Form instance (a DVX window with controls)
// ============================================================

typedef struct BasFormT {
    char              name[BAS_MAX_CTRL_NAME]; // form name (e.g. "Form1")
    WindowT          *window;                  // DVX window
    WidgetT          *root;                    // widget root (from wgtInitWindow)
    WidgetT          *contentBox;              // VBox/HBox for user controls
    AppContextT      *ctx;                     // DVX app context
    BasControlT      *controls;                // stb_ds dynamic array
    int32_t           controlCount;
    BasVmT           *vm;                      // VM for event dispatch
    BasModuleT       *module;                  // compiled module (for SUB lookup)
    // Form-level properties (accumulated during .frm parsing)
    int32_t           frmWidth;
    int32_t           frmHeight;
    int32_t           frmLeft;
    int32_t           frmTop;
    bool              frmResizable;
    bool              frmHasResizable;         // true if Resizable was explicitly set
    bool              frmCentered;
    bool              frmAutoSize;
    bool              frmHBox;                 // true if Layout = "HBox"
    // Per-form variable storage (allocated at load, freed at unload)
    BasValueT        *formVars;
    int32_t           formVarCount;
    // Menu ID to name mapping (for event dispatch)
    BasMenuIdMapT    *menuIdMap;
    int32_t           menuIdMapCount;
} BasFormT;

// ============================================================
// Form runtime context
// ============================================================

// Cached .frm source for reload after unload
typedef struct {
    char    formName[BAS_MAX_CTRL_NAME];
    char   *frmSource;                         // malloc'd copy of .frm text
    int32_t frmSourceLen;
} BasFrmCacheT;

typedef struct {
    AppContextT      *ctx;                     // DVX app context
    BasVmT           *vm;                      // shared VM instance
    BasModuleT       *module;                  // compiled module
    BasFormT         *forms;                    // stb_ds dynamic array
    int32_t           formCount;
    BasFormT         *currentForm;             // form currently dispatching events
    BasFrmCacheT     *frmCache;                // stb_ds array of cached .frm sources
    int32_t           frmCacheCount;
} BasFormRtT;

// ============================================================
// API
// ============================================================

// Initialize the form runtime with a DVX context and a compiled module.
BasFormRtT *basFormRtCreate(AppContextT *ctx, BasVmT *vm, BasModuleT *module);

// Destroy the form runtime and all forms/controls.
void basFormRtDestroy(BasFormRtT *rt);

// Wire up the VM's UI callbacks to this form runtime.
void basFormRtBindVm(BasFormRtT *rt);

// ---- UI callback implementations (match BasUiCallbacksT) ----

BasValueT basFormRtGetProp(void *ctx, void *ctrlRef, const char *propName);
void      basFormRtSetProp(void *ctx, void *ctrlRef, const char *propName, BasValueT value);
BasValueT basFormRtCallMethod(void *ctx, void *ctrlRef, const char *methodName, BasValueT *args, int32_t argc);
void     *basFormRtCreateCtrl(void *ctx, void *formRef, const char *typeName, const char *ctrlName);
void     *basFormRtFindCtrl(void *ctx, void *formRef, const char *ctrlName);
void     *basFormRtFindCtrlIdx(void *ctx, void *formRef, const char *ctrlName, int32_t index);
void     *basFormRtLoadForm(void *ctx, const char *formName);
void      basFormRtUnloadForm(void *ctx, void *formRef);
void      basFormRtShowForm(void *ctx, void *formRef, bool modal);
void      basFormRtHideForm(void *ctx, void *formRef);
int32_t   basFormRtMsgBox(void *ctx, const char *message, int32_t flags);

// ---- Event dispatch ----

bool basFormRtFireEvent(BasFormRtT *rt, BasFormT *form, const char *ctrlName, const char *eventName);
bool basFormRtFireEventArgs(BasFormRtT *rt, BasFormT *form, const char *ctrlName, const char *eventName, const BasValueT *args, int32_t argCount);

// ---- Form file loading ----

BasFormT *basFormRtLoadFrm(BasFormRtT *rt, const char *source, int32_t sourceLen);

#endif // DVXBASIC_FORMRT_H
