#include <SupportDefs.h>
#include <UTF8.h>
#include <stdio.h>
#include <string.h>
#include "BeFontEncoding.h"

static BeCharacterEncoding _beSymbolEncoding[] = {
{"Alpha",			0x391},
{"Beta",			0x392},
{"Chi",				0x3a7},
{"Delta",			0x2206},
{"Epsilon",			0x395},
{"Eta",				0x397},
{"Euro",			0x2208}, // element of
{"Gamma",			0x393},
{"Ifraktur",		0x2111},
{"Iota",			0x399},
{"Kappa",			0x39a},
{"Lambda",			0x39b},
{"Mu", 				0x39c},
{"Nu",				0x39d},
{"Omega", 			0x3a9},
{"Omicron", 		0x39f},
{"Phi", 			0x3c6},
{"Pi", 				0x3a0},
{"Psi", 			0x3a8},
{"Rfraktur", 		0x211c},
{"Rho", 			0x3a1},
{"Sigma", 			0x3a3},
{"Tau", 			0x3a4},
{"Theta", 			0x398},
{"Ulsilon1",		0x3d2},
{"Upsilon", 		0x3a5},
{"Xi", 				0x39e},
{"Zeta", 			0x396},
{"aleph", 			0x2135},
{"alpha", 			0x3b1},
{"ampersand", 		0x26},
{"angle", 			0x2220},
{"angleleft", 		0x2329},
{"angleright", 		0x232a},
{"apple", 			0xf000}, //
{"approxequal", 	0x2248},
{"arrowboth", 		0x2194},
{"arrowdblboth", 	0x21d4},
{"arrowdbldown", 	0x21d3},
{"arrowdblleft", 	0x21d0},
{"arrowdblright", 	0x21d2},
{"arrowdblup", 		0x21d1},
{"arrowdown", 		0x2193},
{"arrowhorizex", 	0xf0be},
{"arrowleft", 		0x2190},
{"arrowright", 		0x2192},
{"arrowup", 		0x2191},
{"arrowvertex", 	0xf0bd},
{"asteriskmath", 	0x2217},
{"bar", 			0x7c},
{"beta", 			0x3b2},
{"braceex", 		0xf0ef},
{"braceleft", 		0x7b},
{"braceleftbt", 	0xf0ee},
{"braceleftmid",	0xf0ed},
{"bracelefttp", 	0xf0ec},
{"braceright", 		0x7d},
{"bracerightbt", 	0xf0fe},
{"bracerightmid", 	0xf0fd},
{"bracerighttp", 	0xf0fc},
{"bracketleft", 	0x5b},
{"bracketleftbt", 	0xf0eb},
{"bracketleftex", 	0xf0ea},
{"bracketlefttp", 	0xf0e9},
{"bracketright", 	0x5d},
{"bracketrightbt", 	0xf0fb},
{"bracketrightex", 	0xf0fa},
{"bracketrighttp", 	0xf0f9},
{"bullet", 			0x2022},
{"carriagereturn",	0x21b5},
{"chi", 			0x3c7},
{"circlemultiply", 	0x2297},
{"circleplus", 		0x2295},
{"club", 			0x2663},
{"colon", 			0x3a},
{"comma", 			0x2c},
{"congruent", 		0x2245},
{"copyrightsans", 	0xf0e2},
{"copyrightserif", 	0xa9},
{"degree",			0xb0},
{"delta",			0x3b4},
{"diamond",			0x2666},
{"divide",			0xf7},
{"dotmath",			0x22c5},
{"eight",			0x38},
{"element",			0x2208},
{"ellipsis",		0x2026},
{"emptyset",		0x2205},
{"epsilon",			0x3b5},
{"equal",			0x3d},
{"equivalence",		0x2261},
{"eta",				0x3b7},
{"exclam",			0x21},
{"existential",		0x2203},
{"five",			0x35},
{"florin",			0x192},
{"four",			0x34},
{"fraction",		0x2215},
{"gamma",			0x3b3},
{"gradient",		0x2207},
{"greater",			0x3e},
{"greaterequal",	0x2265},
{"heart",			0x2665},
{"infinity",		0x221e},
{"integral",		0x222b},
{"integralbt",		0x2321},
{"integralex",		0xf0f4}, // ?
{"integraltp",		0x2320},
{"intersection",	0x2229},
{"iota",			0x3b9},
{"kappa",			0x3ba},
{"lambda",			0x3bb},
{"less",			0x3c},
{"lessequal",		0x2264},
{"logicaland",		0x2227},
{"logicalnot",		0xac},
{"logicalor",		0x2228},
{"lozenge",			0x25ca},
{"minus",			0x2212},
{"minute",			0x2032},
{"mu",				0xb5},
{"multiply",		0xd7},
{"nine",			0x39},
{"notelement",		0x2209},
{"notequal",		0x2260},
{"notsubset",		0x2284},
{"nu",				0x3bd},
{"numbersign",		0x23},
{"omega",			0x3c9},
{"omega1",			0x3d6},
{"omicron",			0x3bf},
{"one",				0x31},
{"parenleft",		0x28},
{"parenleftbt",		0xf0e8},
{"parenleftex",		0xf0e7},
{"parenlefttp",		0xf0e6},
{"parenright",		0x29},
{"parenrightbt",	0xf0f8},
{"parenrightex",	0xf0f7},
{"parenrighttp",	0xf0f6},
{"partialdiff",		0x2202},
{"percent",			0x25},
{"period",			0x2e},
{"perpendicular",	0x22a5},
{"phi",				0x3c6},
{"phil",			0x3d5},
{"pi",				0x3c0},
{"plus",			0x2b},
{"plusminus",		0xb1},
//{"prime",			0x3c6}, // cmsy char name for phi
{"product",			0x220f},
{"productsuperset",	0x2283},
{"propersubset",	0x2282},
{"proportional",	0x221d},
{"psi",				0x3c8},
{"question",		0x3f},
{"radical",			0x221a},
{"radicalex",		0x203e},
{"reflexsubset",	0x2286},
{"reflexsuperset",	0x2287},
{"registersans",	0xf0e2},
{"registerserif",	0xae},
{"rho",				0x3c1},
{"second",			0x2033},
{"semicolon",		0x3b},
{"seven",			0x37},
{"sigma",			0x3c3},
{"sigmal",			0x3c2},
{"similar",			0x223c},
{"six",				0x36},
{"slash",			0x2f},
{"space",			0x20},
{"spade",			0x2660},
{"suchthat",		0x220b},
{"summation",		0x2211},
{"tau",				0x3c4},
{"therefore",		0x2234},
{"theta",			0x3b8},
{"theta1",			0x3d1},
{"three",			0x33},
{"trademarksans",	0xf0e4},
{"trademarkserif",	0x2122},
{"two",				0x32},
{"underscore",		0x5f},
{"union",			0x222a},
{"universal",		0x2200},
{"upsilon",			0x3c5},
{"weierstrass",		0x2218},
{"xi",				0x3be},
{"zero",			0x30},
{"zeta",			0x3b6},
{NULL}
};

