/* Unicode chart - http://www.unicode.org/charts/PDF/U0B80.pdf */

function ent(u, s, t)
{
	this.u = u; /* unicode number */
	this.s = s; /* english string */
	/*
	 * Type: special action
	 *	For uyir-mei letters, should the
	 *	vowel be 1 - appended, 2 - prepended or 3 - both
	 */
	this.t = t;
}

function rv(s, n)
{
	this.s = s; /* unicode number */
	this.n = n; /* no. of letters consumed */
}

/* Longest pattern should come first */
var uyir = [	/* vowels */
	new ent("&#2950;",	"A",	1),
	new ent("&#2960;",	"ai",	1),
	new ent("&#2964;",	"au",	1),
	new ent("&#2950;",	"aa",	1),
	new ent("&#2949;",	"a",	1),
	new ent("&#2952;",	"I",	1),
	new ent("&#2952;",	"ii",	1),
	new ent("&#2951;",	"i",	1),
	new ent("&#2954;",	"U",	1),
	new ent("&#2954;",	"uu",	1),
	new ent("&#2953;",	"u",	1),
	new ent("&#2959;",	"E",	1),
	new ent("&#2959;",	"ee",	1),
	new ent("&#2958;",	"e",	1),
	new ent("&#2963;",	"O",	1),
	new ent("&#2954;",	"oo",	1),
	new ent("&#2962;",	"o",	1),
	// special letters
	new ent("&#2947;",	"@",	0),	// ayutha ezhuthu
];

var mei = [	/* consonants */
	new ent("&#2965;",	"k",	0),
	new ent("&#2965;",	"g",	0),
	new ent("&#2969;",	"ng",	0),
	new ent("&#2969;",	"nG",	0),
	new ent("&#2970;",	"ch",	0),
	new ent("&#2970;",	"c",	0),
	new ent("&#2972;",	"j",	0),
	new ent("&#2974;",	"ny",	0),
	new ent("&#2974;",	"nY",	0),
	new ent("&#2980;",	"th",	0),
	new ent("&#2980;",	"dh",	0),
	new ent("&#2975;",	"d",	0),
	new ent("&#2979;",	"nN",	0),	// 3 suzhi
	new ent("&#2975;",	"t",	0),
	new ent("&#2984;",	"N",	0),	// 'tha' type
	new ent("&#2985;",	"n",	0),	// 2 suzhi
	new ent("&#2986;",	"p",	0),
	new ent("&#2986;",	"b",	0),
	new ent("&#2990;",	"m",	0),
	new ent("&#2991;",	"y",	0),
	new ent("&#2993;",	"R",	0),
	new ent("&#2992;",	"r",	0),
	new ent("&#2995;",	"L",	0),
	new ent("&#2994;",	"l",	0),
	new ent("&#2996;",	"zh",	0),
	new ent("&#2996;",	"z",	0),
	new ent("&#2997;",	"v",	0),
	new ent("&#2997;",	"w",	0),
	new ent("&#2998;",	"ss",	0),	// 'w' type sha
	new ent("&#2999;",	"sh",	0),	//
	new ent("&#3000;",	"s",	0),
	new ent("&#3001;",	"h",	0),
];

var uyirmei = [
	new ent("&#3006;",	"A",	0),
	new ent("&#3006;",	"aa",	0),
	new ent("&#3020;",	"au",	0),
	new ent("&#3016;",	"ai",	0),
	// Consume the 'kuril' 'a'. If a mei ezhuthu joins 'a',
	// it just looses its puLLi, unlike other uyir ezhuthus
	// that add a 'kaal' or 'kombu'
	new ent("",		"a",	1),
	new ent("&#3008;",	"I",	0),
	new ent("&#3008;",	"ii",	0),
	new ent("&#3007;",	"i",	0),
	new ent("&#3009;",	"u",	0),
	new ent("&#3010;",	"UU",	0),
	new ent("&#3010;",	"U",	0),
	new ent("&#3015;",	"E",	0),
	new ent("&#3008;",	"ee",	0),
	new ent("&#3014;",	"e",	0),
	new ent("&#3019;",	"O",	0),
	new ent("&#3010;",	"oo",	0),
	new ent("&#3018;",	"o",	0),
];

