/*
 AIM (ALee's Input Method or A Input Method) for Hangul

  Author: A Lee <alee@debian.org>
  Homepage: http://aim.anj.kr/
  Last Update: 2007/09/15

 Copyright 2006 (C) A Lee <alee@debian.org>. All rights reserved.

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License as
  published by the Free Software Foundation; either version 2 of
  the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  GNU General Public License for more details.

  The license can be found at http://www.gnu.org/licenses/gpl.txt.
 */

var aimQ = Array(0,0,0,0,0,0);
var aimStatus = document.createElement('div');
aimStatus.innerHTML = 'En';
aimStatus.style.fontFamily = 'GulimChe,monospace';
aimStatus.style.color = 'white';
aimStatus.style.backgroundColor = 'blue';
aimStatus.style.fontSize = aimStatus.style.lineHeight = '10pt';
aimStatus.style.right = aimStatus.style.bottom = 0;
aimStatus.style.position = document.all?'absolute':'fixed';

function aimDJamo(a,c,d) {
	var i, a=Array( // Double Jamos
		Array(Array(1,7,18,21,24),1,7,18,21,24), // Cho
		Array(Array(39,44,49),Array(31,32,51),Array(35,36,51),51), // Jung
		Array(Array(1,4,9,18,21),Array(1,21),Array(24,30),Array(1,17,18,21,28,29,30),Array(0,21),21))[a]; // Jong
	for (i=a[0].length; c!=a[0][i-1]; i--) if (!i) return i;
	for (a=a[i], i=a.length||1; 1; i--) if (!i || d==a || d==a[i-1]) return i;
}

function aimInsert(f,m,c) { // Insert
	if (!c && aimQ=='0,0,0,0,0,0') return true;
	if (c.length!=6) aimQ=Array(0,0,0,0,0,0);
	else {
		var m=m||'0,0,0,0,0,0', i=c[0]+c[1], j=c[2]+c[3], k=c[4]+c[5];
		c=i&&j?0xac00+(i-(i<3?1:i<5?2:i<10?4:i<20?11:12))*588+(j-31)*28+k-(k<8?0:k<19?1:k<25?2:3):0x3130+(i||j||k);
	}
	if (document.selection) { // IE
		var s=document.selection.createRange(), t=s.text;
		if (t && document.selection.clear) document.selection.clear();
		s.text=(m=='0,0,0,0,0,0'||c&&t.length>1?'':t)+String.fromCharCode(c);
		if (!c || !m || s.moveStart('character',-1)) s.select();
	}
	else if (f.selectionEnd+1) { // Gecko
		if (m!='0,0,0,0,0,0' && f.selectionEnd-f.selectionStart==1) f.selectionStart=f.selectionEnd;
		var e=document.createEvent('KeyEvents');
		e.initKeyEvent('keypress',0,0,null,0,0,0,0,0,c);
		if (c && f.dispatchEvent(e) && m) f.selectionStart--;
	}
}

function aimHangul2(f,c) { // 2-Bulsik
	if (c<65 || (c-1)%32>25) aimInsert(f,0,c);
	else if ((c=Array(17,48,26,23,7,9,30,39,33,35,31,51,49,44,32,36,18,1,4,21,37,29,24,28,43,27)[c%32-1]
			+(c==79||c==80?2:c==69||c==81||c==82||c==84||c==87?1:0))<31) { // Jaum
		if ((!aimQ[5] || !(aimQ[0]=-1)) && aimQ[2]) aimQ[5]=aimDJamo(2,aimQ[4],c);
		if (!aimQ[2] || aimQ[0]<0 || aimQ[0] && (!aimQ[4] || !aimQ[5]) && (aimQ[4] || c==8 || c==19 || c==25))
			aimInsert(f,(aimQ=aimQ[1]||aimQ[2]||!aimDJamo(0,aimQ[0],c)?aimQ:0),aimQ=Array(c,aimQ?0:1,0,0,0,0));
		else if (!aimQ[0] && (aimQ[0]=c) || (aimQ[4]=aimQ[4]||c)) aimInsert(f,0,aimQ);
		if (aimQ[5]) aimQ[5]=c;
	}
	else { // Moum
		if ((!aimQ[3] || aimQ[4] || !(aimQ[2]=-1)) && !aimQ[4]) aimQ[3]=aimDJamo(1,aimQ[2],c);
		if ((aimQ[0] && aimQ[2]>0 && aimQ[4]) && (aimQ[5] || !(aimQ[5]=aimQ[4]) || !(aimQ[4]=0))) {
			aimInsert(f,0,Array(aimQ[0],aimQ[1],aimQ[2],aimQ[3],aimQ[4],0));
			aimInsert(f,aimQ,aimQ=Array(aimQ[5],0,c,0,0,0));
		}
		else if ((!aimQ[0] || aimQ[2]) && (!aimQ[3] || aimQ[4]) || aimQ[2]<0) aimInsert(f,aimQ,aimQ=Array(0,0,c,0,0,0));
		else if (aimQ[2]=aimQ[2]||c) aimInsert(f,0,aimQ);
	}
}

