//工具
Object.extend = function(dest, source, replace) {
	for(prop in source) {
		if(replace == false && dest[prop] != null) continue;
		dest[prop] = source[prop];
	}
	return dest;
};
Object.extend(Function.prototype, {
	getArguments: function() {
		var args = [];
		for(var i=0; i<this.arguments.length; i++)
			args.push(this.arguments[i]);
		return args;
	},
	bind: function(o) {
		if(!window.__objs) {
			window.__objs = [];
			window.__funcs = [];
		}

		var objId = o.__oid;
		if(!objId)
			__objs[objId = o.__oid = __objs.length] = o;

		var me = this;
		var funcId = me.__fid;
		if(!funcId)
			__funcs[funcId = me.__fid = __funcs.length] = me;

		if(!o.__closures)
			o.__closures = [];

		var closure = o.__closures[funcId];
		if(closure)
			return closure;

		o = null;
		me = null;

		return __objs[objId].__closures[funcId] = function() {
			return __funcs[funcId].apply(__objs[objId], arguments);
		};
	}
});

var utils={};
utils.common={
	delay:function(time,obj,depth){
		var caller=arguments.callee.caller;
		if(typeof(depth)=='number'){
			while(depth>0){
				caller=caller.arguments.callee.caller;
				depth--;
			}
		}
		var args=caller.arguments;
		return setTimeout(function(){caller.apply(obj,args)},time);
	}
};
utils.html={
	getElementPos:function(elm){//获取元素位置
		var left=elm.offsetLeft,top=elm.offsetTop;
		var parent=elm;
		while(parent=parent.offsetParent){
			left+=parent.offsetLeft;
			top+=parent.offsetTop;
		}
		return {x:left,y:top}
	},
	appendStyle:function(id,file){
		var styleId='styleFile'+id;
		if($g(styleId)) return;
		var style=document.createElement('link');
		style.href=file;
		style.rel='stylesheet';
		style.type='text/css';
		style.id=styleId;
		document.getElementsByTagName('head')[0].appendChild(style);
	},
	addEventListener:function(elm,evtName,evtFun,useCapture){
		if(typeof(elm)=='string')elm=$g(elm);
		if(elm.addEventListener)elm.addEventListener(evtName,evtFun,useCapture);
		else if(elm.attachEvent)elm.attachEvent('on'+evtName,evtFun);
	},
	cancelEvent:function(elm){
		var args=arguments;
		if(args.length<2)return;
		if(typeof(elm)=='string')elm=$g(elm);
		for(var i=1;i<args.length;i++){
			elm['on'+args[i]]=function(evt){evt=evt||window.event;evt.cancelBubble=true;return false;};
		}
	},
	drag:function(objId,srcId){
		var src=null,obj=null;
		if(typeof(objId)=='string') obj=$g(objId);
		else if(typeof(objId)=='object') obj=objId;
		else return;
		if(typeof(srcId)=='string') src=$g(srcId);
		else if(typeof(srcId)=='object') src=srcId;
		else src=obj;
		src.onmousedown=function(evt){
			if(!evt) evt=window.event;
			var d=document;
			var x=evt.clientX-obj.offsetLeft;
			var y=evt.clientY-obj.offsetTop;
			obj.setCapture();
			
			d.onmousemove=function(evt){
				if(!evt) evt=window.event;
				obj.style.left=evt.clientX-x;
				obj.style.top=evt.clientY-y;
			};

			d.onmouseup=function(evt){
				if(!evt) evt=window.event;
				obj.releaseCapture();
				d.onmousemove=null;
				d.onmouseup=null;
			};
		}
	},
	trim:function(str){
		return str.replace(/^[\s　]*|[\s　]*$/,'');
	},
	cleanText:function(obj,state){
		var name='value';
		var name2='_value';
		if(state==1){
			if(!obj[name2]) obj[name2]=obj[name];
			if(obj[name]==obj[name2]) obj[name]='';
		}
		else if(state==0){
			if(this.trim(obj[name])=='') obj[name]=obj[name2];
		}
	},
	swapImages:function(save){
		var arr=arguments;
		for(var i=1;i<arr.length;i=i+2){
			var obj=$(arr[i]);
			if(obj){
				if(save==1)obj._src=obj.src;
				obj.src=arr[i+1];
				if(save==2)obj._src=obj.src;
			}
		}
	},
	restoreImages:function(){
		var arr=arguments;
		for(var i=1;i<arr.length;i++){
			var obj=$(arr[i]);
			if(obj) obj.src=obj._src;
		}
	}
};

