
var gImeLang = '';
var gimeIcon= null;
var gStartPos = 0;
var gCurField = null;
var gHide = null;
var grgIME = new Array();
var gCurIME = -1;

function gg_GetCookie(name)
{
    var dc = document.cookie;
    var prefix = name + "=";
    var begin = dc.indexOf("; " + prefix);
    if (begin == -1)
    {
        begin = dc.indexOf(prefix);
        if (begin != 0) return null;
    }
    else
    {
        begin += 2;
    }
    var end = document.cookie.indexOf(";", begin);
    if (end == -1)
    {
        end = dc.length;
    }
    return dc.substring(begin + prefix.length, end);
}

function gg_CreateFrame(url, w, h, border, id, name, smooth)
{
	var body;
	var obj = 0;
	if (document.getElementsByTagName && document.getElementsByTagName('body'))
		body = document.getElementsByTagName('body')[0];
	if (!body)
		body = document.getElementsByTagName('frameset')[0];
	if (body)
	{
		obj = document.createElement("iframe");
		if (obj)
		{
			var width = window.innerWidth;
			if (!width)
				width = window.document.body.clientWidth;
			var height = window.innerHeight;
			if (!height)
				height = window.document.body.clientHeight;
			if (w == 0)
				w = width;
			if (h == 0)
				h = height;
			var x = (width - w)/2;
			if (x < 0)
				x = 0;
			var y = 0;
			if (smooth)
				y = -h;
			obj.setAttribute("ID", id);
			obj.setAttribute("data", url);
			obj.setAttribute("width", w);
			obj.setAttribute("height", h);
			obj.setAttribute("src", url);
			obj.setAttribute("frameBorder","0");
			obj.setAttribute("scrolling","no");
			obj.setAttribute("name", name);

			obj.style.position = "absolute";
			obj.style.overflow = "visible";
			obj.style.border = border;
			obj.style.width = "" + w +"px";
			obj.style.height = "" + h + "px";
			obj.style.left = "" + x + "px";
			obj.style.top = "" + y + "px";
			body.appendChild(obj);
	
			
			if (navigator.userAgent.indexOf("MSIE 5.0; Mac_PowerPC")>=0)
				window.open(url, name);
		}
	}
	return obj;
}

function gg_GetFrame(window_name)
{
	if (!document.getElementsByTagName)
		return null;
	var allFrames = document.getElementsByTagName("iframe");
	for (i=0; i < allFrames.length; i++)
	{
		var f = allFrames[i];
		if (f.name == window_name)
			return f;
	}
	return null;
}

function gg_DoSmooth(window_name)
{
	var win = gg_GetFrame(window_name);
	if (win)
	{
		var h = parseInt(win.style.top);
		var fUp = win.getAttribute("dirUp");
		if (fUp!=1 && h < 0)
		{
			h+=10;
			win.style.top = "" + h + "px";
		}
		else if (fUp==1 && h > -400)
		{
			h-=10;
			win.style.top = "" + h + "px";
		}
		else
		{
			var timerID = win.getAttribute("timer");
			clearInterval(timerID);
		}
	}
}



function gg_Smooth(window_name)
{
	var win = gg_GetFrame(window_name);
	if (win)
	{ 
		win.setAttribute("timer", setInterval("gg_DoSmooth('"+ window_name +"')", 25));
	}
}

function gg_SmoothUp(window_name)
{
	var win = gg_GetFrame(window_name);
	if (win)
	{
		win.setAttribute("dirUp", 1);
		win.setAttribute("timer", setInterval("gg_DoSmooth('"+ window_name +"')", 25));
	}
}

function ImeDef(argMethod, argRules, argMatcher, argIgnoreCase)
{
	this.m_method = argMethod;
	this.m_rules = argRules;
	this.m_match = argMatcher;
	this.m_fIgnoreCase = argIgnoreCase;
}

function getEvent(e)
{
	if (window.event)
		e = window.event;
	return e;	
}

