#pragma once
// ui_widgets.h - Immediate-mode widgets built on top of Clay.
//
// Each widget function takes a unique string ID, the value to display/edit,
// and returns whether the value was changed (or the widget was activated).
// The caller owns all data — the widget layer only stores transient UI state
// like which text field is focused or which dropdown is open.

#include "ui/ui_core.h"
#include "ui/ui_icons.h"
#include "platform/platform.h"

////////////////////////////////
// Widget state (global, managed by widget layer)

#define UI_WIDGET_MAX_DROPDOWN_ITEMS 32
#define UI_WIDGET_MAX_TEXT_INPUTS    16

typedef struct UI_KnobDragState {
    U32      dragging_id;   // Hash of the knob being dragged (0 = none)
    F32      drag_start_y;  // Mouse Y when drag started
    F32      drag_start_x;  // Mouse X when drag started (for h-slider)
    F32      value_at_start; // Value when drag started
    B32      was_shift;     // Shift state last frame (to re-anchor on change)
    U32      last_click_id; // Knob hash of last click (for F64-click detection)
    S32      last_click_frame; // Frame number of last click
} UI_KnobDragState;

typedef struct UI_WidgetState {
    // Text input focus
    U32 focused_id;       // Clay element ID hash of the focused text input (0 = none)
    S32  cursor_pos;       // Cursor position in focused text input
    F32      cursor_blink;     // Blink timer (seconds)

    // Text selection (sel_start == sel_end means no selection)
    S32  sel_start;        // Selection anchor (where selection began)
    S32  sel_end;          // Selection extent (moves with cursor)

    // Tab cycling: registered text input IDs in order of declaration
    U32      text_input_ids[UI_WIDGET_MAX_TEXT_INPUTS];
    S32      text_input_count;
    B32      tab_pressed;      // True on the frame Tab was pressed

    // Dropdown
    U32 open_dropdown_id; // Clay element ID hash of the open dropdown (0 = none)

    // Input for this frame
    PlatformInput input;

    // Click detection
    B32 mouse_clicked; // true on the frame mouse transitions from up->down

    // Knob drag state
    UI_KnobDragState knob_drag;

    // Knob text edit state
    U32 knob_edit_id;         // Hash of knob in text edit mode (0 = none)
    char     knob_edit_buf[32];    // Text buffer for numeric entry
    S32      knob_edit_cursor;     // Cursor position in edit buffer
    S32      knob_edit_sel_start;  // Selection anchor
    S32      knob_edit_sel_end;    // Selection extent
} UI_WidgetState;

extern UI_WidgetState g_wstate;

// Call once at startup
void ui_widgets_init();

// Call each frame before building widgets. Pass in the frame's input.
void ui_widgets_begin_frame(PlatformInput input);

// Call after changing theme to force text config refresh
void ui_widgets_theme_changed();

// Reset per-frame text input display buffer allocator (called by begin_frame, but
// can also be called manually if needed)
void ui_text_input_reset_display_bufs();

////////////////////////////////
// Widgets
// All IDs must be unique string literals (passed to CLAY_ID internally).

// Icon element (rendered via icon atlas)
void ui_icon(UI_IconID icon, F32 size, Clay_Color color);

// Simple label
void ui_label(const char *id, const char *text);

// Clickable button. Returns true on the frame it was clicked.
B32 ui_button(const char *id, const char *text);

// Checkbox. Toggles *value on click. Returns true if value changed.
B32 ui_checkbox(const char *id, const char *label, B32 *value);

// Radio button group. Sets *selected to the clicked index. Returns true if changed.
// options is an array of label strings, count is the number of options.
B32 ui_radio_group(const char *id, const char **options, S32 count, S32 *selected);

// Single-line text input. Edits buf in-place (null-terminated, max buf_size-1 chars).
// Returns true if the text changed this frame.
B32 ui_text_input(const char *id, char *buf, S32 buf_size);

// Dropdown / combo box. Sets *selected to chosen index. Returns true if changed.
// options is an array of label strings, count is the number of options.
B32 ui_dropdown(const char *id, const char **options, S32 count, S32 *selected);

// Tab bar. Renders a row of tabs with active/inactive states.
// Returns the currently selected index. Clicking an inactive tab updates *selected.
S32 ui_tab_bar(const char *id, const char **labels, S32 count, S32 *selected);

// Content function type (used by popup windows)
typedef void (*UI_WindowContentFn)(void *user_data);

// Knob / potentiometer. Vertical drag to change value.
// unsigned (is_signed=0): value in [0, max_val]
// signed   (is_signed=1): value in [-max_val, +max_val]
// default_val: value restored on F64-click.
// editable: if true, clicking the value text opens a text input for direct entry.
// Hold Shift while dragging for fine control.
// Returns true if value changed this frame.
B32 ui_knob(const char *id, const char *label, F32 *value, F32 max_val, B32 is_signed, F32 default_val, B32 editable);

// Horizontal slider. Drag left/right to change value.
B32 ui_slider_h(const char *id, const char *label, F32 *value, F32 max_val, B32 is_signed, F32 default_val, B32 editable);

// Vertical slider. Drag up/down to change value.
B32 ui_slider_v(const char *id, const char *label, F32 *value, F32 max_val, B32 is_signed, F32 default_val, B32 editable);

// DAW-style fader (vertical slider with fader cap icon).
B32 ui_fader(const char *id, const char *label, F32 *value, F32 max_val, B32 is_signed, F32 default_val, B32 editable);

////////////////////////////////
// Scrollable area with custom scrollbar
//
// Usage:
//   UI_ScrollState scroll = {0};  // persist across frames
//   ui_scroll_begin("MyScroll", &scroll);
//     /* ... scrollable content ... */
//   ui_scroll_end("MyScroll", &scroll);

typedef struct UI_ScrollState {
    B32 dragging;
    F32 drag_start_y;
    F32 drag_start_scroll;
} UI_ScrollState;

// Opens a horizontal row containing a vertical-scroll content area.
// The content area clips vertically and uses Clay_GetScrollOffset().
void ui_scroll_begin(const char *id, UI_ScrollState *state);

// Closes the content area and draws the scrollbar thumb/track.
void ui_scroll_end(const char *id, UI_ScrollState *state);
