// 입력창을 10ms마다 체크하면서 값이 변했으면 request를 보낸다.
// 파이어폭스에서는 한글을 입력할때 keydown 이벤트가 발생하지 않기 때문에
// 값이 변하는지 계속 보고있어야 한다.
function eolinTagFunction_WatchInputBox(id)
{
	try
	{
		var instance = document.getElementById(id).instance;
		var input = instance.getInput();
		if (input.value.charAt(input.value.length - 1) == ',') {
		    instance.setValue(input.value.substring(0, input.value.length - 1));
		    return;
		}

		// 값이 달라졌는지 체크
		if(input.value != instance.typingText)
		{
			instance.typingText = input.value;
			//instance.requestSuggestion();
		}
	}
	catch(e) { }
}

function Tag(container, language, disable)
{
	this.isSettingValue = false;	// setValue가 짧은 시간에 여러번 실행될때 Safari가 죽어버리는 문제 해결

	this.instance = this;	// requestSuggestion() 함수에서 참조한다
	this.cursor = 0;		// 비동기로 전송되는 스크립트의 짝을 맞추기 위한 커서

	this.isTyping = false;			// input box에 포커스가 있는지 여부
	

	this.typingText = "";			// eolinTagFunction_WatchInputBox에서 input box의 값을 감시하기 위한 변수

	this.inputClassName = "";

	this.language = "ko";
	if(typeof language != "undefined")
		this.language = language;

	this.container = container;		// tag list가 들어갈 container
	this.container.instance = this;
	
	// 10ms마다 input box의 값이 변했는지 체크
	setInterval("eolinTagFunction_WatchInputBox('" + this.container.id + "')", 10);

	// 마지막 노드에 들어가는 input box
	this.inputOnLast = this.createSuggestInput();
	this.inputTemporary = null;

	// tag list
	this.tagList = document.createElement("ul");
	this.tagList.instance = this;

	// tag list first child
	var listItem = document.createElement("li");
	listItem.className = "lastChild";
	listItem.appendChild(this.inputOnLast);

	this.tagList.appendChild(listItem);

	this.container.appendChild(this.tagList);
}

// 마지막노드의 input box를 편집중인지 중간의 list item을 눌러 편집중인지를 리턴
Tag.prototype.isTemporaryEditing = function()
{
	return (this.inputTemporary != null);
}

Tag.prototype.setInputClassName = function(str)
{
	this.inputClassName = str;
	this.inputOnLast.className = str;
	if(this.inputTemporary) this.inputTemporary.className = str;
}

// 현재 편집중인 input box
Tag.prototype.getInput = function()
{
	return (this.inputTemporary == null) ? this.inputOnLast : this.inputTemporary;
}

// cross browser event
Tag.prototype.adjustEventCompatibility = function(event)
{
	if(navigator.appName == "Microsoft Internet Explorer")
	{
		event = window.event;
		event.target = event.srcElement;
	}

	return event;
}

// input box를 생성한다
Tag.prototype.createSuggestInput = function()
{
	var input = document.createElement("input");
	input.instance = this;
	input.className = this.inputClassName;
	input.setAttribute("autocomplete", "off");
	input.onblur = function() {
		var instance = this.instance;

		instance.isTyping = false;		
		instance.setValue(this.value);
	}
	input.onkeypress = function(event) {
		if (!event) event = window.event;
		if (event.keyCode == 13) {
			event.returnValue = false; 
			event.cancelBubble = true;
			try { 
				event.preventDefault(); 
			} catch(e) { }
			return false;
		}
		if ((event.keyCode > 32 && event.keyCode < 48) || (event.keyCode > 57 && event.keyCode < 65) 
			|| (event.keyCode > 90 && event.keyCode < 97) || (event.keyCode > 122 && event.keyCode < 127) ){ 
			event.returnValue = false;
		}
		return true;
	}	
	input.onkeydown = function(event) {
		var instance = this.instance;

		instance.isTyping = true;

		event = instance.adjustEventCompatibility(event);
		
		switch(event.keyCode)
		{
			
			case 8:		// BackSpace
				if(this.value == "")
					instance.moveBack();
				else
					return event.keyCode;
				break;
			case 13:	// Enter
				instance.setValue(this.value.trim());
				break;
			case 188 :	// comma
				if(!event.shiftKey)
					instance.setValue(this.value.trim());
				else
					return event.keyCode;
				break;
			case 9 :    // tab
			    if (this.value.trim() == "") return event.keyCode;
				instance.setValue(this.value.trim());
				break;			
			
			default:
				return event.keyCode;
		}
		
		
		event.returnValue = false;
		event.cancelBubble = true;

		try { event.preventDefault(); } catch(e) { }

		return false;
	}

	return input;
}