utils.web={
	getRequestParameters:function(){
		var url=location.href;
		var queryString='';
		if(url.indexOf('?')!='-1') queryString=url.substring(url.indexOf('?')+1,url.length);
		var arr=queryString.split('&');
		var paramsMap={};
		for(var i=0;i<arr.length;i++){
			var str=arr[i];
			if(!str||str.indexOf('=')==-1) continue;
			var pair=str.split('=');
			var key=pair[0];
			var value=decodeURIComponent(pair[1]);
			if(!paramsMap[key])paramsMap[key]=value;
			else if(typeof(paramsMap[key])=='object')paramsMap[key].push(value);
			else{
				var old=paramsMap[key];
				paramsMap[key]=[];
				paramsMap[key].push(old);
				paramsMap[key].push(value);
			}
		}
		return paramsMap;
	}
};

utils.Validator={
	isEmail:function(value){
		var re=/^\w+@\w+\.\w+$/;
		return this.checkReg(re,value);
	},
	isEmpty:function(value){
		var re=/^\s+$/;
		return this.checkReg(re,value);
	},
	checkReg:function(re,value){
		if(!value) return false;
		if(typeof(value)=='string') return re.test(value);
		else if(typeof(value)=='object'&&value.length){
			for(var i=0;i<value.length;i++) if(!re.test(value[i])) return false;
		}
		return true;
	}
};

utils.FormUtils={
	getObjectValue:function(obj){
		var value='';
		var arr=[];
		for(var item in obj){
			arr.push(item+'='+obj[item]);
		}
		return arr.join('&');
	}
};

utils.UrlManager=function(){
	this.initUrlManager.apply(this,arguments);
};
utils.UrlManager.prototype={
	initUrlManager:function(urlMap,paramMap,appPath){
		this.urlMap=urlMap||{};
		this.paramMap=paramMap||{};
		this.appPath=appPath||'';
	},
	getUrl:function(type,params){
		var url=this.urlMap[type];
		if(!url){
			alert('url error');
			return;
		}
		if(url.charAt(0)=='/') url=this.appPath+url;
		return this.processUrl(url,params);
	},
	processUrl:function(url,params){
		var re=/!{(\w+)}/g;
		params=params||{};
		Object.extend(params,this.paramMap);
		return url.replace(re,function(mstr,m1){return params[m1]});
	},
	setUrlMap:function(urlMap){
		this.urlMap=urlMap;
	},
	setParamMap:function(paramMap){
		this.paramMap=paramMap;
	},
	setAppPath:function(path){
		this.appPath=path;
	}
}

utils.HtmlManager=function(){
	this.initHtmlManager.apply(this,arguments);
};
utils.HtmlManager.prototype={
	initHtmlManager:function(path,name,paramMap){
		this.path=path;
		this.dataMap={};
		this.paramMap=paramMap||{};
		this.status={};
		window.o_htmls={};
		window.o_ui={};
	},
	getHtml:function(module,name,target,paramMap){
		if(this.status[module+'_'+name]=='loading') return false;
		var value=this.setHtml(module,name,paramMap);
		if(value) return value;

		this.status[module+'_'+name]='loading';
		var url=this.path+'/'+module+'.js';
		var caller=arguments.callee.caller;
		var argus=caller.arguments;
		var _this=this;
		if(caller.__HtmlManagerF){
			alert('no data');
			this.status[module+'_'+name]='complete';
			return;
		}
		caller.__HtmlManagerF=true;
		if(this.path.indexOf('http://')==-1)
			postData(url,'',function(value){_this.callback(value,module,name,caller,argus,target,paramMap);},'GET');
		else 
			requestScript(url,function(){_this.callback('{}',module,name,caller,argus,target,paramMap);});
	},
	callback:function(value,module,name,caller,argus,target,paramMap){
		this.status[module+'_'+name]='complete';
		if(!value) return;
		eval(value);
		if(typeof(htmls)!='object') return;
		this.dataMap[module]=o_htmls[module];
		this.setHtml(module,name,paramMap);
		caller.apply(target,argus);
	},
	setHtml:function(module,name,paramMap){
		if(!this.dataMap[module]) return null;
		var value=this.dataMap[module][name];
		var target=$g('html_'+name);
		if(value)value=this.processValue(value,paramMap);
		if(!target) return value;
		if(target.innerHTML!='') return value;//alert('ok');
		target.innerHTML=value;
		return value;
	},
	processValue:function(value,params){
		var re=/!{(\w+)}/g;
		params=params||{};
		Object.extend(params,this.paramMap);
		return value.replace(re,function(mstr,m1){return params[m1]});
	}
};

