	//전역변수
	var oldValTag = "", caretPosTag="", tagwordTag="";
	var	timerTag=false; // setTimeOut함수를 호출해야 할지 하지 않아야 할지를 결정하는 변수이다. 타임아웃함수의 호출은 후보태그레이어가 보여지는 상태에서만 호출되야 한다.
	var curCandiSelTag = null; // 후보태그중 현재 선택되어 있는 태그(div 엘리먼트이다)
	var keydownCaretPosTag = new CaretPosition(); // 후보태그 레이어가 보여지는 시점의 캐럿의 위치를 저장하고 있는 변수이다.
	var isLockTag=false; // 후보태그 레이어를 재구성할 것인지, 하지 말아야 할것인지를 결정하는 변수


	function viewTagCandidateTag(tag)
	{
		if(tag.length == 0)
		{
			hiddenTagCandidateLayer();
			return;
		}
		var tagLen = tag.indexOf("#");
		if(tagLen > -1){
			alert("태그검색에서는 '#' 를 사용하지 않고 검색을 합니다.");
			if(tagLen == 0)
				$('tagSch').value = "";
			else
				$('tagSch').value = tag.substring(0, tagLen) + tag.substring(tagLen+1);
			return;
		}

		var requestUrl = g_contextPath + '/servlet/CandidateTag?tagword=' + encodeURIComponent(tag) + '&count=10';
		new Ajax.Request(requestUrl, {
			'method': 'get',
			onCreate: function(transport) {
				//centerPosition($('wait'));
				//$('wait').show();
			},
			onSuccess: function(transport) {
				if (200 == transport.status) {
					//$('wait').hide();
					resultTagProcess(transport.responseXML);
				}
			},
			onFailure: function(transport) {
				//$('wait').hide();
				alert('오류가 발생했습니다. 상태코드는 다음과 같습니다.' + transport.status);
			}
		});
	}

	function resultTagProcess(xmlObj)
	{
		var list_container = $('tagCandidateLayer');
		removeAllChildren(list_container);
		
		var dataItems = xmlObj.getElementsByTagName("candidate");
		var i;

		if(dataItems.length > 0)
		{
			for (i = 0; i < dataItems.length; i++) {
				var dataItem = nodeToJSON(dataItems[i]);
		
				var candiateDiv = new Element('div').update("#" + dataItem.tag + " (" + dataItem.cnt + ")");
				Event.observe(candiateDiv, 'mouseover', tagCandidateMouseOver.bindAsEventListener(candiateDiv, candiateDiv));
				Event.observe(candiateDiv, 'mouseout', tagCandidateMouseOut.bindAsEventListener(candiateDiv, candiateDiv));
				Event.observe(candiateDiv, 'click', tagCandidateMouseClick.bindAsEventListener(candiateDiv, candiateDiv));
		
		
				list_container.appendChild(candiateDiv);
			}
		}
		else
		{
			$('tagCandidateLayer').innerHTML = '<div>태그를 찾을 수 없습니다.</div>';
		}

		showTagCandidateLayer('default');
	}

	function tagCandidateMouseOver(obj, obj2)
	{
		if(curCandiSelTag != null)
			curCandiSelTag.style.backgroundColor = "#ffffff";
			
		obj2.style.backgroundColor = "#f7fdf5";
		curCandiSelTag = obj2;

		
	}

	function replaceTagCandidateTag()
	{
		// 선택된 것으로 태그내용을 바꾸는.
		var tagString = curCandiSelTag.innerHTML;
		tagString = tagString.substring(0, tagString.indexOf(" "));

		if(tagString.length < 1 || tagString.charAt(0) != '#')
			return;

		tagString = tagString.substring(1);
		// 팝업이 호출되었던 시점의 캐럿위치에 존재하는 태그워드의 전체 선택영역을 얻는다. 
		// #민|주  상태라면 '#민'이라는 단어로 팝업이 구성되어 나타나게 되고, '#민주'를 선택하는 선택영역을 구하게 된다.
		
		// keydownCaretPosTag에 팝업이 호출되었던 시점의 캐럿위치가 저장되어 있다.
		// keydownCaretPosTag에서 1씩 값을 감소시켜가면서 '#'을 만날때까지 진행한다.
		
		
		// 선택 시작위치를 찾는다.
		var currentMessage = $('tagSch').value;
		var startPos = 0;
		var endPos = currentMessage.length;
	

		// 선택영역을 현재 선택되어 있는 태그로 치환하고, 캐럿을 원위치 시킨다.
		// 태그 부분을 선택한다.
		setCaretPosition($('tagSch'), startPos, endPos - startPos);

		// 선택된 태그부분을 replaceStr을 이용하여 교체한다.
		insertText($('tagSch'), tagString, false);	

		// 캐럿을 원위치 시킨다.
		//setCaretPosition($('tagSch'), keydownCaretPosTag.start, 0);
		
	}
	
	function tagCandidateMouseOut(obj, obj2)
	{
		obj2.style.backgroundColor = "#ffffff";
	}
	
	function tagCandidateMouseClick(obj, obj2)
	{
		//alert(obj2.innerHTML);
		replaceTagCandidateTag();
		insertText($('tagSch'), " ", false);
		
		hiddenTagCandidateLayer();
	}

	function hiddenTagCandidateLayer()
	{
		$('tagCandidateLayer').style.display = 'none';
		curCandiSelTag = null; // 후보리스트에서 현재 선택된 것을 null로 만든다.
		timerTag = false; // 무한 타이머의 작동을 중지시킨다.
		isLockTag = false;
	}

	function showTagCandidateLayer()
	{
		$('tagCandidateLayer').style.display = '';
		keydownCaretPosTag = getCaretPosition($('tagSch'));
		//$('trace3').innerHTML = keydownCaretPosTag.start;
		timerTag = true; // 무한 타이머의 작동을 시작한다.
	}

	function messageBoxKeyDownTag(e)
	{
		var keyCode = e.keyCode ? e.keyCode : e.which ? e.which : e.charCode;

		if((keyCode == 38 || keyCode == 40) && timerTag) //40 : 아래화살표, 38 : 윗화살표
		{
			isLockTag = true;
		}
		else
		{
			isLockTag = false;
		}
	}

	function messageBoxKeyPressTag(e)
	{
		var keyCode = e.keyCode ? e.keyCode : e.which ? e.which : e.charCode;

		if(keyCode == 13)
		{
			fnSearch();
		}
		else
		{
			if(e.preventDefault)
			{//비IE
				window.setTimeout("getCaretTextTag($('tagSch'))", 50);
			}
		}
	}

	var tagTimeObj = "";
	function getCaretTextTag(oField, e)
	{
		if(e != null)
		{
			var keyCode = e.keyCode ? e.keyCode : e.which ? e.which : e.charCode;

			if(keyCode == 40 && timerTag) //40 : 아래화살표, 38 : 윗화살표
			{
				isLockTag = true;
				setCaretPosition(oField, keydownCaretPosTag.start, 0);
				if(curCandiSelTag == null)
				{
					tagCandidateMouseOver($('tagCandidateLayer').firstChild,$('tagCandidateLayer').firstChild);
				}
				else
				{
					if(curCandiSelTag.nextSibling == null)
					{
						tagCandidateMouseOut(curCandiSelTag,curCandiSelTag);
						tagCandidateMouseOver($('tagCandidateLayer').firstChild,$('tagCandidateLayer').firstChild);
					}
					else
					{
						tagCandidateMouseOut(curCandiSelTag,curCandiSelTag);
						tagCandidateMouseOver(curCandiSelTag.nextSibling,curCandiSelTag.nextSibling);
					}
				}
				replaceTagCandidateTag();
				return;
			}
			else if(keyCode == 38 && timerTag)
			{
				isLockTag=true;
				setCaretPosition(oField, keydownCaretPosTag.start, 0);
				if(curCandiSelTag == null)
				{
					tagCandidateMouseOver($('tagCandidateLayer').lastChild,$('tagCandidateLayer').lastChild);
				}
				else
				{
					if(curCandiSelTag.previousSibling == null)
					{
						tagCandidateMouseOut(curCandiSelTag,curCandiSelTag);
						tagCandidateMouseOver($('tagCandidateLayer').lastChild,$('tagCandidateLayer').lastChild);
					}
					else
					{
						tagCandidateMouseOut(curCandiSelTag,curCandiSelTag);
						tagCandidateMouseOver(curCandiSelTag.previousSibling,curCandiSelTag.previousSibling);
					}
				}
				replaceTagCandidateTag();
				return;
			}
			else
			{
				isLockTag=false;
			}
		}

		if(!isLockTag)
		{

			//debugger;
			// ajax로 서버에 전달할 태그워드를 얻는 역할.
			var oCaretPos = getCaretPosition(oField);
			
			if (caretPosTag != oCaretPos.start || oldValTag != oField.value)
			{
				
				tagwordTag = oField.value;
		
				oldValTag = oField.value; 
				caretPosTag = oCaretPos.start;
	
				timerTag = true;
				viewTagCandidateTag(tagwordTag);
			}
			else {
				// nothing
			}

		}

		if(timerTag)
		{
			//var cur = new Date(); 
			//$('checkmessage').innerHTML = cur.toString();
			tagTimeObj = window.setTimeout("getCaretTextTag($('tagSch'))", 1);
		}
	}
	
	
	document.observe("dom:loaded", function() {
		$('tagCandidateLayer').clonePosition($('tagSch'), {'setHeight': false, 'offsetLeft': 0, 'offsetTop': 20});
	});