function getTarget(e)
{
	var txtInput =  null;
	if (e.target)
		txtInput = e.target;
	else
		txtInput = e.srcElement;
	return txtInput;
}


var gszMarks = "#192:`#189:-#187:=#186:;#222:'#220:\\#219:[#221:]#188:,#190:.#191:/#";
var gszMarksShifted = "#192:~#189:_#187:+#186::#222:\"#220:|#219:{#221:}#188:<#190:>#191:?#";

var gnKeyCount = 0;
var gfBlockNext = false;
var gfSafari = false;
function wime_key(event)
{
	var e = getEvent(event);
	var txtInput =  getTarget(e);
	var srcText = "";
	var fMatched = false;

	// Ctrl-Enter - switch language
	if (e.keyCode==13 && e.ctrlKey)
	{
		wime_switch(event);
		return false;
	}

	if (grgIME==null || gCurIME<0)
		return true;


	
	if ((gfSafari && txtInput.value.length==0) ||							// Don't process first char in Safari, to avoid select bug.
		(e.keyCode>=37 && e.keyCode<=40) || e.keyCode==8 || e.keyCode==46)	// Handle Left, Right, Up, Down, Backspace and Delete.
	{
		gnKeyCount = 0;
		if (txtInput.selectionStart>=0)
			gStartPos = txtInput.selectionStart+1;
		else
			gStartPos = txtInput.value.length+1;
		return true;
	}

	// Don't process SHIFT key
	if (e.keyCode == 16)
		return true;

	// Get the typed character
	uniCode = e.keyCode;
	if (e.keyCode>=65 && e.keyCode<=90 && e.shiftKey==false)
	{
		// Make lower case latin char
		uniCode += 32;
	}

	var method = grgMethods[gCurIME].split(':')[0];

	if (document.selection)
	{ 
		// IE compat
		var cur = document.selection.createRange();
		cur.moveStart('character', -gnKeyCount);
		srcText = cur.text;
		gnKeyCount++;
	}
	else if (txtInput.selectionStart>=0)
	{ 
		// Mozilla
		var nStart = txtInput.selectionStart;
		var nEnd = txtInput.selectionEnd;
		if (gStartPos>nEnd)
			gStartPos = nEnd;
		else
			srcText = txtInput.value.substring(gStartPos, nEnd);
	}
	else 
	{
		// Other browsers: Safari and MacIE
		srcText = txtInput.value.substring(gStartPos, txtInput.value.length);
		if (gStartPos>txtInput.value.length)
			gStartPos = txtInput.value.length;
	}

	// Append the typed char
	if (e.type!="keyup")
	{
		var rgMark;
		var reMark = new RegExp("#" + e.keyCode + ":([^#])*#", '');
		if (e.shiftKey==true)
			rgMark = gszMarksShifted.match(reMark);
		else
			rgMark = gszMarks.match(reMark);
		if (rgMark && rgMark.length == 2)
			srcText += "\\" + rgMark[1];
		else
			srcText += String.fromCharCode(uniCode);
	}

	// Don't process empty text fields
	if (srcText.length==0)
	{
		window.status = "";
		return true;
	}

	
	// Lookup candidates
	if (grgIME[method].m_fIgnoreCase)
		srcText = srcText.toUpperCase();
	var reStr = grgIME[method].m_match.replace(/@/g, srcText);
	var reCand = new RegExp(reStr, 'g');
	rgCand = grgIME[method].m_rules.match(reCand);

	// Select among candidates?
	var szDig = srcText.substring(srcText.length-1, srcText.length);
	var nSel = -1;
	if (rgCand==null && srcText.length>1 && parseInt(szDig)>0)
	{
		nSel = parseInt(szDig);
		srcText = srcText.substring(0, srcText.length-1);
		reStr = grgIME[method].m_match.replace(/@/g, srcText);
		reCand = new RegExp(reStr, 'g');
		rgCand = grgIME[method].m_rules.match(reCand);

		if (nSel>0 && nSel<=rgCand.length)
		{
			rgNew = new Array();
			rgNew[0] = rgCand[nSel-1];
			rgCand = rgNew;
		}
	}

	if (rgCand!=null && rgCand.length==1)
	{
		uniVal = (rgCand+"").split(':')+"";
		var uniChars = "";
		window.status=uniVal;
		var rgOut = uniVal.split('x');
		for (j=1; j<rgOut.length; j++)
		{
			uniVal = parseInt(rgOut[j],16);
			uniChars += String.fromCharCode(uniVal);
		}

		// one match
		if (document.selection)
		{
			// IE
			cur.text = uniChars;
			gnKeyCount = 0;
		}
		else if (txtInput.selectionStart>=0)
		{
			// Mozilla
			oldVal = txtInput.value;
			newStart = gStartPos+1;
			txtInput.value = oldVal.substring(0, gStartPos) + uniChars + oldVal.substring(txtInput.selectionStart, oldVal.length);
			gStartPos = newStart;
			txtInput.selectionStart = newStart;
			txtInput.selectionEnd = newStart;
		}
		else
		{
			// Safari
			oldVal = txtInput.value;
			txtInput.value = oldVal.substring(0, gStartPos) + uniChars;
			gStartPos = txtInput.value.length;
		}
		fMatched = true;
	}
	else if (rgCand==null)
	{
		if (document.selection)
			gnKeyCount = 0;
		else if (txtInput.selectionStart)
			gStartPos = txtInput.selectionStart+1;
		else
			gStartPos = txtInput.value.length+1;
		window.status = "Processing: " + srcText + ". No hits. ";
	}
	else
	{
		var msg = "Candidates: " + srcText + ' - ';
		for (i=0; i<10 && i< rgCand.length; i++)
		{
			keyVal = rgCand[i].split(':');
			uniVal = keyVal[0].split('x')[1];
			msg += '(' + keyVal[1] + ':' + String.fromCharCode(parseInt(uniVal, 16)) + ') ';
		}
		if (rgCand.length>10)
			msg += ' ...';
		window.status = msg;
	}

	gfBlockNext = fMatched;
	return !fMatched;
}

