#define DVX_WIDGET_IMPL
// widgetLabel.c  -- Label widget
//
// Static text display  -- the simplest widget. Not focusable, not interactive.
// Supports accelerator keys via '&' prefix: when the user presses Alt+key,
// focus moves to the next focusable widget after this label. This follows
// the Win3.1 convention where labels act as keyboard shortcuts for adjacent
// controls (e.g., a label "&Name:" before a text input).
//
// The text pointer is stored directly (not copied)  -- the caller must ensure
// the string remains valid for the widget's lifetime, or use widgetLabelSetText
// to update it. This avoids unnecessary allocations for the common case of
// literal string labels.
//
// Background is transparent by default (bgColor == 0 means use the parent's
// content background color from the color scheme). The +1 in calcMinH adds a
// pixel of breathing room below the text baseline.

#include "dvxWidgetPlugin.h"

static int32_t sTypeId = -1;

typedef struct {
    const char  *text;
    WidgetAlignE textAlign;
} LabelDataT;


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

static void widgetLabelDestroy(WidgetT *w);


// ============================================================
// widgetLabelCalcMinSize
// ============================================================

void widgetLabelCalcMinSize(WidgetT *w, const BitmapFontT *font) {
    LabelDataT *d = (LabelDataT *)w->data;
    w->calcMinW = textWidthAccel(font, d->text);
    w->calcMinH = font->charHeight + 1;
}


// ============================================================
// widgetLabelDestroy
// ============================================================

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


// ============================================================
// widgetLabelGetText
// ============================================================

const char *widgetLabelGetText(const WidgetT *w) {
    LabelDataT *d = (LabelDataT *)w->data;
    return d->text;
}


// ============================================================
// widgetLabelPaint
// ============================================================

void widgetLabelPaint(WidgetT *w, DisplayT *d, const BlitOpsT *ops, const BitmapFontT *font, const ColorSchemeT *colors) {
    LabelDataT *ld = (LabelDataT *)w->data;
    int32_t textW   = textWidthAccel(font, ld->text);
    int32_t textX   = w->x;
    int32_t textY   = w->y + (w->h - font->charHeight) / 2;

    if (ld->textAlign == AlignCenterE) {
        textX = w->x + (w->w - textW) / 2;
    } else if (ld->textAlign == AlignEndE) {
        textX = w->x + w->w - textW;
    }

    if (!w->enabled) {
        drawTextAccelEmbossed(d, ops, font, textX, textY, ld->text, colors);
        return;
    }

    uint32_t fg = w->fgColor ? w->fgColor : colors->contentFg;
    uint32_t bg = w->bgColor ? w->bgColor : colors->contentBg;

    drawTextAccel(d, ops, font, textX, textY, ld->text, fg, bg, false);
}


// ============================================================
// widgetLabelSetText
// ============================================================

void widgetLabelSetText(WidgetT *w, const char *text) {
    LabelDataT *d = (LabelDataT *)w->data;
    d->text     = text;
    w->accelKey = accelParse(text);
}


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


static const WidgetClassT sClassLabel = {
    .version = WGT_CLASS_VERSION,
    .flags   = WCLASS_FOCUS_FORWARD,
    .handlers = {
        [WGT_METHOD_PAINT]         = (void *)widgetLabelPaint,
        [WGT_METHOD_CALC_MIN_SIZE] = (void *)widgetLabelCalcMinSize,
        [WGT_METHOD_DESTROY]       = (void *)widgetLabelDestroy,
        [WGT_METHOD_GET_TEXT]      = (void *)widgetLabelGetText,
        [WGT_METHOD_SET_TEXT]      = (void *)widgetLabelSetText,
    }
};

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


WidgetT *wgtLabel(WidgetT *parent, const char *text) {
    WidgetT *w = widgetAlloc(parent, sTypeId);

    if (w) {
        LabelDataT *d = calloc(1, sizeof(LabelDataT));
        w->data        = d;
        d->text        = text;
        w->accelKey    = accelParse(text);
    }

    return w;
}


void wgtLabelSetAlign(WidgetT *w, WidgetAlignE align) {
    if (w && w->type == sTypeId) {
        LabelDataT *d = (LabelDataT *)w->data;
        d->textAlign = align;
    }
}


int32_t wgtLabelGetAlign(const WidgetT *w) {
    if (w && w->type == sTypeId) {
        LabelDataT *d = (LabelDataT *)w->data;
        return (int32_t)d->textAlign;
    }

    return 0;
}


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


static const struct {
    WidgetT *(*create)(WidgetT *parent, const char *text);
    void     (*setAlign)(WidgetT *w, WidgetAlignE align);
} sApi = {
    .create   = wgtLabel,
    .setAlign = wgtLabelSetAlign
};

static const char *sAlignNames[] = { "Left", "Center", "Right", NULL };

static const WgtPropDescT sProps[] = {
    { "Alignment", WGT_IFACE_ENUM, (void *)wgtLabelGetAlign, (void *)wgtLabelSetAlign, sAlignNames }
};

static const WgtIfaceT sIface = {
    .basName      = "Label",
    .props        = sProps,
    .propCount    = 1,
    .methods      = NULL,
    .methodCount  = 0,
    .events       = NULL,
    .eventCount   = 0,
    .createSig    = WGT_CREATE_PARENT_TEXT,
    .defaultEvent = "Click"
};

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