var puLLi = "&#3021;";

function get_char(s, n)
{
	if (s.length > n) {
		return s.charAt(n);
	}
	return "";
}

/*
 * s - string
 * n - index in the string
 * m - was the previous character a 'mei' ezhuthu
 */
function is_uyir(s, n, m)
{
	var	i, arr;

	if (m != 0) {
		arr = uyirmei;
	} else {
		arr = uyir;
	}

	for (i = 0; arr[i]; i++) {

		if (get_char(s, n) == get_char(arr[i].s, 0)) {
			if (arr[i].s.length > 1) {
				if (get_char(s, n + 1) == get_char(arr[i].s, 1)) {
					return new rv(arr[i].u, 2);
				}
			} else {
				return new rv(arr[i].u, 1);
			}
		}
	}
	return new rv("", 0);
}

function is_mei(s, n)
{
	var	i;

	for (i = 0; mei[i]; i++) {
		if (get_char(s, n) == get_char(mei[i].s, 0)) {
			if (mei[i].s.length > 1) {
				if (get_char(s, n + 1) == get_char(mei[i].s, 1)) {
					return new rv(mei[i].u, 2);
				}
			} else {
				return new rv(mei[i].u, 1);
			}
		}
	}
	return new rv("", 0);
}

function e2u(s)
{
	var	m, o, i, ret;
	o = "";

	for (i = 0; i < s.length;) {
		m = 0;
		ret = is_mei(s, i);
		if (ret.n) {
			o += ret.s;
			i += ret.n;
			m = 1;
		}
		ret = is_uyir(s, i, m);
		if (ret.n) {
			o += ret.s;
			i += ret.n;
			m = 1;
		} else if (m) {
			// 'puLLi' for the 'mei' ezhuthu
			o += puLLi;
			m = 1;
		}

		if (!m) {
			if (s.charAt(i) == "<") {
				if (s.charAt(i + 1) == "~") {
					// To avoid parsing enclose it in <~...>
					for (i += 2;i < s.length && s.charAt(i) != ">"; i++) {
						o += s.charAt(i);
					}
					// skip ">"
					i++;
					continue;
				} else {
					for (;i < s.length && s.charAt(i) != ">"; i++) {
						// skip html tags
						o += s.charAt(i);
					}
				}
			}
			// Non tamil character. Skip and proceed
			o += s.charAt(i);
			i++;
		}
	}

	if (i != s.length) {
		// alert("parse length doesnt match: " + s.length + " ~ " + i);
	}


	return o;
}

function is_mei_u(u)
{
	var	i;
	for (i = 0; mei[i]; i++) {
		if (mei[i].u == u) {
			return new rv(mei[i].s, mei[i].s.length);
		}
	}
	return new rv("", 0);
}

function is_uyir_u(u)
{
	var	i;
	for (i = 0; uyir[i]; i++) {
		if (uyir[i].u == u) {
			return new rv(uyir[i].s, uyir[i].s.length);
		}
	}
	for (i = 0; uyirmei[i]; i++) {
		if (uyirmei[i].u == u) {
			return new rv(uyirmei[i].s, uyirmei[i].s.length);
		}
	}
	return new rv("", 0);
}

function u2e(s)
{
	var	e, i, t, ret, a;

	if (s.length < 7) { return s; }

	a = e = "";

	for (i = 0; i < s.length;) {
		t = s.substr(i, 7);
		if ((s.charAt(i) != "&") ||
		    (t.search(/&#[0-9][0-9][0-9][0-9];/) == -1)) {
			// Not tamil unicode
			e += a + s.charAt(i);
			a = "";
			i ++;
			continue;
		}

		ret = is_mei_u(t);
		if (ret.n) {
			e += a + ret.s;
			i += 7;
			if (s.charAt(i) == "&") {
				t = s.substr(i, 7);
				if (t == puLLi) {
					i += 7;
					a = "";
				} else {
					// kuril 'a'
					a = 'a';
				}
			} else {
					// kuril 'a'
					a = 'a';
			}
		} else {
			ret = is_uyir_u(t);
			if (ret.n) {
				e += ret.s;
				i += 7;
			} else {
				e += a;
			}
			a = "";
		}
	}
	return e + a;
}

