/*
 *  H.I.M JavaScript Vietnamese Input Method Source File
 *
 *	GNU Copyright (C) 2004  Hieu Dang Tran <hieu@bluebottle.com>
 *	Website: http://hieu.acunett.com
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License, version 2,
 *  dated June 1991.
 *
 *  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.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

var agt=navigator.userAgent.toLowerCase()
var is_ie = ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1))
var obj_copy, method=0, on_off=1, changed=false, ver="", SFJRX, S, F, J, R, X, DAWEO_func, DAWEO, Z, wSpell=false, FRX
var fID='htmlbox', D, AEO, moc, trang, uni, uni2, saveNode, saveRange, saveE, saveStr, notInAlphabet=false, saveA=false
var oCharCode=new Array(417,416,7899,7898,7901,7900,7907,7906,7903,7902,7905,7904)
var uCharCode=new Array(117,85,250,218,249,217,7909,7908,7911,7910,361,360)
var uCharRep=new Array(432,431,7913,7912,7915,7914,7921,7920,7917,7916,7919,7918)
var alphabet='QWERTYUIOPASDFGHJKLZXCVBNM', no="1234567890", saveKey=false, sk
var english=String.fromCharCode(272)+String.fromCharCode(194)+String.fromCharCode(258)+String.fromCharCode(416)
	english+=String.fromCharCode(431)+String.fromCharCode(202)+String.fromCharCode(212)
var typicalKeyCode = new Array(
	97, 226, 259, 101, 234, 105, 111, 244, 417, 117, 432, 121,
	65, 194, 258, 69, 202, 73, 79, 212, 416, 85, 431, 89);
function notWord(word) { return ("\ \r\n#,\\;.:-_()<>+-*/=?!\"$%{}[]\'~|^\@\&\t".indexOf(word)>=0) }
function start(obj, key) {
	obj_copy=obj
	if (!method) { uni=uni_telex; uni2=uni_vni_viqr }
	else if (method==1) { uni=uni_telex; uni2=false }
	else if ((method==2) || (method==3)) { uni=uni_vni_viqr; uni2=false }
	
	if (!is_ie) {
		if (obj.value.length<=0) return
		if (!obj.data) {
			if (!obj.setSelectionRange) return
			var pos=obj.selectionStart
		}
		else var pos=obj.pos
		uni(obj, String.fromCharCode(key.which), pos)
		if (uni2) uni2(obj, String.fromCharCode(key.which), pos)
	}
	else {
		var word
		obj=ie_getText(obj)
		if (obj) {
			if ((no.indexOf(key)>=0) && uni2) saveKey=key
			else word=uni(obj.curword.text, key, null)
			if (uni2 && (!word || saveKey)) {
				word=uni2(obj.curword.text, key, null)
				saveKey=false
			}
			if (word) {
				if (word[1]) {
					if (window.event!=null) var ta=window.event.srcElement
					else if ((typeof(fID)!='undefined') && (typeof(frame)!='undefined') && doc) var ta=frame
					if (word[1]==true) { obj.curword.text=word[0]; start(ta,key) }
					else {
						if (spellerr(word[0],key)) return
						obj.curword.text=word[0]
						if (notInAlphabet) saveA=notInAlphabet
						start(ta,word[1])
						if (saveA) {
							obj.curword.text+=saveA
							notInAlphabet=false; saveA=false
						}
					}
				} else {
					if (word[2]) {
						var saveWord=obj.curword.text
						obj.curword.text=word[0]
						if (window.event!=null) var ta=window.event.srcElement
					  	else if ((typeof(fID)!='undefined') && (typeof(frame)!='undefined') && doc) var ta=frame
						start(ta,key)
						if (!changed) { obj.curword.text+=key; changed=true }
						obj=ie_getText(obj)
						if (spellerr(obj.curword.text,key)) {
							wSpell=true; changed=false
							obj.curword.text=saveWord
							return start(ta,key)
						}
						start(ta,word[2])
					} else obj.curword.text=word
				}
			}
		}
	}
}

function ie_getText(obj) {
	var caret=obj.document.selection.createRange(), word=""
	while(1) {
		caret.moveStart("character",-1)
		if (word.length == caret.text.length) break
		word=caret.text
		if (notWord(word.charAt(0))) {
			if (word.charCodeAt(0)==13) word=word.substr(2)
			else word=word.substr(1)
			break
		}
	}
	if (word.length) {
		caret.collapse(false)
		caret.moveStart("character",-word.length)
		obj.curword=caret.duplicate()
		return obj
	} else return false
}

