#include "ksyms.h"
#include <stdio.h>

static char *latin1_syms[] = {
	"nul",
	"Control_a",
	"Control_b",
	"Control_c",
	"Control_d",
	"Control_e",
	"Control_f",
	"Control_g",
	"BackSpace",
	"Tab",
	"Linefeed",
	"Control_k",
	"Control_l",
	"Control_m",
	"Control_n",
	"Control_o",
	"Control_p",
	"Control_q",
	"Control_r",
	"Control_s",
	"Control_t",
	"Control_u",
	"Control_v",
	"Control_w",
	"Control_x",
	"Control_y",
	"Control_z",
	"Escape",
	"Control_backslash",
	"Control_bracketright",
	"Control_asciicircum",
	"Control_underscore",
	"space",
	"exclam",
	"quotedbl",
	"numbersign",
	"dollar",
	"percent",
	"ampersand",
	"apostrophe",
	"parenleft",
	"parenright",
	"asterisk",
	"plus",
	"comma",
	"minus",
	"period",
	"slash",
	"zero",
	"one",
	"two",
	"three",
	"four",
	"five",
	"six",
	"seven",
	"eight",
	"nine",
	"colon",
	"semicolon",
	"less",
	"equal",
	"greater",
	"question",
	"at",
	"A",
	"B",
	"C",
	"D",
	"E",
	"F",
	"G",
	"H",
	"I",
	"J",
	"K",
	"L",
	"M",
	"N",
	"O",
	"P",
	"Q",
	"R",
	"S",
	"T",
	"U",
	"V",
	"W",
	"X",
	"Y",
	"Z",
	"bracketleft",
	"backslash",
	"bracketright",
	"asciicircum",
	"underscore",
	"grave",
	"a",
	"b",
	"c",
	"d",
	"e",
	"f",
	"g",
	"h",
	"i",
	"j",
	"k",
	"l",
	"m",
	"n",
	"o",
	"p",
	"q",
	"r",
	"s",
	"t",
	"u",
	"v",
	"w",
	"x",
	"y",
	"z",
	"braceleft",
	"bar",
	"braceright",
	"asciitilde",
	"Delete",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"",
	"nobreakspace",
	"exclamdown",
	"cent",
	"sterling",
	"currency",
	"yen",
	"brokenbar",
	"section",
	"diaeresis",
	"copyright",
	"ordfeminine",
	"guillemotleft",
	"notsign",
	"hyphen",
	"registered",
	"macron",
	"degree",
	"plusminus",
	"twosuperior",
	"threesuperior",
	"acute",
	"mu",
	"paragraph",
	"periodcentered",
	"cedilla",
	"onesuperior",
	"masculine",
	"guillemotright",
	"onequarter",
	"onehalf",
	"threequarters",
	"questiondown",
	"Agrave",
	"Aacute",
	"Acircumflex",
	"Atilde",
	"Adiaeresis",
	"Aring",
	"AE",
	"Ccedilla",
	"Egrave",
	"Eacute",
	"Ecircumflex",
	"Ediaeresis",
	"Igrave",
	"Iacute",
	"Icircumflex",
	"Idiaeresis",
	"ETH",
	"Ntilde",
	"Ograve",
	"Oacute",
	"Ocircumflex",
	"Otilde",
	"Odiaeresis",
	"multiplication",
	"Ooblique",
	"Ugrave",
	"Uacute",
	"Ucircumflex",
	"Udiaeresis",
	"Yacute",
	"THORN",
	"ssharp",
	"agrave",
	"aacute",
	"acircumflex",
	"atilde",
	"adiaeresis",
	"aring",
	"ae",
	"ccedilla",
	"egrave",
	"eacute",
	"ecircumflex",
	"ediaeresis",
	"igrave",
	"iacute",
	"icircumflex",
	"idiaeresis",
	"eth",
	"ntilde",
	"ograve",
	"oacute",
	"ocircumflex",
	"otilde",
	"odiaeresis",
	"division",
	"oslash",
	"ugrave",
	"uacute",
	"ucircumflex",
	"udiaeresis",
	"yacute",
	"thorn",
	"ydiaeresis"
};

