/**
 * 窗口类
 * @author Jason Chen
 * @version 1.0
 * @todo	1. 事件的绑定和解除绑定原理不明
 *			2. 不明白为什么A绑定时href不能相同，FML
 *			3. 写样式文件写到吐，待学习CSS，GOD Bless Me
 *			4. 写到最后思路比较乱，待修正。。。
 *			5. 内嵌iframe功能未处理。。。。。
 */
(function(){
	var jsDialog = window.jsDialog = function(){};
	var userAgent		= navigator.userAgent.toLowerCase(),
		browser 		= {
			version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1],
			safari: /webkit/.test( userAgent ),
			opera: /opera/.test( userAgent ),
			msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
			mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
		},
		isMouseDown		= false,
		documentWidth	= 0,
		documentHeight	= 0,
		mouseOffset		= null,
		dialogList		= null,
		dialogMaskObj	= null,
		suffix			= "",
		events			= {};
	//fun对象扩展 传入函数集合对象
	jsDialog.extend = function(Fns){
		var target=this;
		for ( var name in Fns ) {
			if(name!==undefined){
				target[name]=Fns[name];
			}
		}
		return target;
	};
	/**
	 * Cache
	 */
	var expando = "jsDialog" + (new Date).getTime(),uuid = 0,windowData = {};
	jsDialog.extend({
		cache : {},
		data : function(elem,name,data){
			elem = (elem == window) ?windowData :elem;
			var id = elem[ expando ];
			
			// Compute a unique ID for the element
			if ( !id ){
				id = elem[ expando ] = ++uuid;
			}
			
			// Only generate the data cache if we're trying to access or manipulate it
			if ( name && !jsDialog.cache[ id ] ){
				jsDialog.cache[ id ] = {};
			}
			
			//无效缓存名称
			if(name == ""){
				return false;
			}
			
			// 若data不等于undefined时重写事件的缓存
			if ( data !== undefined ){
				jsDialog.cache[ id ][ name ] = data;
			}
			
			// Return the named cache data, or the ID for the element
			return name ? jsDialog.cache[ id ][ name ] :id;			
		},
		removeData : function(elem,name){
			elem = (elem == window) ?windowData :elem;
			var id = elem[ expando ];
			//删除元素指定的事件
			if ( name ) {
				if ( jsDialog.cache[ id ] ) {
					// 删除事件的缓存
					delete jsDialog.cache[ id ][ name ];
				}
			} else {	// 若没有指定删除的事件，则删除元素所有事件
				// Clean up the element expando
				try {
					delete elem[ expando ];
				} catch(e){
					// IE has trouble directly removing the expando
					// but it's ok with using removeAttribute
					if ( elem.removeAttribute )
						elem.removeAttribute( expando );
				}
	
				// Completely remove the data cache
				delete jsDialog.cache[ id ];
			}
		}
	});
	/**
	 * Event
	 */
	jsDialog.extend({
		addEvent : function(elem, event, listener) {
			if(elem == null) return;
			if ( elem.nodeType == 3 || elem.nodeType == 8 )	return;
			/**
			 * 事件的绑定。 特别针对mouseover等事件以获得“this=调用元素”设计。
			 * 参考jQuery的实现方式。
			 * 通过apply强制指定 函数的作用域context
			 */
			var handle = jsDialog.data(elem,event,function(){
				handle.element = elem;
				arguments[0].listener = listener;
				return jsDialog.handleApply.apply(arguments.callee.element, arguments)
			});
			if (elem.addEventListener){
				elem.addEventListener(event, handle, false);
			} else if (elem.attachEvent){
				elem.attachEvent('on' + event, handle);
			}
		},
		removeEvent : function(elem, event){
			if(elem == null) return;
			if ( elem.nodeType == 3 || elem.nodeType == 8 )	return;
			
			var events = jsDialog.data(elem,event);
			if(events){
				if(event === undefined){
					//删除元素所有事件和缓存
					for ( var type in events ){
						this.remove(elem, type);
					}
					jsDialog.removeData(elem);
				}else{	//删除元素指定事件
					var handle = jsDialog.data(elem,event);
					if(elem.removeEventListener){
						elem.removeEventListener(event,handle,false);
					}else{
						elem.detachEvent('on' + event, handle);
					}
				}
			}
			elem = null;
		},
		handleApply : function(){
			var listener = arguments[0]["listener"];
			listener.apply(this, arguments);
		}
	});
	jsDialog.extend({
		$ : function(id){
			return "string" == typeof id ? document.getElementById(id) : id;
		},
		/**
		 * 字符串转化整数
		 */
		parseInt : function(value){
			value = parseInt(value);
			return isNaN(value)?0:value;
		},
		/**
		 * 鼠标左键判断
		 */
		isLeftMouseKey : function(ev){
			if(browser.msie){
				if(ev.button == 1){return true;}
			}else{
				if(ev.button == 0){return true;}
			}
			return false;
		},
		/**
		 * 获得节点元素左上角的坐标
		 */
		getPosition : function(e){
			var left = 0;
			var top  = 0;
			while (e.offsetParent){
				left += e.offsetLeft + (e.currentStyle?(this.parseInt(e.currentStyle.borderLeftWidth)):0);
				top  += e.offsetTop  + (e.currentStyle?(this.parseInt(e.currentStyle.borderTopWidth)):0);
				e     = e.offsetParent;
			}

			left += e.offsetLeft + (e.currentStyle?(this.parseInt(e.currentStyle.borderLeftWidth)):0);
			top  += e.offsetTop  + (e.currentStyle?(this.parseInt(e.currentStyle.borderTopWidth)):0);
			return {x:left, y:top};
		},
		/**
		 * 获得event的坐标
		 */
		mouseCoords : function(ev){
			if(ev.pageX || ev.pageY){
				return {x:ev.pageX, y:ev.pageY};
			}
			return {
				x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,
				y:ev.clientY + document.body.scrollTop  - document.body.clientTop
			};
		},
		/**
		 * 鼠标在某元素内的偏移量
		 */
		getMouseOffset : function(target, event){
			event = event || window.event;
			var docPos = this.getPosition(target);
			var mousePos  = this.mouseCoords(event);
			return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y};
		},
		getDocumentElement : function(doc) {
			doc = doc || document;
			return (doc.compatMode != "CSS1Compat") ? doc.body : doc.documentElement;
		},
		getDocumentHeight : function(doc) {
			var el = this.getDocumentElement(doc);
			return Math.max(el.scrollHeight, el.clientHeight);
		},
		getDocumentWidth : function(doc) {
			var el = this.getDocumentElement(doc);
			return Math.max(el.scrollWidth, el.clientWidth);
		},
		
		mousedown : function(moveObj,event,__suffix){
			var event = event || window.event;
			if (jsDialog.isLeftMouseKey(event) == false){return;}
			isMouseDown = true;
			//鼠标的偏移量
			mouseOffset   = jsDialog.getMouseOffset(moveObj, event);
			suffix = __suffix;
		},
		mouseup : function(event){
			isMouseDown=false;
		},
		mousemove : function(event){
			var event=event || window.event;
			if(isMouseDown){
				if(dialogList == null || (suffix in dialogList) == false){
					return;
				}
				var width = this.parseInt(dialogList[suffix].style.width);
				//鼠标的坐标
				var mousePos = jsDialog.mouseCoords(event);
				if((mousePos.x - mouseOffset.x + width) >= documentWidth){
					return;
				}
				if((mousePos.y - mouseOffset.y) <= 0){
					return;
				}
				dialogList[suffix].style.left = (mousePos.x - mouseOffset.x)+"px";
				dialogList[suffix].style.top = (mousePos.y - mouseOffset.y)+"px";
			}
		},
		/**
		 * 窗口大小改变时更新mask背景层大小
		 */
		resize : function(event){
			documentWidth = this.getDocumentWidth();
			documentHeight = this.getDocumentHeight();
			dialogMaskObj.style.height = documentHeight + "px";
			dialogMaskObj.style.width = documentWidth + "px";
		},
		/**
		 * 禁止拖拽时选取文字。
		 */
		forbidSelect : function(currentObj){
			if(browser.msie){
				currentObj.setAttribute("unselectable","on");
				this.addEvent(currentObj,"selectstart",function(event){
					window.event.returnValue = false;
				});
			}else if(browser.mozilla){
				currentObj.style.cssText = "-moz-user-select:none";
			}else{
				currentObj.style.cssText = "-moz-user-select:none";
				this.addEvent(currentObj,"selectstart",function(event){
					if(window.event){
						window.event.returnValue = false;
					}else{
						event.preventDefault();
					}
				});
			}
		},
		/**
		 * 窗口的初始化话，避免重复执行相同的操作
		 */
		init : function(suffix,width,height){
			if(dialogList == null){
				/**
				 * mask 层背景。避免重复创建
				 */
				dialogMaskObj = document.createElement('DIV');
				dialogMaskObj.style.cssText = 'display:none;position:absolute;z-index:101;top:0;left:0;width:0;height:0;background:#948C6E;filter:alpha(opacity=40);-moz-opacity:0.45;opacity:0.55;overflow:hidden;';
				document.body.appendChild(dialogMaskObj);
				
				documentWidth = this.getDocumentWidth();
				documentHeight = this.getDocumentHeight();
				dialogMaskObj.style.height = documentHeight + "px";
				dialogMaskObj.style.width = documentWidth + "px";
				
				this.addEvent(document,"mouseup",function(event){
					jsDialog.mouseup(event);
				});
				this.addEvent(document,"mousemove",function(event){
					jsDialog.mousemove(event);
				});
				this.addEvent(window,"resize",function(event){
					jsDialog.resize(event);
				});
			}
			var windowObj = this.$("window" + suffix);
			if(windowObj == null){	//无效窗口
				return this;
			}
			if(dialogList != null && suffix in dialogList){
			}else{
				dialogList = {};
				//避免重复初始化
				dialogList[suffix] = windowObj;
				var moveObj = this.$("windowTop" + suffix);
				this.forbidSelect(moveObj);
				moveObj.style.cursor = "move";
				//点击窗口header事件
				this.addEvent(moveObj,"mousedown",function(event){
					jsDialog.mousedown(this,event,suffix);
				});
				
				//关闭窗口事件
				this.addEvent(this.$("windowClose" + suffix),"click",function(event){
					jsDialog.hide(suffix);
				});
				if(browser.msie){
					windowObj.style.position = "absolute";
				}else{
					windowObj.style.position = "fixed";	
				}
			}
			//窗口初始化
			windowObj.style.width = width + "px";
			windowObj.style.height = height + "px";
			this.$("windowContent" + suffix).style.height = (height - 30) + "px";
			return this;
		},
		/**
		 * 确定按钮的事件
		 */
		functionOk : function(fun,params){
			if (fun == null || fun(params) !== false){
				this.hide(params[0]);
			}
		},
		/**
		 * 取消按钮的事件
		 */
		functionCancel : function(fun,params){
			if (fun == null || fun(params) !== false){
				this.hide(params[0]);
			}
		},
		/**
		 * 显示窗口
		 */
		show : function(suffix,params){
			if(dialogList == null || (suffix in dialogList) == false){
				return;
			}
			var windowObj = dialogList[suffix];
			if(params){
				switch(params.type){
					case "ok":
					case "error":
					case "notice":
					case "confirm":{
						this.$("message" + suffix).style.display = "";
						this.$("iframe" + suffix).style.display = "none";
						if(params.title){
							this.$("windowTopContent" + suffix).innerHTML = params.title;
						}
						if(params.text){
							this.$("window_message" + suffix).innerHTML = params.text;
						}
						this.$("imgIcon" + suffix).className = "icon_" + params.type;

						var window_ok = this.$("window_ok" + suffix);
						window_ok.style.display = (params.ok == false)?"none":"";
						
						//删除原有绑定事件，避免重复加载事件
						this.removeEvent(window_ok,"click");
						this.addEvent(window_ok,"click",function(event){
							jsDialog.functionOk(params.ok_fun,[suffix]);
						});
						
						var window_cancel = this.$("window_cancel" + suffix);
						window_cancel.style.display = (params.cancel == false)?"none":"";
						
						//删除原有绑定事件，避免重复加载事件
						this.removeEvent(window_cancel,"click");
						this.addEvent(window_cancel,"click",function(event){
							jsDialog.functionCancel(params.cancel_fun,[suffix]);
						});
					
						break;
					}
					case "iframe":{
						this.$("message" + suffix).style.display = "none";
						this.$("iframe" + suffix).style.display = "";
						
						if(params.title){
							this.$("windowTopContent" + suffix).innerHTML = params.title;
						}
						window.frames["windowFrame" + suffix].location = params.href;
						break;
					}
				}
				//关闭窗口的事件触发
				if(params.cancel_fun){
					var window_close = this.$("windowClose" + suffix);
					jsDialog.removeEvent(window_close,"click");
					jsDialog.addEvent(window_close,"click",function(event){
						jsDialog.functionCancel(params.cancel_fun,[suffix]);
					});
				}
			}
			
			var width = height = 0;
			width = this.parseInt(windowObj.style.width);
			height = this.parseInt(windowObj.style.height);
			//mask 层背景	自动创建
			dialogMaskObj.style.display = "block";

			//在指定位置显示窗口
			windowObj.style.left = (this.getDocumentElement().clientWidth - width)/2 + "px";
			if(browser.msie){
				windowObj.style.top = (Math.abs(this.getDocumentElement().clientHeight - height)*0.75/2 + this.getDocumentElement().scrollTop) + "px";
			}else{
				windowObj.style.top = (Math.abs(this.getDocumentElement().clientHeight - height)*0.75/ 2) + "px";
			}
			windowObj.style.display = "block";
			
			if(params){
				try{
					if(params.focus == "cancel"){
						this.$("window_cancel" + suffix).focus();
					}else{
						this.$("window_ok" + suffix).focus();
					}
				}catch(e){}
			}
		},
		/**
		 * 隐藏窗口
		 */
		hide : function(suffix){
			if(dialogList == null || (suffix in dialogList) == false){
				return;
			}
			dialogList[suffix].style.display = "none";
			dialogMaskObj.style.display = "none";
			window.frames["windowFrame" + suffix].location = "about:blank";
		},
		/**
		 * 弹出临时性的提示窗口
		 * @todo 根据不同信息列表显示不同ICO
		 */
		showMessage : function(suffix,message,time){
			if(time == undefined){time = 2;}
			this.$("fun_msgBox" + suffix).style.display = "";
			this.$("fun_msg_info" + suffix).innerHTML = message;
			var timer = setInterval(function(){
				jsDialog.$("fun_msgBox" + suffix).style.display = "none";
				clearInterval(timer);
			},time*1000);
		}
	});
})();