function wime_key_safari(event)
{
	var e = getEvent(event);
	var txtInput =  getTarget(e);
	if (txtInput.value.length==1)
	{
		// Re-process first char because the first char can't be processed
		// during keypress (doing so would produce weird selected text).
		gStartPos=0;
		return wime_key(event);
	}
	return true;
}

function wime_placeicon(txtInput)
{
	if (gImeLang=='')
		width = 8;
	else
		width = 20;

	var par = txtInput;
	var left = 0;
	var top = 0;
	while (par)
	{
		left += par.offsetLeft;
		top += par.offsetTop;
		par = par.offsetParent;
	}

	// MacIE dosn't take the body margin into account when returning offsetLeft/offsetTop
	if (navigator.appName=="Microsoft Internet Explorer" && navigator.platform=="MacPPC" && navigator.appVersion.indexOf("MSIE 6")<0)
	{
		if (document.body.style.marginLeft)
			left += parseInt(document.body.style.marginLeft)-1;
		else
			left += 9; // MacIE does not defined marginLeft if it is not set, eventhough a default value of 10 is used.
		if (document.body.style.marginTop)
			top += parseInt(document.body.style.marginTop)-1;
		else
			top += 14; // Ditto (default marginTop is 15).
	}

	gimeIcon.style.left = (left + txtInput.offsetWidth) + "px";
	gimeIcon.style.top  = top + "px";
	gimeIcon.style.width = width + "px";
	gimeIcon.style.height = txtInput.offsetHeight-2 + "px";

	if (gImeLang!='')
		window.status = 'Keyboard Language: '+gImeLang+'.';
	else
		window.status = '';
}

function wime_show(event)
{
	var e = getEvent(event);
	var txtInput =  getTarget(e);
	if (gimeIcon!=null && txtInput!=null)
	{
		gimeIcon.style.visibility='visible';
		wime_placeicon(txtInput);
		gCurField = txtInput;
	}
}

