// 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.

// listHelp.h -- Public API for the shared list/dropdown helper library
//
// Declares dropdown arrow drawing, item length scanning, keyboard
// navigation, and popup list painting shared across widget DXEs
// (ListBox, Dropdown, ComboBox, ListView, TreeView).

#ifndef LIST_HELP_H
#define LIST_HELP_H

#include "../libdvx/dvxWgtP.h"

#define DROPDOWN_BTN_WIDTH   16
#define DROPDOWN_MAX_VISIBLE 8
#define POPUP_SCROLLBAR_W    SCROLLBAR_WIDTH

// ============================================================
// Owned string-array adoption
// ============================================================

// Rebuild an internally-owned stb_ds string array as a deep copy of an
// external source array, freeing any previously owned strings first.  Shared
// by ListBox (ownedItems) and ListView (ownedCells): a reorderable list must
// own its strings so drag-reorder can rewrite the array in place without
// mutating a caller-owned SetItems/SetData array.  Returns the (possibly
// reallocated) owned array so the caller can repoint its handle.  NULL source
// elements become empty strings.
char **widgetAdoptOwnedStrings(char **owned, const char **src, int32_t count);

// ============================================================
// Dropdown arrow glyph
// ============================================================

void widgetDrawDropdownArrow(DisplayT *d, const BlitOpsT *ops, int32_t centerX, int32_t centerY, uint32_t color);

// ============================================================
// Item measurement
// ============================================================

int32_t widgetMaxItemLen(const char **items, int32_t count);

// ============================================================
// Keyboard navigation (Up/Down/Home/End/PgUp/PgDn)
// ============================================================

int32_t widgetNavigateIndex(int32_t key, int32_t current, int32_t count, int32_t pageSize);

// ============================================================
// Popup rect calculation
// ============================================================

void widgetDropdownPopupRect(WidgetT *w, const BitmapFontT *font, int32_t contentH, int32_t itemCount, int32_t *popX, int32_t *popY, int32_t *popW, int32_t *popH);

// ============================================================
// Popup list painting
// ============================================================

void widgetPaintPopupList(DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors, int32_t popX, int32_t popY, int32_t popW, int32_t popH, const char **items, int32_t itemCount, int32_t hoverIdx, int32_t scrollPos);

// ============================================================
// Type-ahead search
// ============================================================

// Search items[] for the next entry starting with ch (case-insensitive),
// starting after currentIdx and wrapping around. Returns the matching
// index, or -1 if no match found.
int32_t widgetTypeAheadSearch(char ch, const char **items, int32_t itemCount, int32_t currentIdx);

// ============================================================
// Popup scrollbar hit testing
// ============================================================

// Returns true if the click at (x, y) is on the popup scrollbar.
// Updates *scrollPos in place (clamped to valid range).
bool widgetPopupScrollbarClick(int32_t x, int32_t y, int32_t popX, int32_t popY, int32_t popW, int32_t popH, int32_t itemCount, int32_t visibleItems, int32_t *scrollPos);

#endif // LIST_HELP_H
