/*************************************************/
/*	Author : pzling								 */
/*	Site : http://pzling.com					 */
/*************************************************/

var Fantasy = window.Fantasy || {};

(function(NS){
	defaultConfig = {
		containerClass : "suggest-container",	//提示层样式
		offsetLeft : 0,								//左偏移，默认文本框左对齐，可以通过该值做调整
		offsetTop : 0,								//上偏移
		timerDelay : 600,							//延迟显示提示框
		resultFormat : "约$result$",
		closeBtnAlt : "关闭",
		showCloseBtn : true,						//是否显示关闭按钮
		autoSubmit : false							//点击选项时，是否自动提交
	};
	NS.Suggest = function(txtBox,source,config){
		this.defSource = "/Module/QueryComplete.aspx?q=";
		this.sugKeyClass = "suggest-key";
		this.sugResultClass = "suggest-result";
		this.selectedItemClass = "selected-item";
		this.source = source ? source : this.defSource;
		this.returnData = null;
		this.jsonSource = source instanceof Object ? source : null;
		this.$container = null;		//主容器
		this.isIE = navigator.userAgent.indexOf("MSIE") > 0;
		this.mouseDownItem = null;
		this.$txtBox = $(txtBox);
		this.CONFIG = $.extend(defaultConfig,config || {});
		this.script = null;				//加载脚本
		this.scriptLastestTime = "";	//脚本最后加载时间
		this.scriptTimeout = false;		//脚本是过期
		this.selectedItem = null;		//当前选中项索引
		this.dataCache = {};			//缓存查询数据
		this.queryStr = "";				//输入框的值
		this.timer = null;				//计时器
		this.isRunning = false;			//计时器是否处于运行状态
		this.pressingCount = 0;			//按住按键，连续触发keydown事件
		this._init();
	};
	NS.Suggest.prototype = {
		//初始化
		_init : function(){
			this.createSuggest();	//创建提示层
			this.initEvent();
		},
		//初始化事件绑定
		initEvent : function(){
			var instance = this;
			this.$txtBox.focus(function(){
				instance.start();
			}).blur(function(){
				instance.stop();
				instance.hide();
			}).keydown(function(event){
				var keyCode = event.keyCode;
				switch(keyCode){
					case 13:
						if(instance.itemSelect){instance.itemSelect();}
						instance.submitForm();
						return;
					case 27:	//ESC键，隐藏层并还原原输入值
						instance.hide();
						instance.setQueryStr();
						break;
					case 38:
					case 40:
						//按住按键，延时处理
						if(instance.pressingCount++ ==0){
							if(instance.isRunning) instance.stop();
							instance.selectItem(keyCode == 40);
						}else if(instance.pressingCount >= 3){
							instance.pressingCount = 0;
						}
						break
				}
				if(keyCode != 38 && keyCode !=40){
					if(!instance.isRunning){
						instance.start();
					}
				}
			}).keyup(function(){
				instance.pressingCount = 0;
			}).attr("autocomplete","off");
			this.$container.bind("mousemove",function(event){
				var target = event.target;
				$("#t").html(event.clientX);
				if(target.nodeName != "LI"){
					target = target.parentNode
				}
				if(target.nodeName == "LI"){
					instance.removeSelectedItem();
					instance.selectedItem = target;
					$(target).addClass(instance.selectedItemClass);
				}
			}).bind("mousedown",function(e){
				this.mouseDownItem = e.target ;
				//使输入框不会失去焦点
				//for IE
				instance.$txtBox[0].onbeforedeactivate = function(){
					window.event.returnValue = false;
					instance.$txtBox[0].onbeforedeactivate = null;
				};
				return false;
			}).bind("mouseup",function(event){
				var e = event.target;
				if(this.mouseDownItem != e) return ;
				var pNode = e.parentNode;
				if(pNode.className == "key-main" || pNode.parentNode.className == "key-main"){
					if(instance.itemSelect){instance.itemSelect();}
					instance.submitForm();
				}
				instance.hide();
				return;
			});
		},
		_getXY : function(el){
			var left=0 , top=0;
			if(typeof(el.tagName) != "undefined"){
				while(el.parentNode !== null && el.offsetParent !== null){
					left += el.offsetLeft;
					top += el.offsetTop;
					el = el.offsetParent;
				}
			}
			return {x:left,y:top};
		},
		//添加提示层
		createSuggest : function(){
			this.$container = $(
					'<div>'+
					'</div>')
					.addClass(this.CONFIG.containerClass)
					.bind("selectstart",function(){ return false;});
			$("body").append(this.$container);
			this.$container.css({ 
				 position : "absolute" ,
				 left : this._getXY(this.$txtBox[0]).x + this.CONFIG.offsetLeft,
				 top : this._getXY(this.$txtBox[0]).y + this.$txtBox.outerHeight() + this.CONFIG.offsetTop
			})
			if(this.$container.width() == 0){
				this.$container.css("width",this.$txtBox.outerWidth() - 2);
			}
			this.initShim();
		},
		//如果为IE6,则添加iframe shim
		initShim : function() {
			if(navigator.appVersion.split(";")[1]==" MSIE 6.0"){
				this.$container.shim =	$("<iframe></iframe>")
						.width(this.$container.outerWidth())
						.attr({"id":"sugIframe","src":"about:blank","class":"suggest-shim"})
						.css({
							 position:"absolute",
							 left:this.$txtBox.offset().left + this.CONFIG.offsetLeft,
							 top:this.$txtBox.offset().top + this.$txtBox.outerHeight() + this.CONFIG.offsetTop,
							 border:"none",
							 visibility:"hidden"
						});
				$("body").append(this.$container.shim);
			}
		},
		//更新提示层数据
		fillEleContainer : function(content){
			if(content.length == 1){
				this.$container.html("");
				this.$container.prepend(content)
			}else{
				this.$container.html(content);
			}
			this.selectedItem = null;
		},
		//启动计时器，监听用户输入
		start : function(){
			var instance = this;
			NS.Suggest.focusInstance = this;
			this.timer = setInterval(function(){
				instance.updateInput();
			},this.CONFIG.timerDelay);
			this.isRunning = true;
		},
		//停止计时器
		stop : function(){
			NS.Suggest.focusInstance = null;
			clearInterval(this.timer);
			this.isRunning = false;
		},
		//是否需要更新信息
		needUpdate : function(){
			return this.$txtBox.val() != this.queryStr;
		},
		//更新当前文本框
		updateInput : function(){
			if(!this.needUpdate()) return;
			//查询，更新层内容，保存缓存
			this.queryStr = escape(this.$txtBox.val());
			var q = this.queryStr;
			if(!$.trim(q).length){
				this.fillEleContainer("");
				this.hide();
				return;
			}
			var content = "";
			if(typeof this.dataCache[q] != "undefined"){
				//使用缓存数据
				this.fillEleContainer(this.dataCache[q]);
				this.displayContainer();
			}else if(this.jsonSource){
				NS.Suggest.focusInstance.handleResponse(this.jsonSource[q]);
			}else{
				this.requestData();
			}
			
		},
		//根据内容显示或隐藏提示层
		displayContainer : function(){
			if(this.$container.html() == ""){
			//if(this.$container.children("ol").length == 0){
				this.hide();
			}else{
				this.show();
			}
		},
		//加载远程数据
		requestData : function(){
			var _this = this;
			if(!this.isIE) this.script = null;
			//非IE的，需要重新加载<script>
			if(!this.script){
				this.script = $("<script></script>").attr("type","text/javascript");
				document.getElementsByTagName("head")[0].insertBefore(this.script[0],document.getElementsByTagName("head")[0].firstChild);
				if(!this.isIE){
					var t = new Date().getTime();
					this.scriptLastestTime = t;
					this.script.attr("time",t);
					this.script.load(function(script){
						//判断返回的数据是否过期
						_this.scriptTimeout = this.getAttribute("time") != _this.scriptLastestTime;
					})
				}
			}
			if(this.beforeRequest){this.beforeRequest();}
			this.script.attr("src",this.source + encodeURIComponent(this.queryStr));
	
		},
		//处理获取到的数据
		handleResponse : function(data){
			if(this.scriptTimeout) return ;
			this.returnData = data;
			if(this.dataReturn){this.dataReturn(data);}
			//格式化数据
			this.returnData = this.formatData(this.returnData);
			var len = this.returnData.length;
			if(len>0){
				var content = "";
				var $list = $("<ol class=\"key-main\">");
				for(i=0; i<len; i++){
					$list.append(this.formatItem(this.returnData[i]["key"],this.returnData[i]["result"]));
				}
				content = $list;
				//更新数据
				this.fillEleContainer(content);
				//添加关闭按钮
				this.appendCloseBtn();
			}else if(this.empty){
				this.empty();
			}

			if(this.beforeShow){this.beforeShow();}
			this.dataCache[this.queryStr] =  this.$container.html();
			this.displayContainer();
		},
		//格式化结果数组(一或二维数组)
		//格式一：[["key1", "result1"], ["key2", "result2"], ...]
		//格式二：["key1", "key2", ...]
		formatData : function(data){
			var arr = [];
			if(!data) return arr;
			var len = data.length;
			if(!len) return arr;
			var item;
			for( i=0; i<len; i++){
				item = data[i];
				if(typeof(item) == "string"){
					arr[i] = {"key" : item};
				} else if ($.isArray(item) && item.length >= 2){
					arr[i] = {"key" : item[0] , "result" : item[1]};
				}
			}
			return arr;
		},
		//格式化输出项
		formatItem : function(key,result){
			var $li = $("<li></li>").append($('<span></span>').addClass(this.sugKeyClass).html(key)).attr({"key":key,"val":result});
			if(typeof result != "undefined"){
				var resultText = this.CONFIG.resultFormat.replace("$result$",result);
				$li.append($('<span></span>').addClass(this.sugResultClass).html(resultText));
			}
			return $li[0];
		},
		//更新当前文本框为选中的key
		updateInputFromKey : function(){
			this.$txtBox.val(this.getSelectedItemKey());
		},
		appendCloseBtn : function(){
			if(this.CONFIG.showCloseBtn){
				$('<div class="suggest-close"></div>')
				.append(
					$('<a href="javascript:void(0);">关闭</a>')
					.attr({"title":this.CONFIG.closeBtnAlt,"target":"_self"})
				).appendTo(this.$container);
			}
		},
		//用键盘选择key
		selectItem : function(down){
			//不存在搜索结果，直接返回
			this.stop();
			var items = this.$container.find("li");
			if(items.length == 0) return ;
			//按ESc隐藏了，显示返回就可以
			if(this.isVisible()){
				this.show();
				return;
			}
			var newSelectedItem;
			if(this.selectedItem){
				newSelectedItem = down ? $(this.selectedItem).next() : $(this.selectedItem).prev();
			}else{
				newSelectedItem = items.eq(down ? 0 : items.length - 1);
			}
			newSelectedItem = newSelectedItem[0]
			this.removeSelectedItem();
			this.setSelecedItem(newSelectedItem);
			if(!newSelectedItem){
				//回复原文本框值
				this.setQueryStr();
				return;
			}
			this.updateInputFromKey();
		},
		isVisible : function(){
			return this.$container.css("display") == "none";
		},
		//移除选中项
		removeSelectedItem : function(){
			$(this.selectedItem).removeClass(this.selectedItemClass);
			this.selectedItme = null;
		},
		//设置选中项
		setSelecedItem : function(target){
			$(target).addClass(this.selectedItemClass);
			this.selectedItem = target;
		},
		//回复原文本框值
		setQueryStr : function(){
			this.$txtBox.val(this.queryStr);
		},
		//获取选中项的key
		getSelectedItemKey : function(){
			if(!this.selectedItem) return "";
			return $(this.selectedItem).attr("key");
		},
		//获取选中项的Val
		getSelectedItemVal : function(){
			if(!this.selectedItem) return "";
			return $(this.selectedItem).attr("val");
		},
		//显示提示层
		show : function(){
			if(this.$container.shim){this.$container.shim.css({height:this.$container.height(),visibility:""});}
			this.$container.show();
		},
		//隐藏提示层
		hide : function(){
			if(this.$container.shim){this.$container.shim.css("visibility","hidden");}
			this.$container.hide();
		},
		submitForm : function(){
			if(this.selectedItem != null ){
				this.updateInputFromKey();
			}
			this.$txtBox.blur();
			var form = this.$txtBox[0].form;
			if(!form || !this.CONFIG.autoSubmit) return false;
			form.submit();
		}
	};
	NS.Suggest.focusInstance = null;
	NS.Suggest.beforeRequest = null;
	NS.Suggest.beforeShow = null;
	NS.Suggest.dataReturn = null;
	NS.Suggest.itemSelect = null;
	NS.Suggest.empty = null;
	NS.Suggest.CallBack = function(data){
		if(!NS.Suggest.focusInstance) return;
		NS.Suggest.focusInstance.handleResponse(data);
	};
})(Fantasy);