// tag list의 이전 항목으로 이동
Tag.prototype.moveBack = function()
{
	
	var prevNode = this.getInput().parentNode.previousSibling;
	if(this.tagList.childNodes.length > 1 && prevNode)
	{			

		var text = prevNode.innerHTML;
		//var text = prevNode.innerHTML.unhtmlspecialchars();

		prevNode.parentNode.removeChild(prevNode);
		this.tagList.lastChild.className = "lastChild";
		this.getInput().value = text;
	}
}


// 노드의 값을 배열로 반환한다
Tag.prototype.getValues = function()
{
	var values = new Array();

	for(var i=0; i<this.tagList.childNodes.length-1; i++)		
		values[i] = this.tagList.childNodes[i].innerHTML.trim();
	
	return values;
}

// 마지막 노드의 input box에 값을 추가하거나 임시 input box의 값을 tag list에 세팅한다
Tag.prototype.setValue = function(str)
{
	if(this.isSettingValue)
		return;
	else
		this.isSettingValue = true;	

	if(this.isTemporaryEditing())
	{
		this.inputTemporary.parentNode.onclick = this.tagListMouseClick;

		if(str.trim() == "")
			this.inputTemporary.parentNode.parentNode.removeChild(this.inputTemporary.parentNode);
		else
			this.inputTemporary.parentNode.innerHTML = str;

		this.typingText = "";
		this.inputTemporary = null;
	}
	else if(str.trim() != "")
	{
		var inputContainer = this.tagList.lastChild;
		inputContainer.className = "";

		var listItem = document.createElement("li");
		listItem.onclick = this.tagListMouseClick;
		listItem.appendChild(document.createTextNode(str));

		this.tagList.removeChild(inputContainer);
		this.tagList.appendChild(listItem);
		this.tagList.appendChild(inputContainer);

		this.typingText = "";
		this.inputOnLast.value = "";
		this.focusOnInput();
	}

	this.tagList.lastChild.className = "lastChild";

	this.isSettingValue = false;
}

// tag list를 마우스로 클릭하면 input box로 변신시키기 위한 이벤트 핸들러
Tag.prototype.tagListMouseClick = function()
{
	var instance = this.parentNode.instance;

	instance.inputTemporary = instance.createSuggestInput();
	instance.inputTemporary.value = this.innerHTML;	
	instance.typingText = this.innerHTML;

	this.innerHTML = "";
	this.onclick = null;
	this.appendChild(instance.inputTemporary);

	instance.focusOnInput();	
}



// 적절한 input box로 포커스를 이동시킨다
Tag.prototype.focusOnInput = function()
{
	this.getInput().focus();
	this.getInput().select();
}

// 이하 잡 유틸들

function getOffsetTop(obj)
{ return obj ? obj.offsetTop + getOffsetTop(obj.offsetParent) : 0; }

function getOffsetLeft(obj)
{ return obj ? obj.offsetLeft + getOffsetLeft(obj.offsetParent) : 0; }

var StringBuffer = function()
{ this.buffer = new Array(); }

StringBuffer.prototype.append=function(str)
{ this.buffer[this.buffer.length] = str; }

StringBuffer.prototype.toString = function()
{ return this.buffer.join(""); }

if(!String.prototype.trim) {
	String.prototype.trim = function()
	{ return this.replace(new RegExp("(^\\s*)|(\\s*$)", "g"), ""); }
}

var x=0;
function debug(s){try{document.getElementById("debug").innerHTML=++x+")"+s+"<br />"+document.getElementById("debug").innerHTML}catch(e){}}