static BeCharacterEncoding _beStandardEncoding[] = {
{"A",				65},
{"AE",				198},
{"Aacute",			193},
{"Acircumflex",		194},
{"Adieresis",		196},
{"Agrave",			192},
{"Aring",			197},
{"Atilde",			195},
{"B",				66},
{"C",				67},
{"Ccedilla",		199},
{"D",				68},
{"E",				69},
{"Eacute",			201},
{"Ecircumflex",		202},
{"Edieresis",		203},
{"Egrave",			200},
{"Eth",				208},
{"Euro",			0x2208},//
{"F",				70},
{"G",				71},
{"H",				72},
{"I",				73},
{"Iacute",			205},
{"Icircumflex",		206},
{"Idieresis",		207},
{"Igrave",			204},
{"J",				74},
{"K",				75},
{"L",				76},
{"Lslash",			0x141},//
{"M",				77},
{"N",				78},
{"Ntilde",			209},
{"O",				79},
{"OE",				0x152},
{"Oacute",			211},
{"Ocircumflex",		212},
{"Odieresis",		214},
{"Ograve",			210},
{"Oslash",			216},
{"Otilde",			213},
{"P",				80},
{"Q",				81},
{"R",				82},
{"S",				83},
{"Scaron",			0x160},
{"T",				84},
{"Thorn",			222},
{"U",				85},
{"Uacute",			218},
{"Ucircumflex",		219},
{"Udieresis",		220},
{"Ugrave",			217},
{"V",				86},
{"W",				87},
{"X",				88},
{"Y",				89},
{"Yacute",			221},
{"Ydieresis",		0x178},
{"Z",				90},
{"Zcaron",			0x17d},
{"a",				97},
{"aacute",			225},
{"acircumflex",		226},
{"acute",			180},
{"adieresis",		228},
{"ae",				230},
{"agrave",			224},
{"ampersand",		38},
{"aring",			229},
{"asciicircum",		94},
{"asciitilde",		126},
{"asterisk",		42},
{"at",				64},
{"atilde",			227},
{"b",				98},
{"backslash",		92},
{"bar",				124},
{"braceleft",		123},
{"braceright",		125},
{"bracketleft",		91},
{"bracketright",	93},
{"breve",			0x2d8},
{"brokenbar",		166},
{"bullet",			0x2022},
{"c",				99},
{"caron",			0x2c7},
{"ccedilla",		231},
{"cedilla",			184},
{"cent",			162},
{"circumflex",		0x2c6},
{"colon",			58},
{"comma",			44},
{"copyright",		169},
{"currency",		164},
{"d",				100},
{"dagger",			0x2020},
{"daggerdbl",		0x2021},
{"degree",			176},
{"dieresis",		168},
{"divide",			247},
{"dollar",			36},
{"dotaccent",		0x2d9},
{"dotlessi",		0x131},
{"e",				101},
{"eacute",			233},
{"ecircumflex",		234},
{"edieresis",		235},
{"egrave",			232},
{"eight",			56},
{"ellipsis",		0x2026},
{"emdash",			0x2014},
{"endash",			0x2013},
{"equal",			61},
{"eth",				240},
{"exclam",			33},
{"exclamdown",		161},
{"f",				102},
{"fi",				-1},//
{"five",			53},
{"fl",				-1},//
{"florin",			0x192},
{"four",			52},
{"fraction",		0x2215},
{"g",				103},
{"germandbls",		223},
{"grave",			96},
{"greater",			62},
{"guillemotleft",	171},
{"guillemotright",	187},
{"guilsinglleft",	0x2039},
{"guilsinglright",	0x203a},
{"h",				104},
{"hungarumlaut",	0x2dd},
{"hyphen",			173},
{"i",				105},
{"iacute",			237},
{"icircumflex",		238},
{"idieresis",		239},
{"igrave",			236},
{"j",				106},
{"k",				107},
{"l",				108},
{"less",			60},
{"logicalnot",		172},
{"lslash",			0x142},
{"m",				109},
{"macron",			175},
{"minus",			45},
{"mu",				181},
{"multiply",		215},
{"n",				110},
{"nine",			57},
{"ntilde",			241},
{"numbersign",		35},
{"o",				111},
{"oacute",			243},
{"ocircumflex",		244},
{"odieresis",		246},
{"oe",				0x153},
{"ogonek",			0x2db},
{"ograve",			242},
{"one",				49},
{"onehalf",			189},
{"onequarter",		188},
{"onesuperior",		185},
{"ordfeminine",		170},
{"ordmasculine",	186},
{"oslash",			248},
{"otilde",			245},
{"p",				112},
{"paragraph",		182},
{"parenleft",		40},
{"parenright",		41},
{"percent",			37},
{"period",			46},
{"periodcentered",	183},
{"perthousand",		0x2030},
{"plus",			43},
{"plusminus",		177},
{"q",				113},
{"question",		63},
{"questiondown",	191},
{"quotedbl",		34},
{"quotedblbase",	0x201e},
{"quotedblleft",	0x201c},
{"quotedblright",	0x201d},
{"quoteleft",		0x2018},
{"quoteright",		0x2019},
{"quotesinglbase",	0x201a},
{"quotesingle",		0x2019},
{"r",				114},
{"registered",		174},
{"ring",			0x2da},
{"s",				115},
{"scaron",			0x161},
{"section",			167},
{"semicolon",		59},
{"seven",			55},
{"six",				54},
{"slash",			47},
{"space",			32},
{"sterling",		163},
{"t",				116},
{"thorn",			254},
{"three",			51},
{"threequarters",	190},
{"threesuperior",	179},
{"tilde",			0x2dc},
{"trademark",		0x2122},
{"two",				50},
{"twosuperior",		178},
{"u",				117},
{"uacute",			250},
{"ucircumflex",		251},
{"udieresis",		252},
{"ugrave",			249},
{"underscore",		95},
{"v",				118},
{"w",				119},
{"x",				120},
{"y",				121},
{"yacute",			253},
{"ydieresis",		255},
{"yen",				165},
{"z",				122},
{"zcaron",			0x17e},
{"zero",			48},
{NULL}
//
//"no-break-space",	160
};