utils.CookieManager={
	setCookie:function(name,value,expires,path,domain,secure){
		var expStr='';
		if(expires){
			var expDate=new Date();
			expDate.setTime(expDate.getTime()+expires*1000);
			expStr=';expires='+expDate.toGMTString();
		}
		var pathStr=path?';path='+path:'';
		var domainStr=domain?';path='+domain:'';
		var secureStr=secure?';secure':'';
		document.cookie=name+'='+encodeURIComponent(value)+expStr+pathStr+domainStr+secureStr;
	},
	getCookie:function(name){
		var cookie=document.cookie;
		var start=cookie.indexOf(name+'=');
		if(start==-1) return null;
		var end=cookie.indexOf(';',start);
		end=end<0?cookie.length:end;
		return decodeURIComponent(cookie.substring(start+name.length+1,end));
	},
	deleteCookie:function(name){
		var expDate=new Date();
		expDate.setTime(expDate.getTime()-1);
		document.cookie=name+'='+';expires='+expDate.toGMTString();
	},
	getCookies:function(){
		var cookie=document.cookie;
		var arr=cookie?cookie.replace(/;/g,'').split(' '):[];
		var result=[];
		for(var i=0;i<arr.length;i++){
			var str=arr[i];
			var pair=str.split('=');
			result.push({name:pair[0],value:unescape(pair[1])});
		}
		return result;
	}
};