function searchAndDestroy(key,word,by,searchFor,i) {
	var g,h,poschar,replace,pos
	if (is_ie) pos=findCharToChange(word,key,null,searchFor)
	else pos=findCharToChange(word,key,i,searchFor)
	if (pos) {
		if (pos[2]) {
			if (is_ie) return new Array(pos[2],0,pos[1])
			else {
				replaceChar(word,i-pos[0],pos[1],0)
				iframeFinish(saveRange,saveNode,saveE,pos[3])
				iframefix(pos[2])
			}
		} else if (pos[1]) {
			if (is_ie) return ie_replaceChar(word, pos[0], pos[1],0)
			else return replaceChar(word,i-pos[0],pos[1],0)
		} else {
			replace=searchFor
			var charCode
			if (is_ie) poschar=word.substr(word.length-pos,1)
			else poschar=word.value.substr(i-pos,1)
			for (g=0; g<replace.length; g++) {
				if (isNaN(replace[g])) var cmp=poschar
				else var cmp=poschar.charCodeAt(0)
				if (cmp==replace[g]) {
					if (!isNaN(by[g])) charCode=by[g]
					else charCode=by[g].charCodeAt(0)
					if (is_ie) return ie_replaceChar(word, pos, charCode,0)
					else return replaceChar(word,i-pos,charCode,0)
				}
			}
		}
	}
	return false
}

function ie_replaceChar(word, pos, charCode, nochange) {
	for (var i=0; i<oCharCode.length; i++) {
		if (charCode==oCharCode[i]) {
			for (var h=0; h<uCharCode.length; h++) {
				if ((word.substr(word.length-pos-1,1).charCodeAt(0)==uCharCode[h]) && (pos!=1)) {
					var r=String.fromCharCode(uCharRep[h])+String.fromCharCode(charCode)
					break; break;
				}
			}
		}
	}
	if (!isNaN(charCode)) {
		if (!nochange) changed=true
		if (!r) r=String.fromCharCode(charCode)
		return word.substr(0,word.length-pos-r.length+1)+r+word.substr(word.length-pos+1)
	} else return word.substr(0,word.length-pos)+charCode+word.substr(word.length-pos+1)
}

function uni_vni_viqr(obj, key, i) {
	DAWEO_func=DAWEO_vni_viqr
	if ((method==2) || (method==0)) {
		DAWEO="6789"; SFJRX="12534"; S="1"; F="2"; J="5"; R="3"; X="4"; Z="0"; D="9"; AEO="6"; moc="7"; trang="8"; FRX="234"
	} else if (method==3) {
		DAWEO="^+(D"; SFJRX="'`.?~"; S="'"; F="`"; J="."; R="?"; X="~"; Z="-"; D="D"; AEO="^"; moc="+"; trang="("; FRX="`?~"
	}
	
	var upkey=key.toUpperCase()
	if (SFJRX.indexOf(upkey)>=0) {
		if (!is_ie) typicalReplace(obj, key, i)
		else {
			var return_word=typicalReplace(obj, key, null)
			if (return_word) return return_word
		}
	} else if (upkey==D) {
		var searchFor=new Array('d','D')
		var by=new Array(273,272)
	} else if (upkey==AEO) {
		var searchFor=new Array('a','A',259,258,'e','E','o','O',417,416,225,193,224,192,7841,7840,7843,7842,227,195,
								233,201,232,200,7865,7864,7867,7866,7869,7868,
								243,211,242,210,7885,7884,7887,7886,245,213)
		var by=new Array(226,194,226,194,234,202,244,212,244,212,7845,7844,7847,7846,7853,7852,7849,7848,7851,7850,
						7871,7870,7873,7872,7879,7878,7875,7874,7877,7876,
						7889,7888,7891,7890,7897,7896,7893,7892,7895,7894)
	} else if (upkey==moc) {
		var searchFor=new Array('o','O',244,212,'u','U',243,211,242,210,7885,7884,7887,7886,245,213,
								250,218,249,217,7909,7908,7911,7910,361,360)
		var by=new Array(417,416,417,416,432,431,7899,7898,7901,7900,7907,7906,7903,7902,7905,7904,
						7913,7912,7915,7914,7921,7920,7917,7916,7919,7918)
	} else if (upkey==trang) {
		var searchFor=new Array('a','A',226,194,225,193,224,192,7841,7840,7843,7842,227,195)
		var by=new Array(259,258,259,258,7855,7854,7857,7856,7863,7862,7859,7858,7861,7860)
	} else if (upkey==Z) {
		var searchFor=delSign('searchFor')
		var by=delSign('by')
	} else return normC(obj,key,i)
	return finish_uni(key,obj,by,searchFor,i)
}

