/**
 * @file    choice.c
 * @brief   Filling a CHOICE group and reading the chosen option.
 *          A reading aid for the tutorial page "widget-types", not a complete
 *          plugin: the functions below would be wired into an IcPlugin
 *          (on_widget_event) or called from init()/a Worker callback.
 *
 * @note    ASCII-only and C89 on purpose (VC6 / CP950 safe, and it must pass
 *          the syntax-only guard). The widget ids match choice.nxlay.
 */

#include <string.h>

#include "nexus_plugin_api.h"

/** @brief The HostAPI table, saved by init() (not shown here). */
static const NxHostApi *s_host = (const NxHostApi *)0;

/** @brief widget id of the CHOICE ([w.1] in choice.nxlay). */
#define WID_SPEED 1

/** @brief Option texts; a CHOICE group fills its options the same way as a DROPDOWN (NX_WP_ITEMS). */
static const char *const s_speeds[3] = { "Slow", "Normal", "Fast" };

/**
 * @brief  Call once from init() (UI Thread).
 * @return ERR_OK or an error code.
 * @note   NX_WP_ITEMS is a BLOB: one NxItemHead per item, followed by the item
 *         text, each record padded to a multiple of 4 bytes. At most 8 items.
 *         The value of the widget is the item INDEX. The host copies the blob
 *         during the call only.
 */
NxLong choice_setup(NxPluginCtx ctx)
{
    unsigned char buf[3 * 24];
    NxPropVal     v;
    NxItemHead    h;
    NxDword       pos = 0;
    NxDword       rec;
    int           i;

    for (i = 0; i < 3; i++)
    {
        h.text_len   = (NxWord)strlen(s_speeds[i]);
        h.detail_len = 0;
        h.item_id    = (NxDword)i;
        h.flags      = 0;
        rec = ((NxDword)sizeof(h) + h.text_len + 3u) & ~3u;
        memset(buf + pos, 0, rec);
        memcpy(buf + pos, &h, sizeof(h));
        memcpy(buf + pos + sizeof(h), s_speeds[i], h.text_len);
        pos += rec;
    }
    memset(&v, 0, sizeof(v));
    v.SizeOfStruct = (NxDword)sizeof(v);
    v.kind         = (NxWord)NX_WKIND_BLOB;
    v.u.blob.ptr   = buf;
    v.u.blob.len   = pos;
    return s_host->SetWidgetProp(ctx, 0, WID_SPEED, NX_WP_ITEMS, &v);
}

/**
 * @brief  Widget event handler: evt->val.u.i64 is the chosen option (0-based).
 */
void NX_CALL choice_on_event(NxPluginCtx ctx, NxByte panel_id, NxWord widget_id,
                    const NxWidgetEvent *evt)
{
    NX_UNUSED_ARG(panel_id);
    if (widget_id == WID_SPEED && evt->kind == NX_WEVT_CHANGED &&
        evt->val.kind == NX_WKIND_I64 && evt->val.u.i64 >= 0 && evt->val.u.i64 < 3)
    {
        s_host->LogWrite(ctx, NX_LOG_INFO, s_speeds[(int)evt->val.u.i64]);
    }
}

/**
 * @brief  Selects an option; index must be smaller than the number of options.
 */
NxLong choice_select(NxPluginCtx ctx, NxDword index)
{
    NxPropVal v;

    memset(&v, 0, sizeof(v));
    v.SizeOfStruct = (NxDword)sizeof(v);
    v.kind         = (NxWord)NX_WKIND_I64;
    v.u.i64        = (NxI64)index;
    return s_host->SetWidgetProp(ctx, 0, WID_SPEED, NX_WP_VALUE, &v);
}
