// 2007.06.19
// kevin han
// Noovo Utility class
// charset = UTF-8
//
// 




/////////////////////////////////////////////////////////////////////////////////////////////////////////
// Auto Completion

nus.util.AutoCompletion = nus.lang.Class.extend();

nus.dom.css.declareCSS("\
	.suggestion_list_box {position:absolute; \
		border:solid 1px #808080; \
		background-Color:#f0f0fa; \
		padding :4px 4px 4px 4px; \
		cursor:pointer; \
		overflow-X:visible; overflow-Y:auto; \
		width:100%; \
		font-size:10pt; }\
	.suggestion_item {overflow:visible;white-space:nowrap;} \
 ");


nus.util.AutoCompletion.addPrototypes({

	width:100,
	height:100,

	_active_element: null,
	_listBox: null,
	_suggestList:null,
	_hilite_item:null,

	_tagList: null,
	_editingTagPos:-1,

	_request: null,

	init: function(elm) {
		if (elm) {
			this.attach(elm);
		}
	},

	attach: function(elm) {
		elm.autocomplete = "off";

		//this["onkeydown_event_key"] = nus.event.addListener(elm, "onkeydown", this.onKeyDown, this);
		//this["onkeyup_event_key"] = nus.event.addListener(elm, "onkeyup",  this.onChange, this);
		nus.event.addListener(elm, "onkeydown", this.onKeyDown, this);
		nus.event.addListener(elm, "onkeyup",  this.onChange, this);
	},
	
	detach: function(elm) {
		nus.event.removeAllListener(elm);
	},

	resize: function(w,h) {
		if (this._listBox) {
			if (w != "auto") {
				this._listBox.style.width = w+"px";
			}
			else 
				this._listBox.style.width = w+"px";

			if (h != "auto") {
				this._listBox.style.height = h+"px";
			}
			else 
				this._listBox.style.height = h+"px";
		}

		this.width = w;
		this.height = h;
	},
	onKeyDown: function(ev) {
		ev = ev || window.event;
		this._active_element = ev.srcElement;

		switch(ev.keyCode) {
			/*
			case 9 : 
				if (!this._hilite_item) {
					if (this._suggestList.length > 0) {
						this._tagList[this._editingTagPos] = this._suggestList[0];
					}
				}
			*/
			case 13 : 
				if (!this._hilite_item) {
					this.onCompleteWord();
				}
				else {
					this.onClickSuggestion();
				}
				nus.event.stopEvent(ev);
				return false;

			case 20 : break;
			case 27 : 
				this.showListBox(false);
				break;
			case 38 : 
				this.moveCursor("prev");
				break;

			case 40 : 
				this.moveCursor("next");
				break;

			default:
				break;
		}
	},
	onChange: function(ev) {
		ev = ev || window.event;
		this._active_element = ev.srcElement;

		switch(ev.keyCode) {
			case 13 : // enter
			case 16 : // shift
			case 17 : // ctrl
			case 27 : //esc
			case 35 : // end
			case 36 : // home
			case 37 : 
			case 38 :
			case 39 :
			case 40 :
			case 229 : // 한영전환
				return;

		}
		
		nus.lang.postCommand(this, "query");
	},

	onCommand: function(cmd, param) {
		switch(cmd) {
			case "query" :
				var word = this.getEditingWord();
				if (!word) {
					this.showListBox(false);
					return;
				}
				this.onRefreshSuggestion(word);
				break;
		}
	},

	getEditingWord: function() {
		var text = this._active_element.value;
		var words = text.split(",");

		var editingWord = null;

		if (this._tagList) {
			for(var i=0;i< words.length;i++) {
				if (!this._tagList[i] || this._tagList[i] != words[i]) {
					// 비었거나 달라진 단어가 입력중으로 판정
					editingWord = words[i];
					this._editingTagPos = i;
					break;
				}
			}
		}
		
		if (!editingWord) {
			editingWord = words.getLast();
			this._editingTagPos = words.length-1;
		}

		if (!editingWord || editingWord == "") return null;
		this._tagList = words;

		return editingWord.trim();
	},

	makeListBox: function() {
		this._listBox = document.createElement("DIV");
		
		this._listBox.className = "suggestion_list_box";
		this._listBox.style.display = "none";
		this._listBox.style.overflowX = "hidden";
		if (this.height != "auto") {
			this._listBox.style.height = this.height + "px";
		}
		this._listBox.onmousedown = function(ev) {
			ev = ev || window.event;
			nus.event.stopEvent(ev);		
			return false;
		}

		document.body.appendChild(this._listBox);
	},

	onRefreshSuggestion: function(word) {
		this.showListBox(false);
		this.querySuggest(word);
	},

	onUpdateList: function(list, rate) {
		if (!this._listBox) this.makeListBox();
		
		this._suggestList = list;
		this._hilite_item = null;

		this._listBox.innerHTML = "";
		if (this.height != "auto" && list.length>=5) {
			this._listBox.style.height = 5*12+"px";
		}
		else {
			this._listBox.style.height = "auto";
		}

		this.getEditingWord();
		var tag = this._tagList[this._editingTagPos].trim();
		var html = [];
		

		for(var i=0;i<list.length;i++) {
			var word = list[i];
			var r = new RegExp(tag, "gi").exec(word);
			if (r && r.length > 0) {
				word = word.replace(new RegExp(tag, "gi"), "{0}");
				word = word.format("<b>"+r[0]+"</b>");
			}
			html.push("<div class='suggestion_item' onclick='"+this.ID+".onClickSuggestion(this)' onmouseover='"+this.ID+".onMoveCursor(this)' "+
				"onmousedown='"+this.ID+".onMouseDown(arguments[0] || window.event);' "+"id='"+i+"'>"+word+"</div>");
		}
		if (html.length == 0) {
			this._listBox.style.display = "none";
			this.showListBox(false);
			return;
		}

		this._listBox.innerHTML = html.toHTML();
		this.showListBox(true);
		//this.moveCursor();
	},
	showListBox: function(isShow) {
		if (!this._listBox) return;

		if (isShow) {
			this._inputRect = nus.dom.getObjectRect(this._active_element);
			nus.dom.move(this._listBox, this._inputRect.left, this._inputRect.bottom); 
			this._listBox.style.width= this._inputRect.getWidth() + "px";
		}

		this._listBox.style.display = (isShow)?"":"none";
	},
	moveCursor: function(cmd) {
		if (!this._suggestList || this._suggestList.length == 0 || this._listBox.style.display == "none") return;

		var index = 0;
		var items = this._listBox.childNodes;
		
		if (this._hilite_item) {
			for(var i=0;i<items.length;i++) {
				if (items[i] == this._hilite_item) {
					if (cmd == "prev") index = i-1;
					else index = i+1;
				}
			}

			index = Math.max(0, Math.min(items.length-1, index) );
		}
			
		this.onMoveCursor(items[index]);

		var y = this._hilite_item.offsetTop - (this._listBox.offsetHeight/2);
		this._listBox.scrollTop = Math.max(0, y);
	},
	onMouseDown: function(ev) {
		nus.event.stopEvent(ev);
	},
	onMoveCursor: function(item) {		
		if (this._hilite_item) {
			this._hilite_item.style.backgroundColor = "transparent";
		}
		
		if (item) {
			item.style.backgroundColor = "#C3C2F0";
			this._hilite_item = item;
		}
	},
	onClickSuggestion: function(item) {
		if (!item && this._hilite_item == -1) return;

		item = item || this._hilite_item;
		
		var tagList = this._tagList;

		if (!$hasClassName(item, "suggestion_item")) {
			return;
		}


		tagList[this._editingTagPos] = this._suggestList[item.id];
		this.onCompleteWord();
	},
	onCompleteWord: function() {
		var tagList = this._tagList;

		var val = "";
		for (var i=0;i<tagList.length;i++) {
			if (tagList[i] != "") val += tagList[i]+",";
		}

		this._active_element.focus();
		this._active_element.value = val;

		this.showListBox(false);
	},

	onDestroy: function() {
		this.abortRequest();
		this._listBox.removeNode(true);
		
		nus.event.removeListener(this._active_element, this["onkeydown_event_key"]);
		nus.event.removeListener(this._active_element, this["onkeyup_event_key"]);

		nus.util.AutoCompletion.superCall(this,"onDestroy");
	},
	
	abortRequest: function() {
		if (this._request) {
			this._request.setComplete();
			this._request = null;
		}
	},

	querySuggest: function(word) {
		this.abortRequest();
	},

	onQueryComplete:function(rsp) {
	}
});

