
function jjAutoComplete() {
	
	var obj  = '';      // ÀÎÇ²¹Ú½º ¿ÀºêÁ§Æ®
	var sUrl = '';      // ´ë»ó°æ·Î(¼­¹ö»çÀÌµå ÇÁ·Î±×·¥ °æ·Î+ÆÄÀÏ¸í)
	var method = '';    // Àü¼Û¹æ½Ä [GET, POST]
	var anc = 0;        // ¹è¿­Æ÷ÀÎÅÍ
	var dataIdx = [];   // ¹®ÀÚ¿­ ÀÎµ¦½ºÀúÀå¼Ò
	var data = [];      // ¼­¹ö¿¡¼­ °¡Á®¿Â µ¥ÀÌÅÍ ÀúÀå¼Ò
	var dataFilter = [];// Ãß°¡µÈ¹®ÀÚ¿­·Î ÇÊÅÍ¸µÇÑÈÄ µ¥ÀÌÅÍ ÀúÀå¼Ò
	
	var word = '';           // ÀÎÇ²¹Ú½º¿¡ ÀÔ·ÂµÈ Ç®¿öµå
	var thisWord = '';       // ÇöÀçÃßÀûÁßÀÎ ±ÛÀÚ
	var dataReq = false;     // ¾ÆÀÛ½º ÄÄÆ÷³ÍÆ®
	var skin = '';           // Ãâ·Â½ºÅ²(css¿Í ¿¬µ¿) className = skin
	var pannel = '';         // ·¹ÀÌ¾î ¹è°æ ¿ÀºêÁ§Æ®
	var pannelList = '';     // ·¹ÀÌ¾î ¸®½ºÆ® ¿ÀºêÁ§Æ®
	var pannelListTable = '';// Å×ÀÌºí ¿ÀºêÁ§Æ® (½ÇÁ¦ tbody°¡ µé¾î°¨)
	var pannelPositionInterval = ''; // ¸®»çÀÌÁî½Ã Æ÷Áö¼Å´× Å¸ÀÓ
	
	var tmp1, tmp2; // ÀÓ½Ãº¯¼ö ("ÀÌ¹®¿­ »ï±¹Áö 10" ÀÏ°æ¿ì tmp1="ÀÌ¹®¿­ »ï±¹Áö ", tmp2="10"
	
	this.init = function() {
		/* --------------------------- **
		** ÄÄÆÛ³ÍÆ® ÃÊ±âÈ­ ¼öÇà
		** --------------------------- */
		this.data = [];
		this.dataIdx = [];
		this.anc = 0;
		this.method = 'GET';
		if(!this.skin) this.skin = 'basic';
		this.autoComplete = false;
		
		if(typeof obj == 'string') this.getObj(); // ¹®ÀÚ¿­ÀÌ¸é ¿ÀºêÁ§Æ® Ã£À½
		
		var parentObj = this; // ÇöÀçÅ¬·¡½º ¹é¾÷
		
		// Å°¾×¼Ç µî·Ï
		this.obj.onkeydown = function(){ return parentObj.keyCheck(event, 'dn');}
		this.obj.onkeyup   = function(){ return parentObj.keyCheck(event, 'up');}
		this.obj.onblur    = function(){ parentObj.hide(); }
	}
	this.keyCheck = function(event, arrow) {
		/* --------------------------- **
		** Å°¾×¼Ç È®ÀÎ ¹× µ¿ÀÛ ¹èºÐ
		** --------------------------- */
		switch(event.keyCode) {
			case 16: // Shift
			case 17: // Left Ctrl
			case 18: // Left Alt
			case 21: // Right Alt
			case 25: // Right Ctrl
				if(arrow == 'up') return false;
			case 38: if(arrow == 'dn') this.prev(); return false; // up
			case 40: if(arrow == 'dn') this.next(); return false; // dn
			case 27: if(arrow == 'dn') this.hide(); return false; // esc
			case  9:                                              // tab
				if(arrow != 'dn') return; // µÎ¹øµ¿ÀÛµÇ´Â°É ¹æÁöÇÏ±âÀ§ÇÔ
				if(event.shiftKey === true) this.prev();            // Shift + tab
				else this.next();
				return false;
			default :
				if(this.word !== this.obj.value) { // ±âÁ¸±ÛÀÚ¿Í ÇöÀç±ÛÀÚ°¡ µ¿ÀÏÇÏ¸é µ¿ÀÛ¾ÊÀ½
					this.word = this.obj.value;
					this.getData();
				}
				if(this.obj.value == '') this.hide(); // ÇöÀç ¿ÀºêÁ§Æ®ÀÇ ³»¿ëÀÌ ¾øÀ¸¸é ·¹ÀÌ¾î¼û±è
				return true;
		}
	}
	this.getData = function() {
		/* --------------------------- **
		** ¼­¹ö¿Í Åë½Å
		** --------------------------- */
		var strs = this.word.split(' ');
		this.anc = strs.length -1;
		var str = strs[this.anc].toString();
		
		var c = this.k2e(str).slice(0,2);
		if(c.length < 2) return;
		
		this.thisWord = c;
		if(	(typeof this.data[this.anc] == 'object'||
				typeof this.data[this.anc] == 'array')&&
				this.data.length>0&&
				this.dataIdx[this.anc]==c) {
			this.setData();
			return;
		}
		
		var parentObj = this;
		if(typeof dataReq !== 'object') this.getdataReq();
		
		// Àü¼Û°á°úÈ®ÀÎ µî·Ï
		this.dataReq.onreadystatechange = function() {
			if(parentObj.dataReq.readyState == 4) {
				parentObj.data[parentObj.anc] = [];
				var data = parentObj.dataReq.responseText.split("\n");
				for(var i=0,len=data.length; i<len; i++) {
					var get = data[i].split('|');
					parentObj.data[parentObj.anc][i] = [get[0],get[1],get[2]];
				}
				
				parentObj.dataIdx[parentObj.anc] = parentObj.thisWord;
				parentObj.setData();
				
				// µð¹ö±× ¸ð´ÏÅÍ¸µ
				//var arr = new jjArray();
				//document.testform.testfield2.value=arr.view(parentObj.dataIdx)+"\n";
				//document.testform.testfield2.value+=arr.view(parentObj.data);
			}
		}
		
		// Àü¼Û¹× ¼öÇà
		this.dataReq.open(this.method, this.sUrl+'?str='+str, true);
		this.dataReq.send(null);
	}
	this.setData = function() {
		/* --------------------------- **
		** µ¥ÀÌÅÍ Á¤¸®¹× Ãâ·Â
		** --------------------------- */
		this.filter();
		this.show();
		this.insert();
	}
	this.show = function() {
		/* --------------------------- **
		** ·¹ÀÌ¾î»ý¼º
		** --------------------------- */
		if(typeof this.pannel !== 'object') {
			// create object
			if(document.readyState != 'complete') return; // À¥ÆäÀÌÁö°¡ ¿ÏÀüÈ÷ ¿­¸®Áö ¾ÊÀ¸¸é ½ÇÇàÇÏÁö ¾ÊÀ½
			
			var pannel = document.createElement('DIV');
			pannel.id = 'JDAM';
			pannel.className = this.skin ? this.skin : 'basic';
			this.pannel = pannel;
			
			var pannelClose = document.createElement('DIV');
			pannelClose.className = 'pannelClose';
			pannelClose.innerHTML = "<a href='javascript:;' onclick=\"document.getElementById('JDAM').style.display='hidden';\"></a>";
			
			var pannelList = document.createElement('DIV');
			pannelList.className = 'pannelList';
			pannelList.onmousewheel = function() { parentObj.wheelCtr(); return false; }
			this.pannelList = pannelList;
			
			pannel.appendChild(pannelClose);
			pannel.appendChild(pannelList);
			document.body.appendChild(pannel);
		}
		this.setPannelPosition();
		var parentObj = this;
		this.pannelPositionInterval = setInterval(function() {parentObj.setPannelPosition();}, 500);
		this.pannel.style.display = 'block';
	}
	this.wheelCtr = function() {
		/* --------------------------- **
		** ¸¶¿ì½ºÈÙ ÄÁÆ®·Ñ
		** --------------------------- */
		if( event.wheelDelta ) {
			if( event.wheelDelta > 0 ) this.pannelList.scrollTop -= 20;
			else if( event.wheelDelta < 0 ) this.pannelList.scrollTop += 20;
		}
	}
	this.setPannelPosition = function() {
		/* --------------------------- **
		** ·¹ÀÌ¾î À§Ä¡ Á¶Á¤
		** --------------------------- */
		var pos = this.getRealOffset(this.obj);
		this.pannel.style.left = pos[0]+1 +'px';
		this.pannel.style.top  = pos[1]+1 +'px';
		this.pannel.style.width= pos[2] +'px';
	}
	this.hide = function() {
		/* --------------------------- **
		** ·¹ÀÌ¾î ¼û±è
		** --------------------------- */
		if(typeof this.pannel == 'object') {
			
			var x = event.offsetX;
			var y = event.offsetY;
			var w = this.pannel.offsetWidth;
			var h = this.pannel.offsetHeight;
			
			if(x<1||y<1||x>h||y>w) { //¸¶¿ì½º°¡ ·¹ÀÌ¾îÀ§¿¡ ÀÖÀ¸¸é ¼û±âÁö ¾ÊÀ½
				this.pannel.style.display = 'none';
				clearInterval(this.pannelPositionInterval);
			}
		}
	}
	this.getRealOffset = function(obj, endTag) {
		/* --------------------------- **
		** ÇØ´ç¿ÀºêÁ§Æ®ÀÇ ½ÇÁ¦ À§Ä¡¸¦ Ã£À½
		** --------------------------- */
		if(!endTag) endTag = 'BODY';
		var valueT = 0, valueL = 0;
    
    do {
			valueT += obj.offsetTop  || 0;
			valueL += obj.offsetLeft || 0;
			obj = obj.offsetParent;
		} while (obj && obj.tagName != endTag && obj != null);

		return [valueL, valueT+this.obj.offsetHeight, this.obj.offsetWidth, this.obj.offsetHeight];
	}
	this.insert = function() {
		/* --------------------------- **
		** ÇÊÅÍµÈ µ¥ÀÌÅÍ¸¦ pannelListTable¿¡ ´ãÀ½
		** --------------------------- */
		if(typeof this.pannelList != 'object') return;
		this.pannelList.innerHTML = '';
		this.tab = -1;
		this.tmp1 = '';
		this.tmp2 = '';
		
		if(!this.obj.value) return;
		var str = this.obj.value;
		var strs = str.split(' ');
		for(var i=0,len=strs.length -1; i<len; i++) {
			this.tmp1 += strs[i] + ' ';
		}
		this.tmp2 = strs.pop();
		
		var parentObj = this;
		var table = document.createElement("TABLE");
		var tbody = document.createElement("TBODY");
		table.appendChild(tbody);
		if(typeof this.dataFilter == 'object') {
			for(var i=0, len=this.dataFilter.length; i<len; i++) {
				var tr = document.createElement('TR');
				var td = document.createElement('TD');
				td.onmouseover = function() {this.className='over';}
				td.onmouseout  = function() {this.className='nomal';}
				td.onclick     = function() {parentObj.obj.focus();parentObj.obj.value = parentObj.tmp1+this.innerHTML;}
				td.innerHTML = this.dataFilter[i][1];
				tr.appendChild(td);
				tbody.appendChild(tr);
			}
		}
		this.pannelList.appendChild(table);
		this.pannelListTable = tbody;
	}
	this.filter = function() {
		/* --------------------------- **
		** °Ë»öµÈ µ¥ÀÌÅÍ¸¦ ÀÛÀº´ÜÀ§·Î ÇÊÅÍ¸µ
		** --------------------------- */
		if(typeof this.word !== 'string' || !this.word) return;
		var dataFilter = [];
		var data = this.data[this.anc];
		var strs = this.word.split(' ');
		var str = strs[this.anc];
		var strEng = this.k2e(str).toLowerCase();
		var strEngRev = this.reverse(strEng);

		for(var i=0,len=data.length; i<len; i++) {
			var chk = data[i][0].toLowerCase();
			var tmp1 = chk.substr(0,strEng.length);
			var tmp2 = chk.substr(strEng.length);
			if(tmp1!=strEng&&tmp2!=strEng) {
				chk = this.reverse(chk);
				var tmp1 = chk.substr(0,strEng.length);
				var tmp2 = chk.substr(strEng.length);
				if(tmp1 != strEng&&tmp2!=strEng) continue;
			}
			dataFilter[dataFilter.length] = [data[i][0],data[i][1],data[i][2]];
		}
		this.dataFilter = dataFilter;
		
		// µð¹ö±× ¸ð´ÏÅÍ¸µ
		//var arr2 = new jjArray();
		//document.testform.testfield.value=str;
		//document.testform.testfield.value+=':'+strEng+'\n';
		//document.testform.testfield.value+=arr2.view(dataFilter);
	}
	this.reverse = function(str) {
		/* --------------------------- **
		** ¹®ÀÚ¸¦ °Å²Ù·Î µ¹¸²
		** --------------------------- */
		str = toString(str);
		var rtn = '';
		for(var i=0,len=str.length; i<len; i++) {
			rtn = str.charAt(i) + rtn;
		}
		return rtn;
	}
	this.getdataReq = function() {
		/* --------------------------- **
		** ¾ÆÀÛ½º ÄÄÆÛ³ÍÆ® »ý¼º
		** --------------------------- */
		this.dataReq = false;
		if (window.XMLHttpRequest) { //ÆÄÀÌ¾îÆø½º³ª ¸ÆÀÇ »çÆÄ¸®ÀÇ °æ¿ìÃ³¸®
			this.dataReq = new XMLHttpRequest();
		} else if (window.ActiveXObject) { //IE°è¿­ÀÇ ºê¶ó¿ìÁ®ÀÇ °æ¿ì
			try { this.dataReq = new ActiveXObject("Msxml2.XMLHTTP"); }
			catch (e1) {
				try { this.dataReq = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e2) { }
			}
		}
	}
	this.next = function() {
		/* --------------------------- **
		** ´ÙÀ½Ç×¸ñ
		** --------------------------- */
		this.tab++;
		if(this.tab>=this.dataFilter.length) this.tab = 0;
		this.moveTab();
	}
	this.prev = function() {
		/* --------------------------- **
		** ÀÌÀüÇ×¸ñ
		** --------------------------- */
		this.tab--;
		if(this.tab<0) this.tab = this.dataFilter.length -1;
		this.moveTab();
	}
	this.moveTab = function() {
		/* --------------------------- **
		** ÀÌÀü´ÙÀ½µ¿ÀÛ½Ã Æ÷ÀÎÅÍ ÀÌµ¿
		** --------------------------- */
		var obj = this.pannelListTable;
		if(typeof obj == 'object') {
			for(var i=0,len=obj.childNodes.length; i<len; i++) {
				if(i==this.tab) {
					obj.childNodes[i].childNodes[0].className = 'over';
					this.obj.value = this.tmp1 + this.dataFilter[i][1];
					var pos = this.getRealOffset(obj.childNodes[i], 'DIV');
					this.pannelList.scrollTop = pos[1] - this.pannelList.offsetHeight/3;
				}
				else obj.childNodes[i].childNodes[0].className = 'nomal';
			}
		}
	}
	this.getObj = function() {
		/* --------------------------- **
		** ±âº» ÀÎÇ²¹Ú½º Ã£À½
		** --------------------------- */
		if(!this.obj) this.error('°³Ã¼°¡ Á¤ÀÇµÇÁö ¾Ê¾Ò½À´Ï´Ù.');
		if(typeof this.obj != 'object') this.obj = document.getElementById(this.obj);
		if(this.obj.tagName != 'INPUT') this.error('°³Ã¼¸¦ È°¼ºÈ­ÇÒ ¼ö ¾ø½À´Ï´Ù.');
	}
	this.error = function(msg) {
		/* --------------------------- **
		** ¿¡·¯Ãâ·Â
		** --------------------------- */
		if(!msg) reutrn;
		alert(msg);
	}
	this.k2e = function(str) {
		/* --------------------------- **
		** ÇÑ±Û => ¿µ¹® (ÀÚ¼ÒºÐ¸®ÇÏ¿© ÇØ´çÇÏ´Â Å°ºÎºÐÃ£À½) (ÇÑ±Û => gksrmf)
		** --------------------------- */
		// korean to english
		var korTable = [
			["¤¡", "¤¢", "¤¤", "¤§", "¤¨", "¤©", "¤±", "¤²", "¤³", "¤µ", "¤¶", "¤·", "¤¸", "¤¹", "¤º", "¤»", "¤¼", "¤½", "¤¾"],
			["¤¿", "¤À", "¤Á", "¤Â", "¤Ã", "¤Ä", "¤Å", "¤Æ", "¤Ç", "¤È", "¤É", "¤Ê", "¤Ë", "¤Ì", "¤Í", "¤Î", "¤Ï", "¤Ð", "¤Ñ", "¤Ò", "¤Ó"],
			["",   "¤¡", "¤¢", "¤£", "¤¤", "¤¥", "¤¦", "¤§", "¤©", "¤ª", "¤«", "¤¬", "¤­", "¤®", "¤¯", "¤°", "¤±", "¤²", "¤´", "¤µ", "¤¶", "¤·", "¤¸", "¤º", "¤»", "¤¼", "¤½", "¤¾"]
		];
		var engTable = [
		//["¤¡", "¤¢", "¤¤", "¤§", "¤¨", "¤©", "¤±", "¤²", "¤³", "¤µ", "¤¶", "¤·", "¤¸", "¤¹", "¤º", "¤»", "¤¼", "¤½", "¤¾"],
			["r",  "R",  "s",  "e",  "E",  "f",  "a",  "q",  "Q",  "t",  "T",  "d",  "w",  "W",  "c",  "z",  "x",  "v",  "g"],
		//["¤¿", "¤À", "¤Á", "¤Â", "¤Ã", "¤Ä", "¤Å", "¤Æ", "¤Ç", "¤È", "¤É", "¤Ê", "¤Ë", "¤Ì", "¤Í", "¤Î", "¤Ï", "¤Ð", "¤Ñ", "¤Ò", "¤Ó"],
			["k",  "o",  "i",  "O",  "j",  "p",  "u",  "P",  "h",  "hk", "ho", "hl", "y",  "n",  "nj", "np", "nl", "b",  "m",  "ml", "l"],
		//["",   "¤¡", "¤¢", "¤£", "¤¤", "¤¥", "¤¦", "¤§", "¤©", "¤ª", "¤«", "¤¬", "¤­", "¤®", "¤¯", "¤°", "¤±", "¤²", "¤´", "¤µ", "¤¶", "¤·", "¤¸", "¤º", "¤»", "¤¼", "¤½", "¤¾"]
			["",   "r",  "R",  "rt", "s",  "sw", "sg", "e",  "f",  "fr", "fa", "fq", "ft", "fx", "fv", "fg", "a",  "q",  "qt", "t",  "T",  "d",  "w",  "c",  "z",  "x",  "v",  "g"]
		];
		var rtn = '';
		var uMin = 44032; //°¡
		var uMax = 55203; //ÆR
		for(var i=0,len=str.length; i<len; i++) {
			var s = str.charAt(i);
			var u = escape(s);
			if(u.length<4) {
				rtn += s;
				continue;
			}
			u = parseInt(u.replace(/\%u/,''),16);
			if(u<uMin||u>uMax) {
				u -= 12593;
				if(u>=0&&u<=50) {
					//        ['¤¡','¤¢','¤£','¤¤','¤¥','¤¦','¤§','¤¨','¤©','¤ª','¤«','¤¬','¤­','¤®','¤¯','¤°','¤±','¤²','¤³','¤´','¤µ','¤¶','¤·','¤¸','¤¹','¤º','¤»','¤¼','¤½','¤¾','¤¿','¤À','¤Á','¤Â','¤Ã','¤Ä','¤Å','¤Æ','¤Ç','¤È','¤É','¤Ê','¤Ë','¤Ì','¤Í','¤Î','¤Ï','¤Ð','¤Ñ','¤Ò','¤Ó'];
					var etc = [ 'r', 'R','rt', 's','sw','sg', 'e','E', 'f', 'fr','fa','fq','ft','fx','fv','fg', 'a', 'q', 'Q','qt', 't', 'T', 'd', 'w', 'W', 'c', 'z', 'x', 'v', 'g', 'k', 'o', 'i', 'O', 'j', 'p', 'u', 'P', 'h','hk','ho','hl', 'y', 'n','nj','np','nl', 'b', 'm','ml', 'l'];
					rtn += etc[u];
				} else {
					rtn += s;
				}
				continue;
			}
			u -= uMin;
			var a = b = c = 0;
			
			a = Math.floor(u/588); u %= 588;
			b = Math.floor(u/28);  c = u % 28;
			
			// Debug
			//alert(a+':'+korTable[0][a]+'/'+b+':'+korTable[1][b]+'/'+c+':'+korTable[2][c]);
			// split
			//rtn += (a>=0?korTable[0][a]:'');
			//rtn += (a>=0?korTable[1][b]:'');
			//rtn += (a>=0?korTable[2][c]:'');
			
			// kor to eng
			rtn += (a>=0?engTable[0][a]:'');
			rtn += (a>=0?engTable[1][b]:'');
			rtn += (a>=0?engTable[2][c]:'');
			
		}
		return rtn;
	}
}

