// dvxWgtP.h -- Plugin API for DVX widget DXE modules
//
// Included by widget .c files to access core infrastructure.
// Provides: widget allocation, tree ops, class table, shared
// interaction state, scrollbar helpers, layout helpers, and
// common utility functions.
//
// Does NOT contain any per-widget prototypes.  Each widget's
// internal functions (paint, onMouse, onKey, calcMinSize, etc.)
// are private to its own .c file and referenced only through
// the WidgetClassT vtable.
#ifndef DVX_WGT_P_H
#define DVX_WGT_P_H

#include "dvxWgt.h"
#include "dvxApp.h"
#include "dvxDraw.h"
#include "dvxWm.h"
#include "dvxVideo.h"

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "dvxMem.h"

// ============================================================
// Widget class table
// ============================================================

// stb_ds dynamic array.  Each widget DXE appends its class(es)
// via wgtRegisterClass() during wgtRegister().
extern const WidgetClassT **widgetClassTable;

// ============================================================
// Validation macros
// ============================================================

#define VALIDATE_WIDGET(w, wtype, retval) \
    do { if (!(w) || (w)->type != (wtype)) { return (retval); } } while (0)

#define VALIDATE_WIDGET_VOID(w, wtype) \
    do { if (!(w) || (w)->type != (wtype)) { return; } } while (0)

// ============================================================
// Cursor shape IDs (mirrors dvxCursor.h defines)
// ============================================================

#define CURSOR_ARROW              0
#define CURSOR_RESIZE_H           1
#define CURSOR_RESIZE_V           2
#define CURSOR_RESIZE_DIAG_NWSE   3
#define CURSOR_RESIZE_DIAG_NESW   4
#define CURSOR_BUSY               5

// ============================================================
// Keyboard modifier flags
// ============================================================

#define KEY_MOD_SHIFT  0x03
#define KEY_MOD_CTRL   0x04
#define KEY_MOD_ALT    0x08

// ============================================================
// Core layout constants
// ============================================================

#define DEFAULT_SPACING  4
#define DEFAULT_PADDING  4
#define SB_MIN_THUMB     14
#define WGT_SB_W         14

// ============================================================
// Inline helpers
// ============================================================

static inline int32_t clampInt(int32_t val, int32_t lo, int32_t hi) {
    if (val < lo) { return lo; }
    if (val > hi) { return hi; }
    return val;
}


static inline void drawTextEmbossed(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, int32_t x, int32_t y, const char *text, const ColorSchemeT *colors) {
    drawText(d, ops, font, x + 1, y + 1, text, colors->windowHighlight, 0, false);
    drawText(d, ops, font, x, y, text, colors->windowShadow, 0, false);
}


static inline void drawTextAccelEmbossed(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, int32_t x, int32_t y, const char *text, const ColorSchemeT *colors) {
    drawTextAccel(d, ops, font, x + 1, y + 1, text, colors->windowHighlight, 0, false);
    drawTextAccel(d, ops, font, x, y, text, colors->windowShadow, 0, false);
}

// ============================================================
// Shared interaction state (defined in widgetCore.c)
// ============================================================

extern bool     sCursorBlinkOn;
extern clock_t  sDblClickTicks;
extern bool     sDebugLayout;
extern WidgetT *sClosedPopup;
extern WidgetT *sFocusedWidget;
extern WidgetT *sKeyPressedBtn;
extern WidgetT *sOpenPopup;
extern WidgetT *sDragWidget;     // widget being dragged (any drag type)
extern int32_t  sPollWidgetCount;
extern WidgetT **sPollWidgets;    // stb_ds dynamic array
extern void   (*sCursorBlinkFn)(void);

// ============================================================
// Core widget functions (widgetCore.c)
// ============================================================

// Tree manipulation
void widgetAddChild(WidgetT *parent, WidgetT *child);
void widgetRemoveChild(WidgetT *parent, WidgetT *child);
void widgetDestroyChildren(WidgetT *w);

// Allocation
WidgetT *widgetAlloc(WidgetT *parent, int32_t type);

// Focus management
WidgetT *widgetFindNextFocusable(WidgetT *root, WidgetT *after);
WidgetT *widgetFindPrevFocusable(WidgetT *root, WidgetT *before);
WidgetT *widgetFindByAccel(WidgetT *root, char key);

// Utility queries
int32_t widgetCountVisibleChildren(const WidgetT *w);
int32_t widgetFrameBorderWidth(const WidgetT *w);
bool widgetIsFocusable(int32_t type);
bool widgetIsHorizContainer(int32_t type);
int32_t multiClickDetect(int32_t vx, int32_t vy);

// Clipboard
void clipboardCopy(const char *text, int32_t len);
const char *clipboardGet(int32_t *outLen);
int32_t clipboardMaxLen(void);

// Hit testing
WidgetT *widgetHitTest(WidgetT *w, int32_t x, int32_t y);