function uni_telex(obj, key, i) {
	DAWEO="DAWEO"; DAWEO_func=DAWEO_telex; SFJRX="SFJRX"; S="S"; F="F"; J="J"; R="R"; X="X"; Z="Z"; FRX="FRX"
	AEO="A"; moc="O"; trang="W"
	var upkey=key.toUpperCase()
	if (SFJRX.indexOf(upkey)>=0) {
		if (!is_ie) typicalReplace(obj, key, i)
		else {
			var return_word=typicalReplace(obj, key, null)
			if (return_word) return return_word
		}
	} else if (upkey=='D') {
		var searchFor=new Array('d','D')
		var by=new Array(273,272)
	} else if (upkey=='A') {
		var searchFor=new Array('a','A',259,258,225,193,224,192,7841,7840,7843,7842,227,195)
		var by=new Array(226,194,226,194,7845,7844,7847,7846,7853,7852,7849,7848,7851,7850)
	} else if (upkey=='W') {
		var searchFor=new Array('a','A',226,194,'o','O',244,212,'u','U',225,193,224,192,7841,7840,7843,7842,227,195,
					243,211,242,210,7885,7884,7887,7886,245,213,
					250,218,249,217,7909,7908,7911,7910,361,360)
		var by=new Array(259,258,259,258,417,416,417,416,432,431,7855,7854,7857,7856,7863,7862,7859,7858,7861,7860,
				7899,7898,7901,7900,7907,7906,7903,7902,7905,7904,
				7913,7912,7915,7914,7921,7920,7917,7916,7919,7918)
	} else if (upkey=='E') {
		var searchFor=new Array('e','E',233,201,232,200,7865,7864,7867,7866,7869,7868)
		var by=new Array(234,202,7871,7870,7873,7872,7879,7878,7875,7874,7877,7876)
	} else if (upkey=='O') {
		var searchFor=new Array('o','O',417,416,243,211,242,210,7885,7884,7887,7886,245,213)
		var by=new Array(244,212,244,212,7889,7888,7891,7890,7897,7896,7893,7892,7895,7894)
	} else if (upkey==Z) {
		var searchFor=delSign('searchFor')
		var by=delSign('by')
	} else return normC(obj,key,i)
	if ((DAWEO.indexOf(upkey)>=0) || (Z.indexOf(upkey>=0))) return finish_uni(key,obj,by,searchFor,i)
}

function normC(obj,key,i) {
	var g=1, word="", upkey=key.toUpperCase()
	if (!is_ie) {
		while(1) {
			if (i-g<0) break
			if (notWord(obj.value.substr(i-g,1))) break
			else word=obj.value.substr(i-g,1)+word
			g++
		}
	} else word=obj
	var uni_array=repSign(null)
	for (g=1; g<=word.length; g++) {
		for (var h=0; h<uni_array.length; h++) {
			if (uni_array[h]==word.charCodeAt(word.length-g)) {
				var fixSign, searchFor=new Array()
				if (h<=23) fixSign=S
				else if (h<=47) fixSign=F
				else if (h<=71) fixSign=J
				else if (h<=95) fixSign=R
				else fixSign=X
				var keyCode=typicalKeyCode[h%24]
				word=word.substr(0,word.length-g)+String.fromCharCode(keyCode)+word.substr(word.length-g+1)
				if ((alphabet.indexOf(upkey)>=0) || (!is_ie)) word+=key
				else notInAlphabet=key
				if (!is_ie) {
					for (var j=0; j<typicalKeyCode.length; j++) searchFor[searchFor.length]=String.fromCharCode(typicalKeyCode[j])
					var pos=findCharToChange(word,fixSign,word.length,searchFor)
					if (!pos) return
					var charCode=returnUniCode(null,fixSign,word.charAt(word.length-pos),null)
					replaceChar(obj,i-g,keyCode,true)
					return replaceChar(obj,i-pos+1,charCode,true)
				} else return new Array(word,fixSign)
			}
		}
	}
}

function finish_uni(key,obj,by,searchFor,i) {
	var upkey=key.toUpperCase()
	if (!is_ie) {
		if ((DAWEO.indexOf(upkey)>=0) || (Z.indexOf(upkey)>=0)) searchAndDestroy(key,obj,by,searchFor,i)
	} else if ((DAWEO.indexOf(upkey)>=0) || (Z.indexOf(upkey)>=0)) {
		var result=searchAndDestroy(key,obj,by,searchFor,null)
		if (result) return result
	}
	return false
}

function delSign(which) {
	if (which=='searchFor') {
		var searchFor=repSign(null)
		for (var h=0; h<english.length; h++) {
			searchFor[searchFor.length]=english.toLowerCase().charCodeAt(h)
			searchFor[searchFor.length]=english.charCodeAt(h)
		}
		return searchFor
	} else if (which=='by') {
		var by=new Array()
		for (var h=0; h<5; h++) { for (var g=0; g<24; g++) by[by.length]=typicalKeyCode[g] }
		var temparr=new Array('d','D','a','A','a','A','o','O','u','U','e','E','o','O')
		for (h=0; h<temparr.length; h++) by[by.length]=temparr[h]
		return by
	}
}