function jjArray() {
	// ¿ä°Ç µð¹ö±ë¿ëÀ¸·Î ¸¸µë.. ¹è¿­¶Ç´Â ¿ÀºêÁ§Æ®ÀÇ ³»¿ëÀ» ¸®ÅÏÇÕ´Ï´Ù.
	this.view = function(arr, dep) {
		var rtn = '';
		//if(dep>1) return 'overflow\n';
		
		if(!dep) dep = 0;
		rtn += '[\n';
		for(var key in arr) {
			rtn += this.pad('   ', dep+1);
			rtn += (isFinite(key) ? key : "'"+key+"'")+" => ";
			if(	typeof arr[key] == 'array' || 
					typeof arr[key] == 'object') rtn += this.view(arr[key], dep+1);
			else rtn += (isFinite(arr[key]) ? arr[key]+"\n" : "'"+arr[key]+"'\n");
		}
		rtn += this.pad('   ', dep);
		rtn += ']\n';
		return rtn;
	}
	this.pad = function(str, cnt) { // ÇØ´ç¼ö¸¹Å­ ¹®ÀÚ¸¦ Ã¤¿ò
		var rtn = '';
		while(cnt>0) {
			rtn += str;
			cnt--;
		}
		return rtn;
	}
}

/* ¿¹Á¦
var ac = new jjAutoComplete();
ac.sUrl = '/automata/getData.php'; // ¼­¹ö°æ·Î µî·Ï
ac.skin = 'basic';                 // ½ºÅ²µî·Ï
ac.obj = document.testform.str;    // ¿ÀºêÁ§Æ® µî·Ï
ac.init();                         // ÃÊ±âÈ­
*/