﻿(function() {
	function $() {
		var elements = [];
		
		for (var i = 0, l = arguments.length; i < l; i++) {
			var element = arguments[i];
			
			if (typeof element == 'string')
				element = document.getElementById(element);
			if (l == 1)
				return element;
			
			elements.push(element);
		}
		return elements;
	}

	function $tag(tname, el) {
		return (el || document).getElementsByTagName(tname);
	}
	
	function $toArray() {
		/*return Array.apply(null, arguments);*/
		/*(var ret = [];
		for (var i = 0, l = obj.length; i < l; i++) {
			ret.push(obj[i]);
		}
		return ret;*/
		return Array.prototype.slice.call(arguments);
	}
	
	// written by Dean Edwards, 2005
	// with input from Tino Zijdel, Matthias Miller, Diego Perini
	function addEvent(element, type, handler) {
		if (element.addEventListener) {
			element.addEventListener(type, handler, false);
		} else {
			// assign each event handler a unique ID
			if (!handler.$$guid) handler.$$guid = addEvent.guid++;
			// create a hash table of event types for the element
			if (!element.events) element.events = {};
			// create a hash table of event handlers for each element/event pair
			var handlers = element.events[type];
			if (!handlers) {
				handlers = element.events[type] = {};
				// store the existing event handler (if there is one)
				if (element["on" + type]) {
					handlers[0] = element["on" + type];
				}
			}
			// store the event handler in the hash table
			handlers[handler.$$guid] = handler;
			// assign a global event handler to do all the work
			element["on" + type] = handleEvent;
		}
	}
	// a counter used to create unique IDs
	addEvent.guid = 1;

	function removeEvent(element, type, handler) {
		if (element.removeEventListener) {
			element.removeEventListener(type, handler, false);
		} else {
			// delete the event handler from the hash table
			if (element.events && element.events[type]) {
				delete element.events[type][handler.$$guid];
			}
		}
	}

	function handleEvent(event) {
		var returnValue = true;
		// grab the event object (IE uses a global event object)
		event = event || eventUtil.getEvent();
		// get a reference to the hash table of event handlers
		var handlers = this.events[event.type];
		// execute each event handler
		for (var i in handlers) {
			this.$$handleEvent = handlers[i];
			if (this.$$handleEvent(event) === false) {
				returnValue = false;
			}
		}
		return returnValue;
	}
	
	var eventUtil = {
		addDOMLoadEvent: function(func) {
			if (!window.__load_events) {
				var init = function () { 
					// quit if this function has already been called 
					if (arguments.callee.done) return; 

					// flag this function so we don't do the same thing twice 
					arguments.callee.done = true; 

					// kill the timer 
					if (window.__load_timer) { 
						clearInterval(window.__load_timer); 
						window.__load_timer = null; 
					}

					// execute each function in the stack in the order they were added 
					for (var i=0;i < window.__load_events.length;i++) { 
						window.__load_events[i](); 
					}
					window.__load_events = null; 
				}; 

				// for Mozilla/Opera9 
				if (document.addEventListener) { 
					document.addEventListener('DOMContentLoaded', init, false); 
				}

				// for Internet Explorer 
				/*@cc_on @*/ 
				/*@if (@_win32) 
				  document.write('<scr'+'ipt id=__ie_onload defer src=//0><\/scr'+'ipt>'); 
				  var script = document.getElementById('__ie_onload'); 
				  script.onreadystatechange = function() { 
					  if (this.readyState == 'complete') { 
						  init(); // call the onload handler 
					  } 
				  }; 
				/*@end @*/ 

				// for Safari 
				if (/WebKit/i.test(navigator.userAgent)) { // sniff 
					window.__load_timer = setInterval(function() { 
						if (/loaded|complete/.test(document.readyState)) { 
							init(); // call the onload handler 
						} 
					}, 10);
				}

				// for other browsers 
				//window.onload = init;

				// create event function stack 
				window.__load_events = [];
			}
		   
			// add function to event stack 
			window.__load_events.push(func);
		},
	
		'addEvent': addEvent,

		'removeEvent': removeEvent,

		cancelDefault: function() {
			var e = eventUtil.getEvent();
			e.preventDefault();
			e.stopPropagation();
			return false;
		},
				
		getEvent: function() {     //compatible msie and firefox
			if(window.event)
				return eventUtil.fixPosition(eventUtil.fixEvent(window.event));        
			var __func__ = arguments.callee.caller;

			while(__func__ != null) {    
				var arg = __func__.arguments[0];
				if(arg) {
					if(typeof(arg) == 'object' && 
						arg.cancelBubble != undefined &&
							((arg.constructor == Event || 
								arg.constructor == MouseEvent) ||
							(arg.preventDefault && 
								arg.stopPropagation))) {
						return eventUtil.fixPosition(arg);
					}
				}
				__func__ = __func__.caller;
			}
			return null;
		},

		fixEvent: function(evt) {
			evt.charCode = evt.type == 'keypress' ? evt.keyCode : 0;
			evt.eventPhase = 2;
			evt.isChar = evt.charCode >  0;
			evt.preventDefault = function() {
				this.returnValue = false;
			};
			
			if (evt.type) {
                if (evt.type == 'mouseover')
                    evt.relatedTarget = evt.toElement;
                else if (evt.type == 'mouseout')
                    evt.relatedTarget = evt.fromElement;
			}
			
			evt.stopPropagation = function() {
				this.cancelBubble = true;
			};
			
			evt.target = evt.srcElement;
			evt.time = new Date().getTime();
			return evt;
		},
		
		fixPosition: function(evt) {
			evt.realX = evt.pageX || evt.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft);
			evt.realY = evt.pageY || evt.clientY + (document.documentElement.scrollTop || document.body.scrollTop);
			return evt;
		}
	};
	
	var DomUtil = {
        forEach: function(args, fn) {
            for (var i = 0; i < args.length; i++) {
                fn(args[i]);
            }
        },
        emptyCld: function() {
            DomUtil.forEach(arguments, function(el) {
                if ('length' in el)
                    DomUtil.forEach(el, function (iel) {
                        DomUtil.clearCld(iel);
                    });
                else
                    DomUtil.clearCld(el);
            });
        },
        clearCld: function(el) {
            el.parentNode.replaceChild(el.cloneNode(false), el);
            delete el;
        },
        createEl: function(elName) {
            if (!DomUtil.createEl[elName])
                DomUtil.createEl[elName] = document.createElement(elName);
            return DomUtil.createEl[elName].cloneNode(true);
        },
        createTxt: function(elName) {
            if (!DomUtil.createTxt[elName])
                DomUtil.createTxt[elName] = document.createTextNode(elName);
            return DomUtil.createTxt[elName].cloneNode(true);
        },
        removeEl: function(el) {
            if (el && el.parentNode) el.parentNode.removeChild(el);
        }
	};
	
	/*DialogBox begin...*/
	function dialogBox() {
		this.init();
	}
	
	dialogBox.options = {
		position: 'absolute',
		zIndex: '999',
		textAlign: 'center',
		border: 'solid 3px #aaaaaa',
		color: '#000000',
		backgroundColor: '#ffffff',
		width: '30%',
		left: '30%',
		cursor: 'move'
	};
	
	dialogBox.prototype = {
		init: function() {			
			var dialogArea = DomUtil.createEl('div');
			for (var opk in dialogBox.options)
				dialogArea.style[opk] = dialogBox.options[opk];
						
			var txtMsg = DomUtil.createEl('div');			
			dialogArea.appendChild(txtMsg);			
			
			this.dialog = dialogArea;
			new SimpleDrag(dialogArea);
			this.msg = txtMsg;
		},
		setMessage: function(msg) {
			msg = msg.toString ? msg.toString() : typeof(msg);
			//if (msg.length > 54)
					//msg = msg.slice(0, 54);
			//this.msg.textContent = this.msg.innerText = msg;
			this.msg.innerHTML = msg;
			
			document.body.appendChild(this.dialog);
			var realHeight = (window.scrollY || window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop) + (document.body.clientHeight > document.documentElement.clientHeight && document.documentElement.clientHeight > 0 ? document.documentElement.clientHeight : document.body.clientHeight)/2 - this.dialog.offsetHeight / 2;
			this.dialog.style.top = realHeight + 'px';			
			this.dialog.lastChild.focus();
		},
		addButton: function(buttonText, clickFn, useValidate) {
			var closeMsg = DomUtil.createEl('input');
			closeMsg.style.color = 'blue';
			closeMsg.type = 'button';
			closeMsg.value = buttonText;
			var me = this;
			addEvent(closeMsg, 'click', function() {
				if (!useValidate || (useValidate && clickFn && clickFn()))
					me.close();
				if (!useValidate && clickFn)
					clickFn();
			});
			me.dialog.appendChild(closeMsg);
		},
		close: function() {
		    this.dialog.parentNode.removeChild(this.dialog);
		}
	};
	
	var dialogUtil = {
		alert: function(msg) {
			if (arguments.length == 0) return;
			var alertArea = new dialogBox();
			alertArea.addButton('\u5173\u95ED', function() {
			    alertArea.close();
			    delete dialogUtil.alert.boxs[alertArea.boxIndex];
			    dialogUtil.alert.count--;			    
			});
			alertArea.setMessage(msg);
			
			if (dialogUtil.alert.count == undefined)
			    dialogUtil.alert.count = 0;
			if (dialogUtil.alert.boxs == undefined)
			    dialogUtil.alert.boxs = {};
			dialogUtil.alert.count++;
			alertArea.boxIndex = dialogUtil.alert.count;
            dialogUtil.alert.boxs[alertArea.boxIndex] = alertArea;
            if (dialogUtil.alert.count > 1) {
                alertArea.addButton('\u5173\u95ED\u6240\u6709', function() {
                    for (var bk in dialogUtil.alert.boxs) {
                        if (dialogUtil.alert.boxs[bk]) {
                            dialogUtil.alert.boxs[bk].close();
                            delete dialogUtil.alert.boxs[bk];
                        }
                    }
                    dialogUtil.alert.count = 0;
                });
            }
		},
		confirm: function(msg, yesFn, noFn) {
			if (arguments.length == 0) return;			
			var confirmArea = new dialogBox();
			confirmArea.addButton('\u662F', yesFn);
			confirmArea.addButton('\u5426', noFn);
			confirmArea.setMessage(msg);
		},
		prompt: function(msg, callback) {
			if (arguments.length == 0) return;			
			var promptArea = new dialogBox();
			var inputDiv = DomUtil.createEl('div');
			var inputArea = DomUtil.createEl('input');
			inputArea.type = 'text';
			inputArea.size = '30';
			inputDiv.appendChild(inputArea);
			promptArea.dialog.appendChild(inputDiv);
			promptArea.addButton('\u786E\u5B9A', function() {
				callback.call(inputArea, inputArea.value);
			});
			promptArea.setMessage(msg);
		}
	};
	/*DialogBox end...*/
	
	var styleUtil = {
		appendCss: function(csstext) {
			var isIe = !!document.createStyleSheet;
			var _style = isIe ? document.createStyleSheet() : document.createElement('style');
			if (isIe)
				_style.cssText = csstext;
			else {
				_style.type = 'text/css';
				var txtNode = document.createTextNode(csstext);
				_style.appendChild(txtNode);
				$tag('head')[0].appendChild(_style); 
			}
		},
	
		includeCss: function(cssUrl) {
			var lnk = document.createElement('link');
			lnk.setAttribute('rel', 'stylesheet');
			lnk.setAttribute('type', 'text/css');
			lnk.setAttribute('href', cssUrl);
			$tag('head')[0].appendChild(lnk);
		},
		
		getStyles: function() {
			return document.styleSheets || document.getElementsByTagName('style');
		},
		
		getRules: function(styleSheet) {
			return styleSheet.cssRules || styleSheet.rules;
		},

		addCssRule: function(cSelector, cRuleText, styleSheet) {			
			if (styleSheet.rules)
				styleSheet.addRule(cSelector, cRuleText);
			else if (styleSheet.insertRule) {
				var _rules = styleUtil.getRules(styleSheet);
				var _cindex = _rules.length;
				styleSheet.insertRule(cSelector + '{' + cRuleText + '}', _cindex);
			}
		},
		
		getRealStyle: function(el, styleName) {
			el = $(el);
			if (el.currentStyle)
				return el.currentStyle[styleName];
			else if (window.getComputedStyle)
				return window.getComputedStyle(el, null)[styleName];
			return null;
		},
		
        setStyle: function(element, styles) {
            element = $(element);
            var elementStyle = element.style;
            for (var property in styles)
              if (property == 'opacity') styleUtil.setOpacity(styles[property]);
              else
                elementStyle[(property == 'float' || property == 'cssFloat') ?
                  (Object.isUndefined(elementStyle.styleFloat) ? 'cssFloat' : 'styleFloat') :
                    property] = styles[property];

            return element;
          },

          setOpacity: function(element, value) {
            element = $(element);
            element.style.opacity = (value == 1 || value === '') ? '' :
              (value < 0.00001) ? 0 : value;
            return element;
          },
	
        toggleDisplay: function(objname, value) {
			var obj = $(objname);
			obj.style.display = obj.style.display == 'none' ? value || '' : 'none';
		}
	};
	
	var cookieUtil = {
		getCookie: function(cookieName) {
			var re = new RegExp(encodeURIComponent(cookieName) + '=([^;]+);?');
			var matchedck = null;
			if ((matchedck = re.exec(document.cookie)) != null &&
				matchedck && matchedck[1])
				return decodeURIComponent(matchedck[1]);
			return '';
			/*var cookie_start = document.cookie.indexOf(cookieName);
			var cookie_end = document.cookie.indexOf(';', cookie_start);
			return cookie_start == -1 ? '' : decodeURIComponent(document.cookie.substring(cookie_start + name.length + 1, (cookie_end > cookie_start ? cookie_end : document.cookie.length)));*/
		},
		/**
		 *cookie名称、值、过期时间（小时）...
		 */
		setCookie: function(cookieName, cookieValue, hours, path, domain, secure) {
			if (!cookieName)
				throw new Error('cookie name is null');
			var expires = new Date();
			expires.setTime(expires.getTime() + (hours * 1000 * 60 * 60));
			document.cookie = encodeURIComponent(cookieName) + '=' + encodeURIComponent(cookieValue || '')
				+ (expires ? '; expires=' + expires.toGMTString() : '')
				+ (path ? '; path=' + path : '')
				+ (domain ? '; domain=' + domain : '')
				+ (secure ? '; secure' : '');
		},
		
		eraseCookie: function(cookieName) {
			cookieUtil.setCookie(cookieName, '', -1);
		}
	};
	
	var stringUtil = {
		/**
		 *去除字符串两边空格
		 */
		trimString: function(str) {
			if (!str)
				return '';
			return str.replace(/(^\s+)|(\s+$)/gi, '');
		},
		isChinese: function(inputStr) {
			return /^[\u4E00-\u9FA5]+$/.test(inputStr);
		},
		cnToAscii: function(cnString) {
			return escape(cnString).replace(/%u/g, '\&#x');
		},
		cnToUnicode: function(cnString) {
			return escape(cnString).replace(/%/g, '\\');
		},
		/**
		 *charCodes ascii或unicode字符串
		 *regexp 匹配规则
		 */
		charCodeToCn: function(charCodes, regexp) {
			return charCodes.replace(regexp, function($0, $1, $2) {
				return String.fromCharCode(
					parseInt($2, 16)/*把16进制的字符串转换成int型数字*/
				);
			});
		},
		asciiToCn: function(asciiChars) {		
			return stringUtil.charCodeToCnString(asciiChars, /(\&#x)(\w{4})/gi);/*unescape(asciiChars.replace(/\&#x/g, '%u'));*/
		},
		unicodeToCn: function(unicodeChars) {
			return unescape(unicodeChars.replace(/\\/g, '%'));
		}
	};
	
	var validators = {		
		isNull: function(inputStr) {
			return stringUtil.trimString(inputStr).length == 0;
		},
		isEmail: function(inputStr) {
			return /^[\w]+[\-\.]?[\w]+@[a-zA-Z0-9]+\.[a-zA-Z]+(\.[a-zA-Z]+)?$/.test(inputStr);
		},
		isPhone: function(inputStr) {
			return /^\d{3,4}\d{8}$/.test(inputStr);
		},
		isMobile: function(inputStr) {
			return /^0?1(3|5){1}\d{9}$/.test(inputStr);
		},
		isNumber: function(inputStr) {
			return /^\d+$/.test(inputStr);
		},
		keyNonNumber: function(kcode) {/*按下的键非数字*/
			return kcode < 48 || kcode > 57;
		},
		keyIsGeneral: function(e) {/*四个方向键，删除键，退格键*/
			var kcode = e.keyCode;
			return e.charCode != 46 && ((kcode >= 37 && kcode <= 40) || kcode == 8 || kcode == 46);
		}
    };
		
	/**
     *页面元素验证类
     */
    function formValidation(errImg){
        this.init(errImg);
    }
    
    /**
     *为此类的实例添加属性及方法
     */
    formValidation.prototype = {
        validator: [],/*需验证对象数组*/
        clsName: 'err_message',/*错误样式*/
        errImg: 'images/chkerr.gif',/*错误图标*/
        init: function(errImg) {/*初始化*/
			if (errImg)
				this.errImg = errImg;
            this.appendCss();
        },
        appendCss: function() {/*在页面头部添加样式*/
            var _errRule = this.clsName + '{background-color: #FFFF99;background-repeat: no-repeat;background-position: left center;padding: 4px;line-height: 150%;font-size: 12px;color: #000000;}';
            styleUtil.appendCss(_errRule);
        },
        /**
         *el:被验证的元素
         *errel:显示错误消息的元素
         *errmsg:错误消息
         *func:用于判断的函数
         */
        reg: function(opt) {
            this.validator.push(opt);
            this.seterr(opt);
        },
        seterr: function(opt) {/*设置错误消息*/
            var errel = $(opt.errel);
            errel.style.display = 'none';
            errel.className = this.clsName;
            var errmsg = document.createTextNode(opt.errmsg || errel.innerHTML);
            errel.innerHTML = '';/*先清空显示错误信息的元素的内容*/
            errel.appendChild(this.createImg());
            errel.appendChild(errmsg);
        },
        validate: function() {/*开始验证*/
            var isValid = true;/*默认全部验证通过*/
            for (var i = 0, l = this.validator.length, isFirst = true; i < l; i++) {
                var errel = $(this.validator[i].errel);
                if (this.validator[i].func && this.validator[i].func()) {
                    errel.style.display = 'block';/*显示错误信息元素*/
                    if (isFirst) {
                        var fel = $(this.validator[i].el);
                        if ((fel.focus && fel.focus()) ||
                            (fel.Focus && fel.Focus())){}
                        isFirst = false;
                    }
                    if (isValid)
                        isValid = false;/*验证失败，只要有一个验证失败*/
                } else {
                    errel.style.display = 'none';/*隐藏错误信息元素*/
                }
            }
            return isValid;
        },
        createImg: function() {/*创建图片*/
            var img = DomUtil.createEl('img');
            img.src = this.errImg;
            return img;
        }
    };
    
    function tableSorter(opt) {
		this.init(opt);
	}

	tableSorter.prototype = {
		/**
		 *opt参数：{el:表格id，
		 *sortRows:要排序的列,sortcallback:排序后执行的函数}
		 */
		init: function(opt) {
			this.el = $(opt.el);//表格
			this.sortcallback = opt.sortcallback;
			this.sortRows = opt.sortRows;
			this.orderRule = [];//各列的排序方向：升序、倒序
			this.bindEvents();
		},
		bindEvents: function() {
			this.rows = $toArray(this.el.tBodies[0].rows);
			this.ths = this.el.tHead ? this.el.tHead.rows[0].cells : this.rows.shift().cells;/*表格没有定义thead就取第一行*/
			
			var l = this.sortRows ? this.sortRows.length : this.ths.length;/*不指定要排序的列则默认所有列排序*/
			
			if (this.sortRows)
				if (!this.ths[this.sortRows[l - 1]])
					throw new Error('index out of range');/*列不存在*/
					
			for (var i = 0, current = null, rowIndex = -1; i < l; i++) {
				rowIndex = this.sortRows ? this.sortRows[i] : i;
				current = this.ths[rowIndex];
				current.onclick = this.getFunc(this, 'sort', rowIndex);
				current.style.cursor = 'pointer';
				this.orderRule[rowIndex] = false;/*默认倒序*/
			}
		},
		getFunc: function(variable, method, param) {
			return function() {
				variable[method](param);
			}
		},
		sort: function(rowIndex) {
			var me = this;
			this.rows = this.rows.sort(function(a, b) {
				a = a.cells[rowIndex].innerHTML;/*列内容*/
				b =  b.cells[rowIndex].innerHTML;
				a = isNaN(a) ? a : parseFloat(a);/*判断是否为数字再决定转换*/
				b = isNaN(b) ? b : parseFloat(b);
				var order = a < b;
				if (me.orderRule[rowIndex])
					order = !order;/*与本列上一次排序方向相反*/
				return order ? 1 : -1;
			});
			
			this.addStyle(rowIndex);
			this.lastSorted = this.ths[rowIndex];/*设置最后一次被排序的列为当前列*/
			this.orderRule[rowIndex] = !this.orderRule[rowIndex];/*改变下次本列排序方向*/
			
			var _frag = document.createDocumentFragment();/*创建文档碎片，这样只需调用一次appendChild*/
			for (var i = 0, l = this.rows.length; i < l; i++)
				_frag.appendChild(this.rows[i]);
			this.el.tBodies[0].appendChild(_frag);/*此时的appendChild只是移动原有行位置*/
			
			if (this.sortcallback)
				this.sortcallback(this.ths[rowIndex], this.orderRule[rowIndex]);
		},
		addStyle: function(rowIndex) {
			if (this.lastSorted)
				this.lastSorted.style.background = '';/*清除最后一次被点击的(标题列？)样式*/
			this.ths[rowIndex].style.background = this.orderRule[rowIndex] ? 'red' : 'blue';
		}
	};
	
	function textScroll(el, options) {/*文字滚动效果*/
		this.el = $(el);
		options = options || textScroll.options;
		for (var i in options) {
			this[i] = options[i];
		}
		
		this.init();
	}

	textScroll.options = {
		Delay: 30,/*间隔*/
		LineHeight: 60,/*可滚动的最大高度*/
		Amount: 1,/*每次滚动长度*/
		DirUp: true,/*向上滚动？*/
		Timeout: 1500,/*间歇滚动间隔*/
		hasPause: true,/*是否间歇滚动*/
		autoStart: true
	};

	textScroll.prototype = {
		/**
		 *事件绑定，将el的evt事件绑定到obj对象的fun方法
		 *el: HTMLElement对象
		 *evt: 绑定的事件
		 *obj: 对象
		 *fun:　方法
		 */
		bind: function(el, evt, obj, fun) {
			el[evt] = function() {
				obj[fun]();
			};
		},
		/**
		 *设置定时器，使用间歇滚动的情况下使用setTimeout，平滑滚动使用setInterval
		 *obj: 对象
		 *fun: 方法
		 *ms: 定时间间隔
		 */
		setTimer: function(obj, fun, ms) {
			return (this.hasPause ? setTimeout : setInterval)(function() {
				obj[fun]();
			}, ms);
		},
		/**
		 *对象初始化函数
		 */
		init: function() {				
			this.cloneChilds(this.el);
			this.bind(this.el, "onmouseover", this, "stop");/*鼠标悬停，停止滚动*/
			this.bind(this.el, "onmouseout", this, "start");/*鼠标移开，开始滚动*/
			if (this.autoStart)/*是否自动开始，即外部无需再调用start方法*/
				this.start();
		},
		cloneChilds: function(el) {/*拷贝所有的子节点添加到容器上*/
			/*var dfr = document.createDocumentFragment();
			for (var i = 0, l = el.childNodes.length; i < l; i++) {
				dfr.appendChild(el.childNodes[i].cloneNode(true));
			}
			el.appendChild(dfr);*/
			el.innerHTML += el.innerHTML;/*关键*/
		},
		autoScroll: function() {
			if(this.DirUp) {
				if(this.el.scrollTop >= this.el.scrollHeight / 2){
					this.el.scrollTop = 0;
				}
				this.el.scrollTop += this.Amount;
			} else {
				if(this.el.scrollTop <= 0)
					this.el.scrollTop = this.el.scrollHeight / 2;
				this.el.scrollTop -= this.Amount;
			}
			
			if (this.hasPause) {
				var delay = (parseInt(this.el.scrollTop) % this.LineHeight != 0) ? this.Delay : this.Timeout;
				this.autoTimer = this.setTimer(this, "autoScroll", delay);
			}
		},
		start: function() {
			this.stop();
			this.autoTimer = this.setTimer(this, "autoScroll", this.Delay);
		},
		stop: function() {
			(this.isPause ? clearTimeout : clearInterval)(this.autoTimer);/*清除定时器*/
		},
		scrollUp: function() {
			this.stop();
			this.DirUp = true;/*向上滚动*/
			this.start();
		},
		scrollDown: function() {
			this.stop();
			this.DirUp = false;/*向下滚动*/
			this.start();
		}
	};

	function tabSwitcher(elArray) {
		if (elArray.constructor != Array || elArray.length < 2)
			throw new Error('类型不匹配');
		this.elArray = elArray;
		for (var i = 0; i < elArray.length; i++) {
			elArray[i].tab = $(elArray[i].tab);
			elArray[i].div = $(elArray[i].div);
			if (elArray[i].tab && elArray[i].div) {
				elArray[i].tab.onmouseover = this.setTab(this, i);
			}
		}
		this._index = 0;
		this._last = elArray[0];
	}

	tabSwitcher.prototype = {
		toggleClass: function(active, inactive) {
            var tmp = active;
            active.tab.className = inactive.tab.className;
            styleUtil.setStyle(active, inactive.style);
            inactive.tab.className = tmp.tab.className;
            styleUtil.setStyle(inactive, tmp.style);     
            tmp = null;
		},
		setTab: function(me, _index) {
			return function() {
				if (me._index != _index) {
					if (me._last) {
						styleUtil.toggleDisplay(me._last.div);
					}
                    styleUtil.toggleDisplay(me.elArray[_index].div);
					me.toggleClass(me.elArray[_index], me._last);
					me._last = me.elArray[_index];
					me._index = _index;
				}
			}
		}
	};

	var selectUtil = {
        originOption: DomUtil.createEl('option'),
		/**
		 *<%-- 
		 *把json对象绑定到select上，以动态创建option的形式
		 *el: HTMLSelectElement
		 *proSortArray: proSort对象数组
		 *tField：即option显示的文本使用的json的属性
		 *vFild：即option显示的值（value）使用的json的属性
		 *setlength：设置select的option个数，不传则默认为0，即清空select的option
		 *--%>
		 */
		bindOptions: function(el, proSortArray, tField, vField, setlength) {
			el.length = setlength || 0;
			if (proSortArray != null) {
				var frag = document.createDocumentFragment();
				for (var i = 0, l = proSortArray.length; i < l; i++) {
					var newOpt = selectUtil.createOption(proSortArray[i][tField], proSortArray[i][vField]);
					frag.appendChild(newOpt);
				}
				el.appendChild(frag);
			}
		},

		/**
		 *创建option并返回它
		 *text：option显示的文本
		 *value：option的值(value)
		 */
		createOption: function(text, value) {
			/*var newOpt = document.createElement('option')
			var oText = /*document.createTextNode(text)*/
			var newOpt = selectUtil.originOption.cloneNode(true);/*克隆方法比创建新的速度快*/
			newOpt.value = value;
			newOpt.text = text;
			return newOpt;
		},
		
		searchOption: function(sel, svalue) {
			for (var i = 0; i < sel.length; i++) {
				if (sel[i].value == svalue)
					return { result: true, index: i };
			}
			return false;
		}
	};
	selectUtil.originOption.appendChild(document.createTextNode(''));

	function AjaxHelper(_url, _data, _callback, _isget, _isJson) {
		if (arguments.length == 1 && typeof arguments[0] == 'object')
			return this.request(arguments[0]);
		else
			return this.request({
				url: _url,
				data: _data,
				callback: _callback,				        
				isget: _isget,
				isJson: _isJson
			});
	}

	AjaxHelper.create = function(_url, _data, _callback, _isget, _isJson) {
		return new AjaxHelper(_url, _data, _callback, _isget, _isJson);
	}

	AjaxHelper.each = function( object, callback, args ) {
		if ( args ) {
			if ( object.length == undefined ) {
				for ( var name in object )
					if ( callback.apply( object[ name ], args ) === false )
						break;
			} else
				for ( var i = 0, length = object.length; i < length; i++ )
					if ( callback.apply( object[ i ], args ) === false )
						break;

		// A special, fast, case for the most common use of each
		} else {
			if ( object.length == undefined ) {
				for ( var name in object )
					if ( callback.call( object[ name ], name, object[ name ] ) === false )
						break;
			} else
				for ( var i = 0, length = object.length, value = object[0]; 
					i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
		}

		return object;
	};
		
	AjaxHelper.prototype = {
		createXMLHttp: function() {
			if(window.XMLHttpRequest){
				return new XMLHttpRequest();
			} else if(window.ActiveXObject){
				return new ActiveXObject('Microsoft.XMLHTTP');
			} 
			throw new Error('XMLHttp object could be created.');
		},
		// Serialize an array of form elements or a set of
		// key/values into a query string
		param: function( a ) {
			var s = [];

			// If an array was passed in, assume that it is an array
			// of form elements
			if ( a.constructor == Array )
				// Serialize the form elements
				AjaxHelper.each( a, function(){
					s.push( encodeURIComponent(this.name) + '=' + encodeURIComponent( this.value ) );
				});

			// Otherwise, assume that it's an object of key/value pairs
			else
				// Serialize the key/values
				for ( var j in a )
					// If the value is an array then the key names need to be repeated
					if ( a[j] && a[j].constructor == Array )
						AjaxHelper.each( a[j], function(){
							s.push( encodeURIComponent(j) + '=' + encodeURIComponent( this ) );
						});
					else
						s.push( encodeURIComponent(j) + '=' + encodeURIComponent( a[j] ) );

			// Return the resulting serialization
			return s.join('&').replace(/%20/g, '+');
		},
		sendMethod: ['POST', 'GET'],
		request: function(option) {
			if (!option.url) return;
			if (!this.xhr)
				this.xhr = this.createXMLHttp();
			var xhr = this.xhr;
					
			var method = this.sendMethod[option.isget ? 1 : 0];
						
			xhr.onreadystatechange = function(){
				if(xhr.readyState == 4){
					if (xhr.status == 200) {
						if (option.isJson)
							option.callback(eval('(' + xhr.responseText + ')'), xhr.status, xhr);
						else
							option.callback(xhr.responseText, xhr.status, xhr);
					}
				}
			}
			
			try {
				var data = this.param(option.data);
				var url = option.url;
				if (option.isget) {					
					url += (option.url.indexOf('?') != -1 ? '&' : '?') + 
						(data && data.length > 0 ? data + '&' : '') + (+new Date);
				}
				
				xhr.open(method, url, true);
				xhr.setRequestHeader('Content-Length', data.length);
				xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
				xhr.send(data);
			} catch (e) {
				if (option.callback)
					option.callback(xhr, xhr.status, e);
			}
		},
		abort: function() {
			this.xhr && this.xhr.abort();
		}
	};

    /*Drag*/
    var Class = {
        create: function() {
            return function() { this.initialize.apply(this, arguments); }
        }
    }

    var Extend = function(destination, source) {
        for (var property in source) {
            destination[property] = source[property];
        }
    }

    var Bind = function(object, fun) {
        return function() {
            return fun.apply(object, arguments);
        }
    }

    var BindAsEventListener = function(object, fun) {
        return function(event) {
            return fun.call(object, (event || window.event));
        }
    }

    var SimpleDrag = Class.create();
    SimpleDrag.prototype = {
      initialize: function(drag) {
        this.Drag = $(drag);
        this._x = this._y = 0;
        this._fM = BindAsEventListener(this, this.Move);
        this._fS = Bind(this, this.Stop);
        this.Drag.style.position = "absolute";
        addEvent(this.Drag, "mousedown", BindAsEventListener(this, this.Start));
      },
      Start: function(oEvent) {
        this._x = oEvent.clientX - this.Drag.offsetLeft;
        this._y = oEvent.clientY - this.Drag.offsetTop;
        addEvent(document, "mousemove", this._fM);
        addEvent(document, "mouseup", this._fS);
      },
      Move: function(oEvent) {
        this.Drag.style.left = oEvent.clientX - this._x + "px";
        this.Drag.style.top = oEvent.clientY - this._y + "px";
      },
      Stop: function() {
        removeEvent(document, "mousemove", this._fM);
        removeEvent(document, "mouseup", this._fS);
      }
    };
    /*Drag*/

	function setOpacity(el, from, option) {
        el = $(el);
        option = option || {};
        var speed = option.speed || 10, duration = option.duration || 5, to = option.to || (from == 0 ? 100 : 0), isAdd = from < to;        
        el.style.opacity = from / 100;
        if (el.filters) el.style.filter = 'alpha(opacity = ' + from + ')';
        
        var opTime = setInterval(function() {
            if ((isAdd && from < to) || (!isAdd && from > to)) {
                from += isAdd ? duration : -duration;
                from = parseInt(from);
                console.log(from, to, isAdd, duration);
                el.style.opacity = from / 100;
                if (el.filters) el.style.filter = 'alpha(opacity = ' + from + ')';
            } else {
                clearInterval(opTime);
            }
        }, speed);
	}
	
	window.zzz = {
		'$Ver': '100',
		'$Date': '2008-09-19',
		'$Desc': '\u5C0F\u660E',
		'$': $,
		'$tag': $tag,
		'$toArray': $toArray,		
		'tableSorter': tableSorter,
		'eventUtil': eventUtil,
		'DomUtil': DomUtil,
		'dialogUtil': dialogUtil,
		'styleUtil': styleUtil,
		'cookieUtil': cookieUtil,
		'stringUtil': stringUtil,
		'validators': validators,
		'formValidation': formValidation,
		'textScroll': textScroll,
		'tabSwitcher': tabSwitcher,
		'selectUtil': selectUtil,
		'AjaxHelper': AjaxHelper,
		'Drag': SimpleDrag,
		'setOpacity': setOpacity
	};
})();