function DAWEO_act(g,curChar,upkey,nsA,nsO,nsW,nsARep,nsORep,nsWRep) {
	var cc, h, upC=curChar.toUpperCase(), a1=new Array(AEO,moc,trang)
	var a2=new Array(nsA,nsO,nsW,nsARep,nsORep,nsWRep)
	for (cc=0; cc<3; cc++) {
		for (h=0; h<a2[cc%3].length; h++) {
			if (a2[cc%3][h]==upC.charCodeAt(0)) {
				if (curChar!=upC) return new Array(g,String.fromCharCode(a2[cc%3+3][h]).toLowerCase().charCodeAt(0))
				else return new Array(g,a2[cc%3][h])
			}
		}
	}
	return false
}

function DAWEO_vni_viqr(word, key, str) {
	var newSign6=new Array(7854,7898,7856,7900,7862,7906,7858,7902,7860,7904)
	var newSign6Rep=new Array(7844,7888,7846,7890,7852,7896,7848,7892,7850,7894)
	var newSign7=new Array(7888,7890,7896,7892,7894)
	var newSign7Rep=new Array(7898,7900,7906,7902,7904)
	var newSign8=new Array(7844,7846,7852,7848,7850)
	var newSign8Rep=new Array(7854,7856,7862,7858,7860)
	var curChar, upkey=key.toUpperCase()
	for (var g=1; g<=word.length; g++) {
		curChar=word.substr(word.length-g,1)
		if (str.indexOf(curChar)>=0) return g
		else if (english.indexOf(curChar.toUpperCase())>=0) {
			charCode=curChar.charCodeAt(0)
			if (upkey==D) {
				if (charCode==273) return new Array(g, 'd')
				else if (charCode==272) return new Array(g, 'D')
			} else if (upkey==AEO) {
				if (charCode==226) return new Array(g, 'a')
				else if (charCode==194) return new Array(g, 'A')
				else if (charCode==244) return new Array(g, 'o')
				else if (charCode==212) return new Array(g, 'O')
				else if (charCode==234) return new Array(g,' e')
				else if (charCode==202) return new Array(g,' E')
			} else if (upkey==moc) {
				if (charCode==417) return new Array(g, 'o')
				else if (charCode==416) return new Array(g, 'O')
				else if (charCode==432) return new Array(g, 'u')
				else if (charCode==431) return new Array(g, 'U')
			} else if (upkey==trang) {
				if (charCode==259) return new Array(g, 'a')
				else if (charCode==258) return new Array(g, 'A')
			}
		} else {
			var result=DAWEO_act(g,curChar,upkey,newSign6,newSign7,newSign8,newSign6Rep,newSign7Rep,newSign8Rep)
			if (result) return result
		}
	}
}

function DAWEO_telex(word, key, str) {
	var newSignA=new Array(7854,7856,7862,7858,7860)
	var newSignARep=new Array(7844,7846,7852,7848,7850)
	var newSignO=new Array(7898,7900,7906,7902,7904)
	var newSignORep=new Array(7888,7890,7896,7892,7894)
	var newSignW=new Array(7844,7846,7852,7848,7850,7888,7890,7896,7892,7894)
	var newSignWRep=new Array(7854,7856,7862,7858,7860,7898,7900,7906,7902,7904)
	var curChar, upkey=key.toUpperCase()
	for (var g=1; g<=word.length; g++) {
		curChar=word.substr(word.length-g,1)
		if (str.indexOf(curChar)>=0) return g
		else if (english.indexOf(curChar.toUpperCase())>=0) {
			charCode=curChar.charCodeAt(0)
			if (upkey=='D') {
				if (charCode==273) return new Array(g, 'd')
				else if (charCode==272) return new Array(g, 'D')
			}
			else if (upkey=='A') {
				if (charCode==226) return new Array(g, 'a')
				else if (charCode==194) return new Array(g, 'A')
			}
			else if (upkey=='W') {
				if (charCode==259) return new Array(g, 'a')
				else if (charCode==258) return new Array(g, 'A')
				else if (charCode==417) return new Array(g, 'o')
				else if (charCode==416) return new Array(g, 'O')
				else if (charCode==432) return new Array(g, 'u')
				else if (charCode==431) return new Array(g, 'U')
			}
			else if (upkey=='E') {
				if (charCode==234) return new Array(g, 'e')
				else if (charCode==202) return new Array(g, 'E')
			}
			else if (upkey=='O') {
				if (charCode==244) return new Array(g, 'o')
				else if (charCode==212) return new Array(g, 'O')
			}
		}
		else {
			var result=DAWEO_act(g,curChar,upkey,newSignA,newSignO,newSignW,newSignARep,newSignORep,newSignWRep)
			if (result) return result
		}
	} 
}