// Scrollbar helpers
void widgetScrollbarThumb(int32_t trackLen, int32_t totalSize, int32_t visibleSize, int32_t scrollPos, int32_t *thumbPos, int32_t *thumbSize);

// ============================================================
// Scrollbar drawing and hit testing (widgetScrollbar.c)
// ============================================================

typedef enum {
    ScrollHitNoneE,
    ScrollHitArrowDecE,
    ScrollHitArrowIncE,
    ScrollHitPageDecE,
    ScrollHitPageIncE,
    ScrollHitThumbE
} ScrollHitE;

void widgetDrawScrollbarH(DisplayT *d, const BlitOpsT *ops, const ColorSchemeT *colors, int32_t sbX, int32_t sbY, int32_t sbW, int32_t totalSize, int32_t visibleSize, int32_t scrollPos);
void widgetDrawScrollbarHEx(DisplayT *d, const BlitOpsT *ops, const ColorSchemeT *colors, int32_t sbX, int32_t sbY, int32_t sbW, int32_t totalSize, int32_t visibleSize, int32_t scrollPos, int32_t barW);
void widgetDrawScrollbarV(DisplayT *d, const BlitOpsT *ops, const ColorSchemeT *colors, int32_t sbX, int32_t sbY, int32_t sbH, int32_t totalSize, int32_t visibleSize, int32_t scrollPos);
void widgetDrawScrollbarVEx(DisplayT *d, const BlitOpsT *ops, const ColorSchemeT *colors, int32_t sbX, int32_t sbY, int32_t sbH, int32_t totalSize, int32_t visibleSize, int32_t scrollPos, int32_t barW);
ScrollHitE widgetScrollbarHitTest(int32_t sbLen, int32_t relPos, int32_t totalSize, int32_t visibleSize, int32_t scrollPos);

// ============================================================
// Layout functions (widgetLayout.c)
// ============================================================

void widgetCalcMinSizeBox(WidgetT *w, const BitmapFontT *font);
void widgetCalcMinSizeTree(WidgetT *w, const BitmapFontT *font);
void widgetLayoutBox(WidgetT *w, const BitmapFontT *font);
void widgetLayoutChildren(WidgetT *w, const BitmapFontT *font);

// ============================================================
// Event dispatch (widgetEvent.c)
// ============================================================

void widgetManageScrollbars(WindowT *win, AppContextT *ctx);
void widgetOnBlur(WindowT *win);
void widgetOnFocus(WindowT *win);
void widgetOnKey(WindowT *win, int32_t key, int32_t mod);
void widgetOnKeyUp(WindowT *win, int32_t scancode, int32_t mod);
void widgetOnMouse(WindowT *win, int32_t x, int32_t y, int32_t buttons);
void widgetOnPaint(WindowT *win, RectT *dirtyArea);
void widgetOnResize(WindowT *win, int32_t newW, int32_t newH);
void widgetOnScroll(WindowT *win, ScrollbarOrientE orient, int32_t value);

// ============================================================
// Paint helpers (widgetOps.c)
// ============================================================

void widgetPaintOne(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors);
void widgetPaintOverlays(WidgetT *root, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors);

// ============================================================
// Pressable helpers (widgetOps.c)
// ============================================================
//
// Shared drag/press state machine for WCLASS_PRESS_RELEASE widgets
// (Button, ImageButton).  The widget's w->pressed flag tracks the
// visual state; these helpers handle mouse/key activation and fire
// the widget's onClick callback on release-within-bounds.

void widgetPressableOnAccelActivate(WidgetT *w, WidgetT *root);
void widgetPressableOnDragEnd(WidgetT *w, WidgetT *root, int32_t x, int32_t y);
void widgetPressableOnDragUpdate(WidgetT *w, WidgetT *root, int32_t x, int32_t y);
void widgetPressableOnKey(WidgetT *w, int32_t key, int32_t mod);
void widgetPressableOnMouse(WidgetT *w, WidgetT *root, int32_t vx, int32_t vy);

// ============================================================
// Text helpers (widgetOps.c)
// ============================================================
//
// Generic text get/set for widgets whose DataT struct has
// `const char *text` as the first field (Button, Checkbox, Label,
// Radio). The widget class must set WCLASS_HAS_TEXT so destroy
// frees the text automatically. Widgets register these directly
// as their WGT_METHOD_GET_TEXT / WGT_METHOD_SET_TEXT handlers.

const char *widgetTextGet(const WidgetT *w);
void        widgetTextSet(WidgetT *w, const char *text);

// Shared helper libraries:
//   texthelp/textHelp.h  -- clipboard, text editing, word boundaries
//   listhelp/listHelp.h  -- dropdown arrow, popup list, keyboard nav
// Widget DXEs that use these include the headers directly.

#endif // DVX_WGT_P_H
