﻿(function(){
var Key = {
	ESC:27,
	TAB:9,
	UP:38,
	DOWN:40,
	ENTER:13
};
if (typeof window.$5 == 'undefined') window.$5 = {};
var smartHint = window.$5.smartHint = function(inputId, hintId){};
smartHint.prototype = {
	inputer:null,
	hinter:null,
	hintPanel:null,
	onAppendHint:function(){},
	onBeforeShow:function(){return true},
	init:function(inputer, hinter, setPosition) {
		this.inputer = inputer;
		this.hinter = hinter;
		this.inputer.attr('autocomplete','off');
		this.hinter.addClass('smartHint');
		this.hinter.width(this.inputer.width());
		if (setPosition) this.resetPosition();
		
		var self = this;
		this.inputer.bind("keydown", function(event) {
			event = event || window.event;
//			tagSmartHint.isTabKey = false;
//			smartHint.tabRelObj = null;
			switch (event.keyCode) {
				case Key.TAB:
					if (self.hintPanel.isVisible()) {
						self.hintPanel.hintCurrent();
					}
//					tagSmartHint.isTabKey = true;
					smartHint.tabRelObj = this.inputer;
					
					if (typeof event.cancelable == "undefined") return false;
					else event.preventDefault();
					break;
				case Key.ENTER:
					if (self.hintPanel.isVisible()) {
						self.hintPanel.hintCurrent();
						if (typeof event.cancelable == "undefined") return false;
						else event.preventDefault();
					}
					break;
			}
		});
		this.inputer.bind("keyup", function(event) {
			event = event || window.event;
			switch (event.keyCode) {
				case Key.ESC:
					self.hintPanel.hide();
					break;
				case Key.UP:
					if (!self.hintPanel.isVisible()) {
						self.hintPanel.show();
					}
					if (!self.hintPanel.isVisible()) return;
					self.hintPanel.moveUp();
					break;
				case Key.DOWN:
					if (!self.hintPanel.isVisible()) {
						self.hintPanel.show();
					}
					if (!self.hintPanel.isVisible()) return;
					self.hintPanel.moveDown();
					break;					
				default:
					self.hintPanel.show();
					break;
			}
//			tagSmartHint.isTabKey = false;
			smartHint.tabRelObj = null;
		});
		
		this.hintPanel = new hintPanel(this.hinter);
		this.hintPanel.onAppendHint = function(text) {
			return self.onAppendHint.call(self, self.inputer, self.hinter, text);
		};
		this.hintPanel.onBeforeShow = function() {
			return self.onBeforeShow.call(self, self.inputer, self.hinter);
		};
	},
	resetPosition:function(){
	    var pos = this.inputer.offset();
	    this.hinter.css({left:pos.left,top:pos.top + this.inputer.height() + 6});
	},
	addHint:function(text) {
		this.hintPanel.add(text, false);
	},
	addWarn:function(text){
	    this.hintPanel.add(text, true);
	},
	clearHints:function() {
		this.hintPanel.clear();
		this.hintPanel.hide();
	}
};

var hintPanel = function(hinter) {
	this.hinter = hinter;
	hintPanel.PanelArray.push(this);
};

hintPanel.PanelArray = [];

hintPanel.prototype = {
	curIndex:-1,
	hintCount:0,		
	interval:null,
	add:function(text,warn) {
		var div = $(document.createElement("div"));
		div.append(text);
		div.addClass(warn ? "warn" : "normal");
		
		if (!warn) {
		    var self = this;
		    div.mouseover(function(){
			    self.move2Hint(parseInt(div.attr("_index"), 10));
		    });
		    div.attr("_index", this.hintCount);
    		
		    div.click(function() {
			    self.onAppendHint(this.innerText || this.textContent);
			    self.hide();
		    });
		}
	    this.hinter.append(div);
	    this.hintCount++;
	},
	clear:function() {
		this.hinter.empty();
		this.hintCount = 0;
	},
	move2Hint:function(index) {
		var prevIndex = this.curIndex;
		this.curIndex = index = (index + this.hintCount) % this.hintCount;
		if (prevIndex > -1 && prevIndex < this.hintCount && prevIndex != index) {
			this.hinter[0].childNodes[prevIndex].className = "normal";
		}
		var el = this.hinter[0].childNodes[index];
		if(el.className != 'warn')el.className = "selected";
	},
	hasHints:function() {
		return this.hintCount > 0;
	},
	/**
	 * 当提示附加到输入框时。
	 */
	onAppendHint:function(text) {
		return true;
	},
	/**
	 * 在提示框显示之前
	 */
	onBeforeShow:function(){
		return true;
	},
	show:function() {
		var self = this;
		if (this.interval != null) {
			this.hide();
			window.clearInterval(this.interval);
		}
		
		this.interval = window.setInterval(function(){
			if (self.onBeforeShow() && self.hintCount != 0) {
				self.move2Hint(0);
				self.hinter.show();
			}	
			window.clearInterval(self.interval);
		}, 500);					
	},
	hide:function() {
		if (this.interval != null) window.clearInterval(this.interval);
		this.hinter.hide();
	},
	moveUp:function() {
		this.move2Hint(this.curIndex - 1);
	},
	moveDown:function() {
		this.move2Hint(this.curIndex + 1);
	},
	hintCurrent:function() {
		$(this.hinter[0].childNodes[this.curIndex]).trigger('click');
	},
	isVisible:function() {
		return this.hinter.css('display') != "none";
	}
};
$(document).bind("click", function(event) {
	var array = hintPanel.PanelArray;
	for (var i = 0; i < array.length; i++) {
		if (array[i].isVisible()) {
			array[i].hide();
		}
	}		
});
	
})()