function spellerr(word,key) {
	var upword=word.toUpperCase()
	var notViet=new Array('DD','AA','EE','OO','CI','OU','UG','IG','REC','YY','YI','IY','EY','CE','EA','EI','II','UU')
	var vSConsonant=new Array('B','C','D','G','H','K','L','M','N','P','Q','R','T','V')
	var vDConsonant=new Array('CH','GI','KH','NGH','GH','NG','NH','PH','QU','TH','TR')
	var vSConsonantE=new Array('C','M','N','P','T')
	var vDConsonantE=new Array('CH','NG','NH')
	var sConsonant=new Array('C','P','T','CH')
	var tmpword=upword, update=false
	sk=sk.toUpperCase()
	if ((key.toUpperCase()==sk) && (FRX.indexOf(sk)>=0)) {
		for (var g=0; g<sConsonant.length; g++) {
			if (upword.substr(upword.length-sConsonant[g].length,sConsonant[g].length)==sConsonant[g]) return true
		}
	}
	for (g=0; g<word.length; g++) {
		if ("FJZW1234567890".indexOf(upword.substr(g,1))>=0) return true
		for (var h=0; h<notViet.length; h++) { if (upword.substr(g,notViet[h].length)==notViet[h]) return true }
	}
	for (g=1; g<word.length; g++) { if ("SX".indexOf(upword.substr(g,1))>=0) return true }
	for (h=0; h<vDConsonant.length; h++) {
		if (tmpword.substr(0,vDConsonant[h].length)==vDConsonant[h]) {
			tmpword=tmpword.substr(vDConsonant[h].length)
			update=true; break
		}
	}
	if (!update) {
		for (h=0; h<vSConsonant.length; h++) {
			if (tmpword.substr(0,1)==vSConsonant[h]) { tmpword=tmpword.substr(1); break }
		}
	}
	update=false
	for (h=0; h<vDConsonantE.length; h++) {
		if (tmpword.substr(tmpword.length-vDConsonantE[h].length)==vDConsonantE[h]) {
			tmpword=tmpword.substr(0,tmpword.length-vDConsonantE[h].length)
			update=true; break
		}
	}
	if (!update) {
		for (h=0; h<vSConsonantE.length; h++) {
			if (tmpword.substr(tmpword.length-1)==vSConsonantE[h]) { tmpword=tmpword.substr(0,tmpword.length-1); break }
		}
	}
	
	if (tmpword) {
		for (g=0; g<vDConsonant.length; g++) {
			for (h=0; h<tmpword.length; h++) { if (tmpword.substr(h,vDConsonant[g].length)==vDConsonant[g]) return true }
		}
		for (g=0; g<vSConsonant.length; g++) { if (tmpword.indexOf(vSConsonant[g])>=0) return true }
	}
	return false
}

