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

#define DVX_WIDGET_IMPL
// widgetStatusBar.c  -- StatusBar widget
//
// A horizontal container that draws a sunken border around each visible
// child to create the classic segmented status bar appearance. Children
// are typically labels or other simple widgets, laid out by the generic
// horizontal box layout. The status bar itself has no special layout
// logic -- it's a standard HBox with tight padding/spacing and the
// extra per-child sunken border decorations.
//
// The border drawing is done as an overlay on top of children rather
// than as part of the child's own paint, because it wraps around
// the child's allocated area (extending 1px past each edge). This
// keeps the sunken-panel effect consistent regardless of the child
// widget type.
//
// No mouse/key handlers -- the status bar is purely display. Children
// that are interactive (e.g., a clickable label) handle their own events.

#include "dvxWgtP.h"

// Tight padding keeps the status bar visually a single-line strip
// (VB-style).  The per-child sunken bevel already adds 1px of visual
// inset around each panel, so additional container padding just makes
// the bar look chunky.
#define STATUSBAR_PAD        1
#define STATUSBAR_GAP        2

static int32_t sTypeId = -1;


// ============================================================
// Prototypes
// ============================================================

void     wgtRegister(void);
WidgetT *wgtStatusBar(WidgetT *parent);
void     widgetStatusBarGetLayoutMetrics(const WidgetT *w, const BitmapFontT *font, int32_t *pad, int32_t *gap, int32_t *extraTop, int32_t *borderW);
void     widgetStatusBarPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors);


// ============================================================
// DXE registration
// ============================================================


static const WidgetClassT sClassStatusBar = {
    .version = WGT_CLASS_VERSION,
    .flags   = WCLASS_HORIZ_CONTAINER,
    .handlers = {
        [WGT_METHOD_PAINT]              = (void *)widgetStatusBarPaint,
        [WGT_METHOD_GET_LAYOUT_METRICS] = (void *)widgetStatusBarGetLayoutMetrics,
        [WGT_METHOD_CALC_MIN_SIZE]      = (void *)widgetCalcMinSizeBox,
        [WGT_METHOD_LAYOUT]             = (void *)widgetLayoutBox,
    }
};

static const struct {
    WidgetT *(*create)(WidgetT *parent);
} sApi = {
    .create = wgtStatusBar
};

static const WgtIfaceT sIface = {
    .basName      = "StatusBar",
    .props        = NULL,
    .propCount    = 0,
    .methods      = NULL,
    .methodCount  = 0,
    .events       = NULL,
    .eventCount   = 0,
    .createSig    = WGT_CREATE_PARENT,
    .isContainer  = true
};

void wgtRegister(void) {
    sTypeId = wgtRegisterClass(&sClassStatusBar);
    wgtRegisterApi("statusbar", &sApi);
    wgtRegisterIface("statusbar", &sIface);
}


WidgetT *wgtStatusBar(WidgetT *parent) {
    // Layout padding/spacing come from widgetStatusBarGetLayoutMetrics, which
    // overrides any w->padding/spacing for metrics-bearing widgets, so no
    // create-time field writes are needed.
    return widgetAlloc(parent, sTypeId);
}


void widgetStatusBarGetLayoutMetrics(const WidgetT *w, const BitmapFontT *font, int32_t *pad, int32_t *gap, int32_t *extraTop, int32_t *borderW) {
    (void)w;
    (void)font;
    *pad      = STATUSBAR_PAD;
    *gap      = STATUSBAR_GAP;
    *extraTop = 0;
    *borderW  = 0;
}


// Draws a 1px sunken bevel (reversed highlight/shadow) around each
// child. The bevel.face=0 with width=1 means only the border lines
// are drawn, not a filled interior -- the child paints its own content.
void widgetStatusBarPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors) {
    (void)font;

    // Draw sunken border around each child
    for (WidgetT *c = w->firstChild; c; c = c->nextSibling) {
        if (!c->visible) {
            continue;
        }

        BevelStyleT bevel;
        bevel.highlight = colors->windowShadow;
        bevel.shadow    = colors->windowHighlight;
        bevel.face      = BEVEL_NO_FILL;
        bevel.width     = 1;
        drawBevel(d, ops, c->x - 1, c->y - 1, c->w + 2, c->h + 2, &bevel);
    }
}