char *latin2_syms[] = {
    "", "Aogonek", "breve", "Lstroke", "", "Lcaron", "Sacute", "",
    "", "Scaron", "Scedilla", "Tcaron", "Zacute", "", "Zcaron", "Zabovedot",
    "", "aogonek", "ogonek", "lstroke", "", "lcaron", "sacute", "caron",
    "", "scaron", "scedilla", "tcaron", "zacute", "doubleacute", "zcaron", "zabovedot",
    "Racute", "", "", "Abreve", "", "Lacute", "Cacute", "",
    "Ccaron", "", "Eogonek", "", "Ecaron", "", "", "Dcaron",
    "Dstroke", "Nacute", "Ncaron", "", "", "Odoubleacute", "", "",
    "Rcaron", "Uring", "", "Udoubleacute", "", "", "Tcedilla", "",
    "racute", "", "", "abreve", "", "lacute", "cacute", "",
    "ccaron", "", "eogonek", "", "ecaron", "", "", "dcaron",
    "dstroke", "nacute", "ncaron", "", "", "odoubleacute", "", "",
    "rcaron", "uring", "", "udoubleacute", "", "", "tcedilla", "abovedot"
};

char *latin3_syms[] = {
    "", "Hstroke", "", "", "", "", "Hcircumflex", "",
    "", "Iabovedot", "", "Gbreve", "Jcircumflex", "", "", "",
    "", "hstroke", "", "", "", "", "hcircumflex", "",
    "", "idotless", "", "gbreve", "jcircumflex", "", "", "",
    "", "", "", "", "", "Cabovedot", "Ccircumflex", "",
    "", "", "", "", "", "", "", "",
    "", "", "", "", "", "Gabovedot", "", "",
    "Gcircumflex", "", "", "", "", "Ubreve", "Scircumflex", "",
    "", "", "", "", "", "cabovedot", "ccircumflex", "",
    "", "", "", "", "", "", "", "",
    "", "", "", "", "", "gabovedot", "", "",
    "gcircumflex", "", "", "", "", "ubreve", "scircumflex", ""
};

char *latin4_syms[] = {
    "", "", "kra", "Rcedilla", "", "Itilde", "Lcedilla", "",
    "", "", "Emacron", "Gcedilla", "Tslash", "", "", "",
    "", "", "", "rcedilla", "", "itilde", "lcedilla", "",
    "", "", "emacron", "gcedilla", "tslash", "ENG", "", "eng",
    "Amacron", "", "", "", "", "", "", "Iogonek",
    "", "", "", "", "Eabovedot", "", "", "Imacron",
    "", "Ncedilla", "Omacron", "Kcedilla", "", "", "", "",
    "", "Uogonek", "", "", "", "Utilde", "Umacron", "",
    "amacron", "", "", "", "", "", "", "iogonek",
    "", "", "", "", "eabovedot", "", "", "imacron",
    "", "ncedilla", "omacron", "kcedilla", "", "", "", "",
    "", "uogonek", "", "", "", "utilde", "umacron", ""
};

char *iso_8859_8_syms[] = {
    "", "", "", "", "", "", "", "",
    "", "", "multiplication", "", "", "", "", "overscore",
    "", "", "", "", "", "", "", "",
    "", "", "division", "", "", "", "", "",
    "", "", "", "", "", "", "", "",
    "", "", "", "", "", "", "", "",
    "", "", "", "", "", "", "", "",
    "", "", "", "", "", "", "", "doubleunderscore",
    "alef", "bet", "gimel", "dalet", "he", "vav", "zayin", "het",
    "tet", "yod", "finalkaf", "kaf", "lamed", "finalmem", "mem", "finalnun",
    "nun", "samekh", "ayin", "finalpe", "pe", "finaltsadi", "tsadi", "qof",
    "resh", "shin", "tav", "", "", "", "", ""
};