function findCharToChange(obj, key, i, searchFor) {
	var g, h, str="", charCode
	for (g=0; g<searchFor.length; g++) {
		if (isNaN(searchFor[g])) str+=searchFor[g]
		else str+=String.fromCharCode(searchFor[g])
	}
	var val=(!is_ie)?obj.value:obj, i=(!is_ie)?i:obj.length, upkey=key.toUpperCase(), typicalE=""
	var word="", count=0, vowArr=new Array(), typicalECode=returnKeyCode(upkey), charCode
	if (obj.value) {
		g=1
		while(1) {
			if (i-g<0) break
			if (notWord(val.substr(i-g,1))) break
			else word=val.substr(i-g,1)+word; g++
		}
	} else word=obj
	if (DAWEO.indexOf(upkey)>=0) var result=DAWEO_func(word,key,str)
	if ((upkey!=Z) && (DAWEO.indexOf(upkey)<0)) for (g=0; g<typicalECode.length; g++) typicalE+=String.fromCharCode(typicalECode[g])
	var special=String.fromCharCode(194)+String.fromCharCode(258)+String.fromCharCode(202)+String.fromCharCode(212)
	special+=String.fromCharCode(416)+String.fromCharCode(431)
	var uni_array=repSign(key)
	if (SFJRX.indexOf(upkey)>=0) var thisKeyCode=returnKeyCode(upkey)
	for (g=1; g<=word.length; g++) {
		if ((DAWEO.indexOf(upkey)<0) || (str.length==0)) {
			if (str.indexOf(word.substr(word.length-g, 1))>=0) {
				if (word.substr(word.length-g, 1).toUpperCase() == 'U') {
					if (word.substr(word.length-g-1, 1).toUpperCase() != 'Q') {
						count++; vowArr[vowArr.length]=g
					}
				} else if (word.substr(word.length-g, 1).toUpperCase() == 'I') {
					if ((word.substr(word.length-g-1, 1).toUpperCase() != 'G') || (count<=0)) {
						count++; vowArr[vowArr.length]=g
					}
				} else { count++; vowArr[vowArr.length]=g }
			} else if (Z.indexOf(upkey)<0) {
				for (h=0; h<uni_array.length; h++) {
					if (uni_array[h]==word.charCodeAt(word.length-g)) {
						var keyCode=typicalKeyCode[h%24]
						word=word.substr(0,word.length-g)+String.fromCharCode(keyCode)+word.substr(word.length-g+1)
						if (!is_ie) {
							if (!obj.data) var savePos=obj.selectionStart
							obj.value=obj.value.substr(0,i-word.length)+word+obj.value.substr(i)
							if (!obj.data) {
								obj.setSelectionRange(savePos,savePos)
								uni(obj,key,i)
								if (uni2) uni2(obj,key,i)
							} else return g
							return
						} else return new Array(0,0,word)
					}
				}
				for (h=0; h<thisKeyCode.length; h++) {
					if (thisKeyCode[h]==word.charCodeAt(word.length-g)) return new Array(g, String.fromCharCode(typicalKeyCode[h]))
				}
			}
		} else if (Z.indexOf(upkey)<0) {
			for (h=0; h<uni_array.length; h++) {
				if (uni_array[h]==word.charCodeAt(word.length-g)) {
					var fixSign
					if (h<=23) fixSign=S
					else if (h<=47) fixSign=F
					else if (h<=71) fixSign=J
					else if (h<=95) fixSign=R
					else fixSign=X
					var keyCode=typicalKeyCode[h%24]
					word=word.substr(0,word.length-g)+String.fromCharCode(keyCode)+word.substr(word.length-g+1)
					if (!is_ie) {
						if (!obj.data) var savePos=obj.selectionStart
						obj.value=obj.value.substr(0,i-word.length)+word+obj.value.substr(i)
						if (!obj.data) obj.setSelectionRange(savePos,savePos)
						uni(obj,key,i)
						if (uni2) uni2(obj,key,i)
						var tmpwrd=obj.value.substr(i-word.length,word.length)
						if (!changed) tmpwrd+=key
						if (spellerr(tmpwrd,key)) {
							word=word.substr(0,word.length-g)+String.fromCharCode(uni_array[h])+word.substr(word.length-g+1)
							obj.value=obj.value.substr(0,i-word.length)+word+obj.value.substr(i)
							if (!obj.data) obj.setSelectionRange(savePos,savePos)
							return
						}
						if ((!changed) && (!obj.data)) {
							obj.value=obj.value.substr(0,obj.selectionStart)+key+obj.value.substr(obj.selectionStart)
							obj.setSelectionRange(savePos+1,savePos+1)
							i+=1; changed=true
						}
						var saveChanged=changed
						if (!obj.data) {
							uni(obj,fixSign,i)
							if (uni2) uni2(obj,fixSign,i)
							changed=saveChanged
						} else return new Array(g,String.fromCharCode(keyCode),fixSign,key)
						return
					} else var returnFix=fixSign
				}
			}
		}
	}
	if ((DAWEO.indexOf(upkey)>=0) && (!result) && (!returnFix)) return false
	if ((!wSpell) && (returnFix)) return new Array(0,returnFix,word)
	else wSpell=false
	if (DAWEO.indexOf(upkey)<0) {
		for (g=1; g<=word.length; g++) {
			if (special.indexOf(word.substr(word.length-g, 1).toUpperCase())>=0) return g
			else if (typicalE.indexOf(word.substr(word.length-g, 1))>=0) {
				for (h=0; h<typicalECode.length; h++) {
					if (word.substr(word.length-g, 1).charCodeAt(0)==typicalECode[h]) return new Array(g, String.fromCharCode(typicalKeyCode[h]))
				}
			}
		}
	}
	if ((result) && (result.length>1)) return result
	if (spellerr(word,key)) return false
	if (result) return result
	if (count==1) return vowArr[0]
	else if (count==2) {
		var cc=0, fdconsonant
		var sconsonant='BCD'+String.fromCharCode(272)+'GHKLMNPQRSTVX'
		var dconsonant=new Array('CH','GI','KH','NGH','GH','NG','NH','PH','QU','TH','TR')
		
		for (h=1; h<=word.length; h++) {
			fdconsonant=false
			for (var a=0; a<dconsonant.length; a++) {
				if (dconsonant[a].indexOf(word.substr(word.length-h-dconsonant[a].length+1, dconsonant[a].length).toUpperCase())>=0) {
					cc++
					fdconsonant=true
					if (dconsonant[a] != 'NGH') h++
					else h+=2
				}
			}
			if (!fdconsonant) {
				if (sconsonant.indexOf(word.substr(word.length-h, 1).toUpperCase())>=0) cc++
				else break
			}
		}
		
		if ((cc==1) || (cc==2)) return vowArr[0]
		else return vowArr[1]
	}
	else if (count==3) return vowArr[1]
	else if (count>3) return vowArr[0]
	else return false
}

function repSign(key) {
	var temp=new Array()
	var uni_array=new Array()
	for (g=0; g<SFJRX.length; g++) {
		if ((key==null) || (SFJRX.substr(g,1) != key.toUpperCase())) {
			temp=returnKeyCode(SFJRX.substr(g,1).toUpperCase())
			for (var h=0; h<temp.length; h++) uni_array[uni_array.length]=temp[h]
		}
	}
	return uni_array
}