static const char *emptyString = "";

BeFontEncoding beSymbolEncoding(_beSymbolEncoding);
BeFontEncoding beStandardEncoding(_beStandardEncoding);

uint16 BeFontEncoding::toUnicode(const char *string) {
	int32 srcLength = strlen(string), length = 2, state = 0;
	uint16 ch;
	convert_from_utf8(B_UNICODE_CONVERSION,
			string,
			&srcLength,
			(char*)&ch,
			&length,
			&state);
	if (length == 0)
		return 0;
	else
		return ch;
}

int32 BeFontEncoding::toUtf8(uint16 unicode, char *string) {
	int32 srcLength = 2, length = 4, state = 0;
	char s[2];

	s[0] = unicode / 256;
	s[1] = unicode % 256;

	convert_to_utf8(B_UNICODE_CONVERSION, 
		s, 
		&srcLength,
		string, 
		&length, 
		&state);
		
	string[length] = 0;
	return length;
}

//
BeFontEncoding::BeFontEncoding(BeCharacterEncoding *encoding) {
	this->encoding = encoding;
	BeCharacterEncoding *enc = encoding;
	size = 0;
	while (enc->name != NULL) {
		if (enc->unicode == -1) {
			strcpy(enc->utf8, enc->name);
		} else {
			toUtf8(enc->unicode, enc->utf8);
		}
		enc ++;	size ++;
	}	
}

int32 BeFontEncoding::getIndex(const char *name) {
int16 min = 0, max = size - 1, k, current;
	while (min <= max) {
		current = (min + max) / 2;
		k = strcmp(name, encoding[current].name);
		if (k < 0) {
			max = current - 1;
		} else if (k > 0) {
			min = current + 1;
		} else {
			return current;
		}
	}
	return -1;
}

const char * BeFontEncoding::getUtf8(const char *name) {
int32 i = getIndex(name);
	if (i != -1) {
		return encoding[i].utf8;
	} else {
		return emptyString;
	}
}

const char *BeFontEncoding::getUtf8At(int32 i) {
	if ((i >= 0) && (i < size)) {
		return encoding[i].utf8;
	} else {
		return emptyString;
	}
};