var SearchTip=function(){
	this.initSearchTip.apply(this,arguments);
};
SearchTip.getInstance=function(id){
	return SearchTip.instances[id];
};
SearchTip.instances={};
SearchTip.count=0;
SearchTip.prototype={
	initSearchTip:function(inputObject,url,count,click,option){
		if(inputObject.getAttribute('_searchTip')) return;
		this.inputObject=inputObject;
		this.url=url;
		this.count=count;
		this.click=click;
		this.option=option||{};
		this.delay=1000;
		inputObject._searchTip=1;
		inputObject.autocomplete='off';
		this.id='searchTip'+SearchTip.count++;
		this.itemIdPre=this.id+'_item';
		SearchTip.instances[this.id]=this;
		
		var tip=document.createElement('div');
		tip.className='searchTip';
		style=tip.style;
		style.position='absolute';
		style.zIndex=2000;
		style.fontSize=12;
		//style.border='1px solid #000';
		//style.backgroundColor='#fff';
		style.display='none';
		tip.innerHTML='<div id="'+this.id+'_body" class="body"><div>中国</div><div class="over">中国移动</div></div><div class="close" onclick="SearchTip.getInstance(\''+this.id+'\').hidden()">关闭</div>';
		document.body.appendChild(tip);
		this.body=$g(this.id+'_body');
		this.element=tip;
		this.setPos();
		
		this.currentKeyword='';
		this.keywordCache='';
		this.index='';
		this.list=null;
		this.length=0;
		this.dataHandler=null;
		this.initEvents();
	},
	initEvents:function(){
		var _this=this;
		this.inputObject.onkeyup=function(evt){_this.onchangeE(evt);return true;};
		//this.inputObject.onmousedown=function(evt){evt=evt||window.event;evt.cancelBubble=true;};
		//this.inputObject.onmouseup=function(evt){evt=evt||window.event;evt.cancelBubble=true;};
		this.body.onmouseover=function(evt){_this.overE(evt);return false;};
		this.body.onmousedown=function(evt){_this.clickE(evt);return false;};
		
		var keydownFun=function(evt){_this.keydown(evt);return true};
		if(document.all){
			//window.attachEvent('onkeydown',keydownFun);
			var oldFun=document.onkeydown;
			var newFun=keydownFun;
			if(oldFun)newFun=function(){keydownFun();oldFun();return true}
			document.onkeydown=newFun;
		}
		else{
			window.addEventListener('keydown',keydownFun,false);
		}
	},
	keydown:function(evt){
		if(this.isHidden()) return;
		evt=evt||window.event;
		var keyCode=evt.keyCode;
		switch(keyCode){
			case 38:
				this.up();
				break;
			case 40:
				this.down();
				break;
			default:
				break;
		}
		return true;
	},
	up:function(){
		var index=this.index;
		if(index==''||index=='0') index=this.length-1;
		else{
			index=parseInt(index);
			index--;
		}
		this.overIndex(index);
	},
	down:function(){
		var index=this.index;
		if(index==''||index==(this.length-1)+'') index=0;
		else{
			index=parseInt(index);
			index++;
		}
		this.overIndex(index);
	},
	overE:function(evt){
		evt=evt||window.event;
		var src=evt.srcElement||evt.target;
		this.over(src);
	},
	overIndex:function(index){
		var d=this.list[index];
		var itemObj=$g(this.itemIdPre+index);
		this.inputObject.value=this.filterHtml(d.name);
		this.currentKeyword=this.trim(this.inputObject.value);
		this.over(itemObj);
	},
	over:function(elm){
		if(elm.className=='body') return;
		if(elm.tagName!='DIV') return;
		if(this.index)$g(this.itemIdPre+this.index).className='';
		elm.className='over';
		this.index=elm.id.replace(this.itemIdPre,'');
	},
	clickE:function(evt){
		evt=evt||window.event;
		var src=evt.srcElement||evt.target;
		src=this.getItemObj(src);
		var index=parseInt(src.id.replace(this.itemIdPre,''));
		var d=this.list[index];
		if(this.click){
			this.click(d);
		}
		//this.inputObject.value=d.name;
		this.hidden();
	},
	getItemObj:function(obj){
		if(obj.parentNode==this.body)return obj;
		else{
			while(obj.parentNode!=this.body){
				obj=obj.parentNode;
			}
			return obj;
		}
	},
	show:function(){
		this.element.style.display='';
	},
	hidden:function(){
		this.element.style.display='none';
	},
	isHidden:function(){
		return this.element.style.display=='none';
	},
	onchangeE:function(evt){
		this.putKeyword();
		if(this.timer) return;
		if(this.keywordCache)this.startSearchTimer();
	},
	putKeyword:function(){
		var keyword=this.trim(this.inputObject.value);
		if(this.currentKeyword==keyword) return;
		this.currentKeyword=keyword;
		this.keywordCache=keyword;
	},

	startSearchTimer:function(){
		var _this=this;
		this.timer=setTimeout(function(){_this.search();},this.delay);
	},
	search:function(){
		var keyword=this.keywordCache;
		this.keywordCache=null;
		if(keyword==''){
			this.hidden();
			this.timer=null;
			return;
		}
		
		var url=this.url;
		if(url.indexOf('?')!=-1){
			url+='&keyword='+encodeURIComponent(keyword)+'&count='+this.count;
		}
		var _this=this;
		postData(url,'',function(value){_this.resultBack(value);},'GET');
	},
	resultBack:function(value){
		var list;
		try{
			list=eval(value);
		}
		catch(e){
		}
		list=list||[];
		this.list=list;
		this.length=list.length;
		if(list.length!=0){
			this.createList();
			this.show();
			this.index='';
		}
		else{
			this.hidden();
		}
		if(this.keywordCache!=null) this.startSearchTimer();
		else this.timer=null;
	},
	createList:function(){
		var list=this.list;
		if(this.dataHandler) this.dataHandler(list);
		var frag=document.createDocumentFragment();
		for(var i=0;i<list.length;i++){
			var item=document.createElement('div');
			item.id=this.itemIdPre+i;
			item.innerHTML=list[i].title||list[i].name;
			frag.appendChild(item);
		}
		this.body.innerHTML='';
		this.body.appendChild(frag);
	},
	setDataHandler:function(dataHandler){
		this.dataHandler=dataHandler;
	},
	setPos:function(){
		var pos=this.getPos();
		var style=this.element.style;
		style.left=pos.x+'px';
		style.top=pos.y+'px';
		var width=this.option.width?this.option.width:this.inputObject.offsetWidth-2;
		width=width>=0?width:0;
		style.width=width+'px';
	},
	getPos:function(){
		var inputObj=this.inputObject;
		var left=inputObj.offsetLeft,top=inputObj.offsetTop;
		var parent=inputObj;
		while(parent=parent.offsetParent){
			left+=parent.offsetLeft;
			top+=parent.offsetTop;
		}
		return {x:left,y:top+inputObj.offsetHeight}
	},
	trim:function(str){
		var re=/^\s*|\s*$/ig;
		return str.replace(re,'');
	},
	filterHtml:function(str){
		var re=/<.?.*?>/g;
		return str.replace(re,'');
	}
};


function $g(id){
	return document.getElementById(id);
}
function $(id){
	return document.getElementById(id);
}