function typicalReplace(obj, key, i) {
	var searchFor=new Array()
	for (var g=0; g<typicalKeyCode.length; g++) searchFor[searchFor.length]=String.fromCharCode(typicalKeyCode[g])
	pos=findCharToChange(obj, key, i, searchFor)
	if (pos) {
		if (pos[2]) return new Array(pos[2],true)
		else if (pos[1]) {
			if (!is_ie) replaceChar(obj, i-pos[0], pos[1],0)
			else return ie_replaceChar(obj, pos[0], pos[1],0)
		} else {
			var charCode=returnUniCode(obj, key, i, pos)
			if (!is_ie) replaceChar(obj,i-pos,charCode,0)
			else return ie_replaceChar(obj, pos, charCode,0)
		}
	}
	return false
}

function returnUniCode(obj, key, i, pos) {
	var uni_array=returnKeyCode(key.toUpperCase())
	if (isNaN(i)) var charCode=i.charCodeAt(0)
	else var charCode=(!is_ie)?(obj.value.charCodeAt(i-pos)):(obj.charCodeAt(obj.length-pos))
	for (var g=0; g<typicalKeyCode.length; g++) if (typicalKeyCode[g]==charCode) {
		if (g<12) {
			var lCase=g
			var uCase=g+12
		} else {
			var lCase=g-12
			var uCase=g
		}
		if (String.fromCharCode(charCode)!=String.fromCharCode(charCode).toUpperCase()) return uni_array[lCase]
		return uni_array[uCase]
	}
}

function returnKeyCode(key) {
	if (key==S) return new Array(225, 7845, 7855, 233, 7871, 237, 243, 7889, 7899, 250, 7913, 253,
									193, 7844, 7854, 201, 7870, 205, 211, 7888, 7898, 218, 7912, 221);
	else if (key==F) return new Array(224, 7847, 7857, 232, 7873, 236, 242, 7891, 7901, 249, 7915, 7923,
										192, 7846, 7856, 200, 7872, 204, 210, 7890, 7900, 217, 7914, 7922);
	else if (key==J) return new Array(7841, 7853, 7863, 7865, 7879, 7883, 7885, 7897, 7907, 7909, 7921, 7925,
										7840, 7852, 7862, 7864, 7878, 7882, 7884, 7896, 7906, 7908, 7920, 7924);
	else if (key==R) return new Array(7843, 7849, 7859, 7867, 7875, 7881, 7887, 7893, 7903, 7911, 7917, 7927,
										7842, 7848, 7858, 7866, 7874, 7880, 7886, 7892, 7902, 7910, 7916, 7926);
	else if (key==X) return new Array(227, 7851, 7861, 7869, 7877, 297, 245, 7895, 7905, 361, 7919, 7929,
										195, 7850, 7860, 7868, 7876, 296, 213, 7894, 7904, 360, 7918, 7928);
}

function replaceChar(obj, pos, charCode, nochange) {
	if (!isNaN(charCode)) {
		var replaceBy=String.fromCharCode(charCode)
		if (!nochange) changed=true
	} else var replaceBy=charCode

	if (!obj.data) {
		var savePos=obj.selectionStart
		for (var i=0; i<oCharCode.length; i++) {
			if (charCode==oCharCode[i]) {
				for (var h=0; h<uCharCode.length; h++) {
					if ((obj.value.substr(pos-1,1).charCodeAt(0)==uCharCode[h]) && (pos<savePos-1)) {
						var r=String.fromCharCode(uCharRep[h])
						break; break
					}
				}
			}
		}
		if (((charCode==417) || (charCode==416)) && (obj.value.substr(pos-1,1).toUpperCase()=='U') && (pos<savePos-1)) {
			if (obj.value.substr(pos-1,1)=='u') var r=String.fromCharCode(432)
			else var r=String.fromCharCode(431)
		}
		obj.setSelectionRange(pos,pos+1)
		obj.value = obj.value.substr(0,obj.selectionStart) + replaceBy + obj.value.substr(obj.selectionEnd)
		if (r) {
			obj.setSelectionRange(pos-1,pos)
			obj.value = obj.value.substr(0,obj.selectionStart) + r + obj.value.substr(obj.selectionEnd)
		}
		obj.setSelectionRange(savePos,savePos)
		scrollIntoView(obj)
	}
	else {
		for (var i=0; i<oCharCode.length; i++) {
			if (charCode==oCharCode[i]) {
				for (var h=0; h<uCharCode.length; h++) {
					if ((obj.data.substr(pos-1,1).charCodeAt(0)==uCharCode[h]) && (pos<obj.pos-1)) {
						var r=String.fromCharCode(uCharRep[h])
						break; break
					}
				}
			}
		}
		obj.deleteData(pos,1); obj.insertData(pos,replaceBy)
		if (r) { obj.deleteData(pos-1,1); obj.insertData(pos-1,r) }
	}
}

