const gen3 = @import("../gen3.zig");
const rom = @import("../rom.zig");
const std = @import("std");

const io = std.io;
const mem = std.mem;

// TODO: Replace with Replacing/Escaping streams

pub const en_us = [_]rom.encoding.Char{
    .{ " ", "\x00" },
    .{ "À", "\x01" },
    .{ "Á", "\x02" },
    .{ "Â", "\x03" },
    .{ "Ç", "\x04" },
    .{ "È", "\x05" },
    .{ "É", "\x06" },
    .{ "Ê", "\x07" },
    .{ "Ë", "\x08" },
    .{ "Ì", "\x09" },
    .{ "Î", "\x0B" },
    .{ "Ï", "\x0C" },
    .{ "Ò", "\x0D" },
    .{ "Ó", "\x0E" },
    .{ "Ô", "\x0F" },
    .{ "Œ", "\x10" },
    .{ "Ù", "\x11" },
    .{ "Ú", "\x12" },
    .{ "Û", "\x13" },
    .{ "Ñ", "\x14" },
    .{ "ß", "\x15" },
    .{ "à", "\x16" },
    .{ "á", "\x17" },
    .{ "ç", "\x19" },
    .{ "è", "\x1A" },
    .{ "é", "\x1B" },
    .{ "ê", "\x1C" },
    .{ "ë", "\x1D" },
    .{ "ì", "\x1E" },
    .{ "î", "\x20" },
    .{ "ï", "\x21" },
    .{ "ò", "\x22" },
    .{ "ó", "\x23" },
    .{ "ô", "\x24" },
    .{ "œ", "\x25" },
    .{ "ù", "\x26" },
    .{ "ú", "\x27" },
    .{ "û", "\x28" },
    .{ "ñ", "\x29" },
    .{ "º", "\x2A" },
    .{ "ª", "\x2B" },
    .{ "{SUPER_ER}", "\x2C" },
    .{ "&", "\x2D" },
    .{ "+", "\x2E" },
    .{ "{LV}", "\x34" },
    .{ "=", "\x35" },
    .{ ";", "\x36" },
    .{ "¿", "\x51" },
    .{ "¡", "\x52" },
    .{ "{PK}", "\x53" },
    .{ "{PKMN}", "\x53\x54" },
    .{ "{POKEBLOCK}", "\x55\x56\x57\x58\x59" },
    .{ "Í", "\x5A" },
    .{ "%", "\x5B" },
    .{ "(", "\x5C" },
    .{ ")", "\x5D" },
    .{ "â", "\x68" },
    .{ "í", "\x6F" },
    .{ "{UNK_SPACER}", "\x77" },
    .{ "{UP_ARROW}", "\x79" },
    .{ "{DOWN_ARROW}", "\x7A" },
    .{ "{LEFT_ARROW}", "\x7B" },
    .{ "{RIGHT_ARROW}", "\x7C" },
    .{ "{SUPER_E}", "\x84" },
    .{ "<", "\x85" },
    .{ ">", "\x86" },
    .{ "{SUPER_RE}", "\xA0" },
    .{ "0", "\xA1" },
    .{ "1", "\xA2" },
    .{ "2", "\xA3" },
    .{ "3", "\xA4" },
    .{ "4", "\xA5" },
    .{ "5", "\xA6" },
    .{ "6", "\xA7" },
    .{ "7", "\xA8" },
    .{ "8", "\xA9" },
    .{ "9", "\xAA" },
    .{ "!", "\xAB" },
    .{ "?", "\xAC" },
    .{ ".", "\xAD" },
    .{ "-", "\xAE" },
    .{ "·", "\xAF" },
    .{ "…", "\xB0" },
    .{ "“", "\xB1" },
    .{ "”", "\xB2" },
    .{ "‘", "\xB3" },
    .{ "'", "\xB4" },
    .{ "♂", "\xB5" },
    .{ "♀", "\xB6" },
    .{ "¥", "\xB7" },
    .{ ",", "\xB8" },
    .{ "×", "\xB9" },
    .{ "/", "\xBA" },
    .{ "A", "\xBB" },
    .{ "B", "\xBC" },
    .{ "C", "\xBD" },
    .{ "D", "\xBE" },
    .{ "E", "\xBF" },
    .{ "F", "\xC0" },
    .{ "G", "\xC1" },
    .{ "H", "\xC2" },
    .{ "I", "\xC3" },
    .{ "J", "\xC4" },
    .{ "K", "\xC5" },
    .{ "L", "\xC6" },
    .{ "M", "\xC7" },
    .{ "N", "\xC8" },
    .{ "O", "\xC9" },
    .{ "P", "\xCA" },
    .{ "Q", "\xCB" },
    .{ "R", "\xCC" },
    .{ "S", "\xCD" },
    .{ "T", "\xCE" },
    .{ "U", "\xCF" },
    .{ "V", "\xD0" },
    .{ "W", "\xD1" },
    .{ "X", "\xD2" },
    .{ "Y", "\xD3" },
    .{ "Z", "\xD4" },
    .{ "a", "\xD5" },
    .{ "b", "\xD6" },
    .{ "c", "\xD7" },
    .{ "d", "\xD8" },
    .{ "e", "\xD9" },
    .{ "f", "\xDA" },
    .{ "g", "\xDB" },
    .{ "h", "\xDC" },
    .{ "i", "\xDD" },
    .{ "j", "\xDE" },
    .{ "k", "\xDF" },
    .{ "l", "\xE0" },
    .{ "m", "\xE1" },
    .{ "n", "\xE2" },
    .{ "o", "\xE3" },
    .{ "p", "\xE4" },
    .{ "q", "\xE5" },
    .{ "r", "\xE6" },
    .{ "s", "\xE7" },
    .{ "t", "\xE8" },
    .{ "u", "\xE9" },
    .{ "v", "\xEA" },
    .{ "w", "\xEB" },
    .{ "x", "\xEC" },
    .{ "y", "\xED" },
    .{ "z", "\xEE" },
    .{ "▶", "\xEF" },
    .{ ":", "\xF0" },
    .{ "Ä", "\xF1" },
    .{ "Ö", "\xF2" },
    .{ "Ü", "\xF3" },
    .{ "ä", "\xF4" },
    .{ "ö", "\xF5" },
    .{ "ü", "\xF6" },
    .{ "\\l", "\xFA" },
    .{ "\\p", "\xFB" },
    .{ "{PAUSE 0x0F}", "\xFC\x08\x0F" },
    .{ "{PAUSE 0x39}", "\xFC\x08\x39" },
    .{ "{PLAY_BGM}", "\xFC\x0B" },
    .{ "{TALL_PLUS}", "\xFC\x0C\xFB" },
    .{ "{PLAYER}", "\xFD\x01" },
    .{ "{STR_VAR_1}", "\xFD\x02" },
    .{ "{STR_VAR_2}", "\xFD\x03" },
    .{ "{STR_VAR_3}", "\xFD\x04" },
    .{ "{KUN}", "\xFD\x05" },
    .{ "{RIVAL}", "\xFD\x06" },
    .{ "{VERSION}", "\xFD\x07" },
    .{ "{AQUA}", "\xFD\x08" },
    .{ "{MAGMA}", "\xFD\x09" },
    .{ "{ARCHIE}", "\xFD\x0A" },
    .{ "{MAXIE}", "\xFD\x0B" },
    .{ "{KYOGRE}", "\xFD\x0C" },
    .{ "{GROUdON}", "\xFD\x0D" },
    .{ "\n", "\xFE" },
    .{ "$", "\xFF" },
};

test "en_us" {
    try rom.encoding.testCharMap(&en_us, "HELLO WORLD", "\xC2\xBF\xC6\xC6\xC9\x00\xD1\xC9\xCC\xC6\xBE");
    try rom.encoding.testCharMap(&en_us, "{PK}{PKMN}", "\x53\x53\x54");
}

pub fn encode(lang: gen3.Language, reader: anytype, out: []u8) !void {
    const map = switch (lang) {
        .en_us => &en_us,
    };

    var fos = io.fixedBufferStream(out);
    try rom.encoding.encodeEx(map, 0, reader, fos.writer());
    try fos.writer().writeByte(0xff);
}

pub fn decode(lang: gen3.Language, str: []const u8, writer: anytype) !void {
    const map = switch (lang) {
        .en_us => &en_us,
    };

    const end = mem.indexOfScalar(u8, str, 0xff) orelse str.len;
    try rom.encoding.encode(map, 1, str[0..end], writer);
}
