#define DVX_WIDGET_IMPL
// widgetSeparator.c  -- Separator widget (horizontal and vertical)
//
// A purely decorative widget that draws a 2px etched line (shadow +
// highlight pair) to visually divide groups of widgets. The etched
// line technique (dark line followed by light line offset by 1px)
// creates a subtle 3D groove that matches the Motif/Win3.1 aesthetic.
//
// Separate constructors (wgtHSeparator/wgtVSeparator) rather than a
// runtime orientation parameter because separators are always fixed
// orientation at construction time.
//
// The min size in the cross-axis is SEPARATOR_THICKNESS (2px), while
// the main axis min is 0 -- the separator stretches to fill the
// available width/height in its parent layout. This makes separators
// work correctly in both HBox and VBox containers without explicit
// sizing.
//
// No mouse/key handlers -- purely decorative, non-focusable.

#include "dvxWidgetPlugin.h"

#define SEPARATOR_THICKNESS  2

static int32_t sTypeId = -1;

typedef struct {
    bool vertical;
} SeparatorDataT;


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

static void widgetSeparatorDestroy(WidgetT *w);


// ============================================================
// widgetSeparatorCalcMinSize
// ============================================================

void widgetSeparatorCalcMinSize(WidgetT *w, const BitmapFontT *font) {
    (void)font;
    SeparatorDataT *d = (SeparatorDataT *)w->data;

    if (d->vertical) {
        w->calcMinW = SEPARATOR_THICKNESS;
        w->calcMinH = 0;
    } else {
        w->calcMinW = 0;
        w->calcMinH = SEPARATOR_THICKNESS;
    }
}


// ============================================================
// widgetSeparatorDestroy
// ============================================================

static void widgetSeparatorDestroy(WidgetT *w) {
    free(w->data);
    w->data = NULL;
}


// ============================================================
// widgetSeparatorPaint
// ============================================================

void widgetSeparatorPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors) {
    (void)font;
    SeparatorDataT *sd = (SeparatorDataT *)w->data;

    if (sd->vertical) {
        int32_t cx = w->x + w->w / 2;
        drawVLine(d, ops, cx, w->y, w->h, colors->windowShadow);
        drawVLine(d, ops, cx + 1, w->y, w->h, colors->windowHighlight);
    } else {
        int32_t cy = w->y + w->h / 2;
        drawHLine(d, ops, w->x, cy, w->w, colors->windowShadow);
        drawHLine(d, ops, w->x, cy + 1, w->w, colors->windowHighlight);
    }
}


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


static const WidgetClassT sClassSeparator = {
    .version = WGT_CLASS_VERSION,
    .flags   = 0,
    .handlers = {
        [WGT_METHOD_PAINT]         = (void *)widgetSeparatorPaint,
        [WGT_METHOD_CALC_MIN_SIZE] = (void *)widgetSeparatorCalcMinSize,
        [WGT_METHOD_DESTROY]       = (void *)widgetSeparatorDestroy,
    }
};

// ============================================================
// Widget creation functions
// ============================================================


WidgetT *wgtHSeparator(WidgetT *parent) {
    WidgetT *w = widgetAlloc(parent, sTypeId);

    if (w) {
        SeparatorDataT *d = calloc(1, sizeof(SeparatorDataT));
        w->data = d;
    }

    return w;
}


WidgetT *wgtVSeparator(WidgetT *parent) {
    WidgetT *w = widgetAlloc(parent, sTypeId);

    if (w) {
        SeparatorDataT *d = calloc(1, sizeof(SeparatorDataT));
        w->data      = d;
        d->vertical  = true;
    }

    return w;
}


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


static const struct {
    WidgetT *(*hSeparator)(WidgetT *parent);
    WidgetT *(*vSeparator)(WidgetT *parent);
} sApi = {
    .hSeparator = wgtHSeparator,
    .vSeparator = wgtVSeparator
};

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

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