static char *fn_syms[] = {
	"F1",
	"F2",
	"F3",
	"F4",
	"F5",
	"F6",
	"F7",
	"F8",
	"F9",
	"F10",
	"F11",
	"F12",
	"F13",
	"F14",
	"F15",
	"F16",
	"F17",
	"F18",
	"F19",
	"F20",
	"Find",
	"Insert",
	"Remove",
	"Select",
	"Prior",
	"Next",
	"Macro",
	"Help",
	"Do",
	"Pause",
	"F21",
	"F22",
	"F23",
	"F24",
	"F25",
	"F26",
	"PageUp",
	"PageDown",
	"F27",
	"F28",
	"F29",
	"F30",
        "F31",
        "F32",
        "F33",
        "F34",
        "F35",
        "F36",
        "F37",
        "F38",
        "F39",
	"F40",
        "F41",
        "F42",
        "F43",
        "F44",
        "F45",
        "F46",
        "F47",
        "F48",
        "F49",
	"F50",
        "F51",
        "F52",
        "F53",
        "F54",
        "F55",
        "F56",
        "F57",
        "F58",
        "F59",
	"F60",
        "F61",
        "F62",
        "F63",
        "F64",
        "F65",
        "F66",
        "F67",
	"F68",
};

static char *spec_syms[] = {
	"VoidSymbol",
	"Return",
	"Show_Registers",
	"Show_Memory",
	"Show_State",
	"Break",
	"Last_Console",
	"Caps_Lock",
	"Num_Lock",
	"Scroll_Lock",
	"Scroll_Forward",
	"Scroll_Backward",
	"Boot",
	"Caps_On",
	"Compose"
};

static char *pad_syms[] = {
	"KP_0",
	"KP_1",
	"KP_2",
	"KP_3",
	"KP_4",
	"KP_5",
	"KP_6",
	"KP_7",
	"KP_8",
	"KP_9",
	"KP_Add",
	"KP_Subtract",
	"KP_Multiply",
	"KP_Divide",
	"KP_Enter",
	"KP_Comma",
	"KP_Period",
	"KP_MinPlus"
};

static char *dead_syms[] = {
	"dead_grave",
	"dead_acute",
	"dead_circumflex",
	"dead_tilde",
	"dead_diaeresis"
};

static char *cons_syms[] = {
	"Console_1",
	"Console_2",
	"Console_3",
	"Console_4",
	"Console_5",
	"Console_6",
	"Console_7",
	"Console_8",
	"Console_9",
	"Console_10",
	"Console_11",
	"Console_12",
	"Console_13",
	"Console_14",
	"Console_15",
	"Console_16",
	"Console_17",
	"Console_18",
	"Console_19",
	"Console_20",
	"Console_21",
	"Console_22",
	"Console_23",
	"Console_24"
};

static char *cur_syms[] = {
	"Down",
	"Left",
	"Right",
	"Up"
};

static char *shift_syms[] = {
	"Shift",
	"AltGr",
	"Control",
	"Alt",
	"Uncaps_Shift"
};

static char *meta_syms[] = {
	"Meta_nul",
	"Meta_Control_a",
	"Meta_Control_b",
	"Meta_Control_c",
	"Meta_Control_d",
	"Meta_Control_e",
	"Meta_Control_f",
	"Meta_Control_g",
	"Meta_BackSpace",
	"Meta_Tab",
	"Meta_Linefeed",
	"Meta_Control_k",
	"Meta_Control_l",
	"Meta_Control_m",
	"Meta_Control_n",
	"Meta_Control_o",
	"Meta_Control_p",
	"Meta_Control_q",
	"Meta_Control_r",
	"Meta_Control_s",
	"Meta_Control_t",
	"Meta_Control_u",
	"Meta_Control_v",
	"Meta_Control_w",
	"Meta_Control_x",
	"Meta_Control_y",
	"Meta_Control_z",
	"Meta_Escape",
	"Meta_Control_backslash",
	"Meta_Control_bracketright",
	"Meta_Control_asciicircum",
	"Meta_Control_underscore",
	"Meta_space",
	"Meta_exclam",
	"Meta_quotedbl",
	"Meta_numbersign",
	"Meta_dollar",
	"Meta_percent",
	"Meta_ampersand",
	"Meta_apostrophe",
	"Meta_parenleft",
	"Meta_parenright",
	"Meta_asterisk",
	"Meta_plus",
	"Meta_comma",
	"Meta_minus",
	"Meta_period",
	"Meta_slash",
	"Meta_zero",
	"Meta_one",
	"Meta_two",
	"Meta_three",
	"Meta_four",
	"Meta_five",
	"Meta_six",
	"Meta_seven",
	"Meta_eight",
	"Meta_nine",
	"Meta_colon",
	"Meta_semicolon",
	"Meta_less",
	"Meta_equal",
	"Meta_greater",
	"Meta_question",
	"Meta_at",
	"Meta_A",
	"Meta_B",
	"Meta_C",
	"Meta_D",
	"Meta_E",
	"Meta_F",
	"Meta_G",
	"Meta_H",
	"Meta_I",
	"Meta_J",
	"Meta_K",
	"Meta_L",
	"Meta_M",
	"Meta_N",
	"Meta_O",
	"Meta_P",
	"Meta_Q",
	"Meta_R",
	"Meta_S",
	"Meta_T",
	"Meta_U",
	"Meta_V",
	"Meta_W",
	"Meta_X",
	"Meta_Y",
	"Meta_Z",
	"Meta_bracketleft",
	"Meta_backslash",
	"Meta_bracketright",
	"Meta_asciicircum",
	"Meta_underscore",
	"Meta_grave",
	"Meta_a",
	"Meta_b",
	"Meta_c",
	"Meta_d",
	"Meta_e",
	"Meta_f",
	"Meta_g",
	"Meta_h",
	"Meta_i",
	"Meta_j",
	"Meta_k",
	"Meta_l",
	"Meta_m",
	"Meta_n",
	"Meta_o",
	"Meta_p",
	"Meta_q",
	"Meta_r",
	"Meta_s",
	"Meta_t",
	"Meta_u",
	"Meta_v",
	"Meta_w",
	"Meta_x",
	"Meta_y",
	"Meta_z",
	"Meta_braceleft",
	"Meta_bar",
	"Meta_braceright",
	"Meta_asciitilde",
	"Meta_Delete"
};

