// C95 / C11 wctype.h — wide-character classification + case folding.
//
// On the W65816 runtime wchar_t is 16-bit but text is Latin-1; the
// high byte is always zero.  All functions reduce to the byte
// equivalents in <ctype.h> by truncating to the low byte (anything
// in 0x100..0xFFFF is non-printable, non-alpha, non-digit per our
// Latin-1 assumption).

#ifndef _WCTYPE_H
#define _WCTYPE_H

#include <wchar.h>
#include <ctype.h>

typedef int wctype_t;
typedef int wctrans_t;

// In Latin-1, wide-char in 0x100..0xFFFF have no class.
#define _WCT_DELEGATE(name)                                         \
    static inline int isw##name(wint_t c) {                         \
        return (c >= 0 && c < 0x100) ? is##name((int)c) : 0;        \
    }

_WCT_DELEGATE(alnum)
_WCT_DELEGATE(alpha)
_WCT_DELEGATE(cntrl)
_WCT_DELEGATE(digit)
_WCT_DELEGATE(graph)
_WCT_DELEGATE(lower)
_WCT_DELEGATE(print)
_WCT_DELEGATE(punct)
_WCT_DELEGATE(space)
_WCT_DELEGATE(upper)
_WCT_DELEGATE(xdigit)

static inline int iswblank(wint_t c) {
    return (c == L' ' || c == L'\t');
}

static inline wint_t towlower(wint_t c) {
    return (c >= 0 && c < 0x100) ? (wint_t)tolower((int)c) : c;
}
static inline wint_t towupper(wint_t c) {
    return (c >= 0 && c < 0x100) ? (wint_t)toupper((int)c) : c;
}

// Programmatic lookup — not strictly needed but trivial to provide.
static inline wctype_t wctype(const char *name) {
    if (!name) return 0;
    // Minimal table — just enough for the common cases.
    char c0 = name[0], c1 = name[1];
    if (c0 == 'a' && c1 == 'l') return 1;   // alpha or alnum
    if (c0 == 'd') return 2;                // digit
    if (c0 == 'l') return 3;                // lower
    if (c0 == 'u') return 4;                // upper
    if (c0 == 's') return 5;                // space
    return 0;
}
static inline int iswctype(wint_t c, wctype_t t) {
    switch (t) {
    case 1: return iswalpha(c);
    case 2: return iswdigit(c);
    case 3: return iswlower(c);
    case 4: return iswupper(c);
    case 5: return iswspace(c);
    }
    return 0;
}

static inline wctrans_t wctrans(const char *name) {
    if (!name) return 0;
    if (name[0] == 't' && name[1] == 'o' && name[2] == 'l') return 1;
    if (name[0] == 't' && name[1] == 'o' && name[2] == 'u') return 2;
    return 0;
}
static inline wint_t towctrans(wint_t c, wctrans_t t) {
    switch (t) {
    case 1: return towlower(c);
    case 2: return towupper(c);
    }
    return c;
}

#endif