function scrollIntoView(obj) {
	var factor=36
	if ((obj_copy.scrollHeight<=obj.scrollTop) || (obj_copy.scrollHeight>=obj.scrollTop+obj.offsetHeight))
		obj.scrollTop=obj_copy.scrollHeight-obj_copy.offsetHeight+factor
}

function statusMessage() {
	var str='Mode: '
	if(!on_off) str+='NONE'
	else if(method==1) str+='TELEX'
	else if(method==2) str+='VNI'
	else if(method==3) str+='VIQR'
	else if(method==0) str+='AUTO'
	str+=" [F9=AUTO->TELEX->VNI->VIQR; F12=On/Off]"
	window.status=str
}

document.onkeydown = function(e) { onKeyDown(e) }
function onKeyDown(e) {
	if (e=='iframe') var key=document.frames[fID].event.keyCode
	else var key=(!is_ie)?e.which:window.event.keyCode
	if (key==120) {
		on_off=true
		if (method==3) method=0
		else method++
	} else if (key==123) on_off=!on_off
	if ((is_ie) || (ver>=1.3)) statusMessage()
}
document.onkeypress = function(e) {
	if ((!is_ie) && (ver<1.3)) return
	var el=(!is_ie)?e.target:window.event.srcElement
	var code=(!is_ie)?e.which:window.event.keyCode
	var test=(el.type != 'textarea') && (el.type != 'text') && (el.id != 'htmlbox')
	if (test || checkCode(code)) return
	if (!is_ie) doKeyPress(el, e)
	else doKeyPress(el, code)
	if (changed) { changed=false; return false }
}
function checkCode(code) {
	if ((!on_off || (code<45) || (code==145) || (code==255)) && (code!=39) && (code!=40) && (code!=43)) return true
}

function iframeinit() {
	var sel=iwindow.getSelection(), range=null
	iwindow.focus()
	range=sel?sel.getRangeAt(0):document.createRange()
	return range
}

function iframefix(e) {
	saveStr=""
	if (typeof(e)=='string') var code=e.charCodeAt(0)
	else { var code=e.which; sk=String.fromCharCode(code) }
	if (checkCode(code)) return
	var range=iframeinit()
	var node=range.endContainer
	if (!range.startOffset) return
	if (typeof(node.data)=='undefined') return
	if (node.data) {
		saveStr=node.data.substr(range.endOffset)
		node.deleteData(range.startOffset,node.data.length)
	}
	range.setEnd(node,range.endOffset)
	range.setStart(node,0)
	if (!node.data) return
	node.value=node.data; node.pos=node.data.length; node.which=code
	saveNode=node; saveRange=range; saveE=e
	if (typeof(e)=='string') {
		start(node,node)
		iframeFinish(range,node,e,null)
	} else {
		start(node,e)
		iframeFinish(range,node,e,false)
	}
}

function iframeFinish(range,node,evt,key) {
	var x=0
	if (key) { changed=true; saveStr=key+saveStr; x++ }
	if (key!=null) {
		node.insertData(node.data.length,saveStr)
		range.setEnd(node,node.data.length-saveStr.length+x)
		range.setStart(node,node.data.length-saveStr.length+x)
	}
	if (changed) { changed=false; if (key!=null) evt.preventDefault() }
}

function FKeyPress(obj) {
	sk=String.fromCharCode(obj.event.keyCode)
	if (checkCode(obj.event.keyCode)) return
	if (is_ie) start(obj, String.fromCharCode(obj.event.keyCode))
}
function doKeyPress(el, e) {
	if (is_ie) {
		sk=String.fromCharCode(e)
		start(el, sk)
	} else {
		sk=String.fromCharCode(e.which)
		start(el, e)
	}
}

function startup() {
	if (!is_ie) {
		for (var i=0; i<agt.length; i++) if (agt.substr(i,3)=='rv:') break
		i+=3
		if (i<agt.length) {
			for (var g=i; g<agt.length; g++) {
				if ((isNaN(agt.substr(g,1))) && (agt.substr(g,1) != '.')) break
				ver+=agt.substr(g,1)
			}
			for (g=0; g<ver.length; g++) if (ver.substr(g,1) == '.') ver=ver.substr(0,g+2)
		}
	}
}

startup()
if ((is_ie) || (ver>=1.3)) statusMessage()

if (typeof(fID)!='undefined') {
	if (is_ie) {
		var frame=document.frames[fID]
		if ((typeof(frame)!='undefined') && (document.frames[fID].document)) {
			var doc=document.frames[fID].document
			doc.designMode="On"
			doc.onkeydown=function() { onKeyDown('iframe') }
			doc.onkeypress=function() {
				FKeyPress(frame)
				if (changed) { changed=false; return false }
			}
		}
	} else {
		if (document.getElementById(fID)) {
			var iwindow=document.getElementById(fID).contentWindow
			var iframedit=iwindow.document
			iframedit.designMode="On"
			iframedit.addEventListener("keypress", iframefix, true)
			iframedit.addEventListener("keydown", onKeyDown, true)
		}
	}
}