static char *ascii_syms[] = {
	"Ascii_0",
	"Ascii_1",
	"Ascii_2",
	"Ascii_3",
	"Ascii_4",
	"Ascii_5",
	"Ascii_6",
	"Ascii_7",
	"Ascii_8",
	"Ascii_9"
};

static char *lock_syms[] = {
	"Shift_Lock",
	"AltGr_Lock",
	"Control_Lock",
	"Alt_Lock"
};

#define E(x) { x, sizeof(x) / sizeof(char **) }

syms_entry syms[] = {
	E(latin1_syms),
	E(fn_syms),
	E(spec_syms),
	E(pad_syms),
	E(dead_syms),
	E(cons_syms),
	E(cur_syms),
	E(shift_syms),
	E(meta_syms),
	E(ascii_syms),
	E(lock_syms)   
};

#undef E

struct syn
synonyms[] = {
	{ "Control_h",		"BackSpace" },
	{ "Control_i",		"Tab" },
	{ "Control_j",		"Linefeed" },
	{ "Meta_Control_h",	"Meta_BackSpace" },
	{ "Meta_Control_i",	"Meta_Tab" },
	{ "Meta_Control_j",	"Meta_Linefeed" },
	{ "Home",		"Find" },
/* Unfortunately Delete already denotes ASCII 0177 */
/*	{ "Delete",		"Remove" }, */
	{ "End",		"Select" },
	{ "PageUp",		"Prior" },
	{ "PageDown",		"Next" },
	{ "multiply",		"multiplication" },
};

const int syms_size = sizeof(syms) / sizeof(syms_entry);
const int syn_size = sizeof(synonyms) / sizeof(synonyms[0]);

/* this is silly, I'll fix it some day */
struct cs {
    char *charset;
    char **charnames;
} charsets[] = {
    { "iso-8859-1", 0 },
    { "iso-8859-2", latin2_syms },
    { "iso-8859-3", latin3_syms },
    { "iso-8859-4", latin4_syms },
    { "iso-8859-8", iso_8859_8_syms }
};

void
set_charset(char *charset) {
	char **p;
	int i;

	for (i = 0; i < sizeof(charsets)/sizeof(charsets[0]); i++) {
	    if (!strcmp(charsets[i].charset, charset)) {
		p = charsets[i].charnames;
		if (p)
		  for (i = 160; i < 256; i++,p++) {
		    if(*p && **p)
		      syms[0].table[i] = *p;
		}
		return;
	    }
	}
	fprintf (stderr, "unknown charset %s - ignoring charset request\n",
		 charset);
}