var gRemove = null;
function wime_hide_delayed()
{
	if (gRemove==gCurField)
	{
		gimeIcon.style.visibility='hidden'; 
		gCurField = null;
	}
}

function wime_hide(event)
{
	var e = getEvent(event);
	var txtInput =  getTarget(e);
	gRemove = txtInput;
	gHide = setTimeout("wime_hide_delayed();",200);

	return false;
}

function wime_load()
{
	var i;
	for (i=0; i < grgMethods.length; i++)
	{
		var imeDef = grgMethods[i];
		window.status = "Downloading IME definition for " + imeDef.split(':')[1];

		// self modifying code?
		var body = document.getElementsByTagName("body")[0];
		var szUrl = "/glyphgate/swime.fd?method=" + imeDef.split(':')[0] + "\&id=" + i;
		var js = gg_CreateFrame(szUrl, 1, 1, "0", "gg_SWIMEData", "gg_SWIMEData", 0);
		if (js)
		{
			js.style.visibility = "hidden";
		}
	}
}

function wime_switch(event)
{
	var e = getEvent(event);

	gCurIME++;
	if (gCurIME>=grgMethods.length)
	{
		gCurIME = -1;
		gimeIcon.innerHTML = '';
		gimeIcon.title = '';
	}
	else
	{
		gimeIcon.innerHTML = grgMethods[gCurIME].split(':')[0];
		gimeIcon.title = grgMethods[gCurIME].split(':')[1];

		if (grgIME[grgMethods[gCurIME].split(':')[0]]==null)
		{
			wime_load();
		}
	}

	gImeLang = gimeIcon.title;
	wime_placeicon(gCurField);
	gCurField.focus();
	clearTimeout(gHide);
}

function wime_block(e)
{
	var fBlock = gfBlockNext;
	gfBlockNext = false;
	return !fBlock;
}

function wime_install()
{
	var url = "/glyphgate/swime_info.html";

	if (navigator.appName=="Netscape" &&
		(navigator.userAgent.indexOf("Netscape/7.0")>=0 ||
		 parseInt(navigator.appVersion)==4))
	{
		// Unsupported browser. Don't install SWIME, only show an info page.
		url = "/glyphgate/swime_info_old.html";
	}
	else
	{
		var input = document.getElementsByTagName("input");
		for (var i=0; i < input.length; i++)
		{
			var obj = input.item(i);
			if (obj.tagName=="INPUT" && obj.type=='text')
			{	
				obj.onkeydown = wime_key;
				obj.onkeypress = wime_block;
				if (navigator.appVersion.indexOf("Safari")>=0)
				{
					gfSafari = true;
					obj.onkeyup = wime_key_safari;
				}
				obj.onfocus = wime_show;
				obj.onblur = wime_hide;
			}		
		}

		var area = document.getElementsByTagName("textarea");
		for (var i=0; i < area.length; i++)
		{
			var obj = area.item(i);
			obj.onkeyup = wime_key;
			obj.onfocus = wime_show;
			obj.onblur = wime_hide;
		}

		var txt = document.createTextNode(" ");
		gimeIcon = document.createElement("div");
		gimeIcon.appendChild(txt);
		gimeIcon.setAttribute("id", "imeIcon");
		gimeIcon.style.position = "absolute";
		gimeIcon.style.visibility = "hidden";
		gimeIcon.onclick = wime_switch;
		gimeIcon.title = 'Click here to install keyboard support.';

		var body = document.getElementsByTagName("body")[0];
		if (body!=null)
		{
			body.appendChild(gimeIcon);
		}
	}

	// Show the information page
	if (window.gg_GetCookie && gg_GetCookie("gg_no_swime_info")!=1)
	{
		window.setTimeout("gg_ShowSwimeHelp('"+url+"')", 4000);
	}
}

function gg_ShowSwimeHelp(url)
{
	window.status = "Loaded SWIME v1.1.0";
	var gg_swimeWindow = gg_CreateFrame(url, 
		400, 55, "1px solid black", "gg_swime", "gg_swimeFrame", 1);
}