function aimHangul3(f,c) { // 3-Bulsik
	c=Array(2,183,24,15,14,8220,120,39,126,8221,43,44,41,46,74,119,30,22,18,78,83,68,73,85,79,52,110,44,62,46,33,10,
		/*A~*/7,63,27,12,5,11,69,48,55,49,50,51,34,45,56,57,29,16,6,13,54,3,28,20,53,26,40,58,60,61,59,42,23,79,
		/*a~*/71,86,72,66,84,96,109,115,93,116,122,113,118,121,21,67,4,70,99,74,9,1,101,17,37,92,47,8251)[c-33];
	if (c>92 && c<123) { // Cho
		aimInsert(f,(aimQ=aimQ[1]||aimQ[2]||!aimDJamo(0,aimQ[0],c-92)?aimQ:0),aimQ=Array(c-92,aimQ?0:1,0,0,0,0));
	}
	else if (c>65 && c<87) { // Jung
		if (!aimQ[3] || !(aimQ[2]=-1)) aimQ[3]=aimDJamo(1,aimQ[2],c-35);
		if ((!aimQ[0] || aimQ[2]) && (!aimQ[3] || aimQ[4]) || aimQ[2]<0) aimInsert(f,aimQ,aimQ=Array(0,0,c-35,0,0,0));
		else if (aimQ[2]=aimQ[2]||c-35) aimInsert(f,0,aimQ);
	}
	else if (c<31) { // Jong
		if (!aimQ[5] || !(aimQ[4]=-1)) aimQ[5]=aimDJamo(2,aimQ[4],c);
		if (!aimQ[0] || !aimQ[2] || aimQ[4] && !aimQ[5] || aimQ[4]<0) aimInsert(f,aimQ,aimQ=Array(0,0,0,0,c,0));
		else if (aimQ[4]=aimQ[4]||c) aimInsert(f,0,aimQ);
	}
	else aimInsert(f,0,c);
}

function aimKeypress(e) {
	var e=e||window.event, f=e.target||e.srcElement, n=f.nodeName||f.tagName, c=e.which||e.which==0?e.which:e.keyCode;
	if (document.body==aimStatus.parentNode) aimStatus.parentNode.removeChild(aimStatus);
	if (f.type=='text' && n=='INPUT' || n=='TEXTAREA') {
		if ((c==10 || c==13 || c==32) && aimInsert(f,0,0) && (e.ctrlKey || e.shiftKey)) { // Toggle
			aimStatus.innerHTML=aimStatus.innerHTML!='En'?'En':e.ctrlKey?'H2':'H3';
			document.body.appendChild(aimStatus);
			return false;
		}
		if (aimStatus.innerHTML!='En' && c>32 && c<127 && !e.altKey && !e.ctrlKey) {
			if (c>64 && c<91 && !e.shiftKey) c+=32;
			if (c>96 && c<123 && e.shiftKey) c-=32;
			if (aimStatus.innerHTML=='H2') aimHangul2(f,c);
			if (aimStatus.innerHTML=='H3') aimHangul3(f,c);
			return false;
		}
	}
}

function aimKeydown(e) {
	var e=e||window.event, f=e.target||e.srcElement, n=f.nodeName||f.tagName;
	if (f.type=='text' && n=='INPUT' || n=='TEXTAREA') {
		if (e.keyCode==8 && (aimQ[1] || aimQ[3] || aimQ[0] && aimQ[2])) { // Backspace
			for (var i=5; !aimQ[i];) i--;
			aimInsert(f,aimQ[i]=0,aimQ);
			return false;
		}
		if (e.keyCode!=16 && e.keyCode<47) aimInsert(f,0,0);
		if (e.keyCode==27) f.blur(); // Esc
	}
}

document.onkeypress = aimKeypress;
document.onkeydown = aimKeydown;