/*
    Copyright (C) 2025, The AROS Development Team. All rights reserved.
 */

/*
 * Classification and conversion tables for ASCII and ISO-8859-1
 * (Latin-1) Unicode compatibility chars (U+0000–U+00FF)
 */

#include <wctype.h>

#if __WCHAR_MAX__ > 255
#define UNICODE_TABLE_SIZE  256
#else
#define UNICODE_TABLE_SIZE  128
#endif

static const wchar_t unicode_l2u[UNICODE_TABLE_SIZE] = {
    // 0x00–0x1F: C0 control chars – identity
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,

    // 0x20–0x2F: Symbols and whitespace – identity
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
    0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,

    // 0x30–0x39: Digits – identity
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
    0x38, 0x39,

    // 0x3A–0x40: Symbols – identity
    0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40,

    // 0x41–0x5A: A–Z – already uppercase
    0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
    0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
    0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
    0x59, 0x5A,

    // 0x5B–0x60: Symbols – identity
    0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60,

    // 0x61–0x7A: a–z ? A–Z
    0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
    0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
    0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
    0x59, 0x5A,

    // 0x7B–0x7F: Symbols + DEL – identity
    0x7B, 0x7C, 0x7D, 0x7E, 

#if __WCHAR_MAX__ < 256
    0x7F
#else
    0x7F,
    // 0x80–0x9F: C1 controls – identity
    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
    0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
    0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,

    // 0xA0–0xBF: Symbols – identity
    0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
    0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
    0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
    0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,

    // 0xC0–0xDF: À–ß – already uppercase or special (ß)
    0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
    0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
    0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
    0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,

    // 0xE0–0xF6: à–ö ? À–Ö
    0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
    0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
    0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,

    // 0xF7: ÷ – identity
    0xF7,

    // 0xF8–0xFE: ø–þ ? Ø–Þ
    0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE,

    // 0xFF: ÿ ? Ÿ (U+0178, not in Latin-1)
    // We fallback to identity since U+0178 is outside 0x00–0xFF
    0xFF
#endif
};

static const wchar_t unicode_u2l[UNICODE_TABLE_SIZE] = {
    // 0x00–0x1F: C0 control chars – unchanged
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,

    // 0x20–0x2F: Symbols and whitespace – unchanged
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
    0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,

    // 0x30–0x39: Digits – unchanged
    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
    0x38, 0x39,

    // 0x3A–0x40: Symbols – unchanged
    0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40,

    // 0x41–0x5A: Uppercase A–Z ? a–z
    0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
    0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
    0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
    0x79, 0x7A,

    // 0x5B–0x60: Symbols – unchanged
    0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60,

    // 0x61–0x7A: Lowercase – identity
    0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
    0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70,
    0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
    0x79, 0x7A,

    // 0x7B–0x7F: Symbols + DEL – unchanged
    0x7B, 0x7C, 0x7D, 0x7E,

#if __WCHAR_MAX__ < 256
    0x7F
#else
    0x7F,
    // 0x80–0x9F: C1 controls – identity
    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
    0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
    0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,

    // 0xA0–0xBF: Symbols and non-case characters – identity
    0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7,
    0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
    0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7,
    0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,

    // 0xC0–0xD6: À–Ö ? à–ö
    0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
    0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
    // 0xD7: × – unchanged
    0xD7,
    // 0xD8–0xDE: Ø–Þ ? ø–þ
    0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE,

    // 0xDF: ß (already lowercase) – identity
    0xDF,

    // 0xE0–0xFF: à–ÿ – identity
    0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7,
    0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
    0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
    0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
#endif
};

static const wctype_t unicode_wctype[UNICODE_TABLE_SIZE] = {
    /* [0x00–0x1F]: control characters */
    [0x00 ... 0x1F] = _WCTYPE_CNTRL,
    [0x20] = _WCTYPE_BLANK | _WCTYPE_SPACE | _WCTYPE_PRINT,
    [0x09] = _WCTYPE_BLANK | _WCTYPE_SPACE,
    [0x0A ... 0x0D] = _WCTYPE_SPACE,

    /* Digits */
    [0x30 ... 0x39] = _WCTYPE_DIGIT | _WCTYPE_XDIGIT | _WCTYPE_ALNUM | _WCTYPE_PRINT | _WCTYPE_GRAPH,

    /* Uppercase letters */
    [0x41 ... 0x5A] = _WCTYPE_ALPHA | _WCTYPE_UPPER | _WCTYPE_PRINT | _WCTYPE_GRAPH,

    /* Lowercase letters */
    [0x61 ... 0x7A] = _WCTYPE_ALPHA | _WCTYPE_LOWER | _WCTYPE_PRINT | _WCTYPE_GRAPH,

    /* Hex alpha (A-F, a-f) */
    [0x41 ... 0x46] = _WCTYPE_XDIGIT,
    [0x61 ... 0x66] = _WCTYPE_XDIGIT,

    /* Punctuation */
    [0x21 ... 0x2F] = _WCTYPE_PUNCT | _WCTYPE_PRINT | _WCTYPE_GRAPH,
    [0x3A ... 0x40] = _WCTYPE_PUNCT | _WCTYPE_PRINT | _WCTYPE_GRAPH,
    [0x5B ... 0x60] = _WCTYPE_PUNCT | _WCTYPE_PRINT | _WCTYPE_GRAPH,
    [0x7B ... 0x7E] = _WCTYPE_PUNCT | _WCTYPE_PRINT | _WCTYPE_GRAPH,

#if __WCHAR_MAX__ < 256
    /* Printable but not graph (space) */
    [0x7F] = _WCTYPE_CNTRL
#else
    [0x7F] = _WCTYPE_CNTRL,
    [0xA0] = _WCTYPE_SPACE | _WCTYPE_PRINT,

    /* Latin-1 supplement classification (partial) */
    [0xC0 ... 0xD6] = _WCTYPE_ALPHA | _WCTYPE_UPPER | _WCTYPE_PRINT | _WCTYPE_GRAPH,
    [0xD8 ... 0xDE] = _WCTYPE_ALPHA | _WCTYPE_UPPER | _WCTYPE_PRINT | _WCTYPE_GRAPH,
    [0xE0 ... 0xF6] = _WCTYPE_ALPHA | _WCTYPE_LOWER | _WCTYPE_PRINT | _WCTYPE_GRAPH,
    [0xF8 ... 0xFE] = _WCTYPE_ALPHA | _WCTYPE_LOWER | _WCTYPE_PRINT | _WCTYPE_GRAPH,
    [0xDF] = _WCTYPE_ALPHA | _WCTYPE_LOWER | _WCTYPE_PRINT | _WCTYPE_GRAPH, /* ß */
#endif
};
