﻿/**
 * @title javascripted page framework - include.js
 * @author huxiaodi(at)gmail.com
 * @date 2009-03-03
 * @desca
 *	prototype extending, cross-browser supportted png wrapper, by regular naming rules,
 *	history fix for IE using iframe,
 *	a eventrouter,
 *	observe the change of the anchor part of the url.
 * @copyright this file is a subset of didyapp javascript framework. author(s) keep all rights received. 
 * while each class or function will have it's own copyright notice to be referer to.
 */

 /**
  * set name-value pair to uri, after "#".
  */
function setUrlParam(name,value){
	var newParams={};
	var oldParams=getUrlParams(top.location.toString());
	for(var key in oldParams){
		newParams[key]=oldParams[key];
	}
	newParams[name]=value;
	var requestString="";
	for(var key in newParams){
		requestString+=key+"="+newParams[key]+"&";
	}
	var uri=top.location.toString().match(/([\s\S]*?)[#]?[\s\S]*/)[1];
	if(requestString.length>1){
		var newUrl=uri+"#"+requestString.substr(0,requestString.length-1);
		top.location=newUrl;
	}
}
 /**
  * get name-value pair from uri, after "#".
  */
function getUrlParam(param){
	return getUrlParams(top.location.toString())[param];
}
 /**
  * parse the uri to name-value pairs array.
  */
function getUrlParams(url){
	try{
		var requestParamString=url.match(/#([\s\S]*)$/)[1];
		var paramPairs=requestParamString.split("&");
		var params={};
		for(var i=0;i<paramPairs.length;i++){
			var paramPair=paramPairs[i].match(/([\s\S]*?)=([\s\S]*?)$/);
			params[paramPair[1]]=paramPair[2];			
		}
		return params;		
	}catch(e){return {}};
}

/**
 * get browser type
 * @return ["old-ie,ie[\d]+,standard];
 */
function getBrowserType(){
	var ua = navigator.userAgent.toLowerCase();
	if (window.ActiveXObject){
		var ver = ua.match(/msie ([\d])/)[1];
		ver=parseInt(ver);
		if(ver<7){
			return "old-ie";
		}else{
			return "ie"+ver;
		}
	}else{
		return "standard";
	}
}
/**
 * get body's offset
 * @return {height:height,width:width}
 */
function getBodySize(){
	var height=document.getElementsByTagName("html")[0].offsetHeight;
	var width=document.getElementsByTagName("html")[0].offsetWeight;
	return {height:height,width:width};
}

/**
 * @title didyapp.fixHistory4IE
 * @author huxiaodi(at)gmail.com
 * @usage
 * 	call "top.fixHistory()" after document onload;
 */
var fixHistory4IE=top.fixHistory4IE=function(){
	if(getBrowserType().indexOf("ie")<0){
		return;
	}
	var historyIframe=fixHistory4IE.historyIframe=document.createElement("iframe");
	
	historyIframe.style.display="none";
	document.body.appendChild(historyIframe);
	fixHistory4IE.cache=[0];
	fixHistory4IE.currentCacheIndex=0;
	fixHistory4IE.getId=function(){
		var id=parseInt(fixHistory4IE.historyIframe.src.match(/id=([\d]*?)&/)[1]);		
		return id;
	}
	fixHistory4IE.pop=function(url){
		with(fixHistory4IE){
			var id=url.match(/id=([\d]*?)&/)[1];			
			if(!isNaN(id) && id!=currentCacheIndex){
			
				var url=cache[id];
				if(url){
					top.location=url;
				}
				currentCacheIndex=id;
			}
		}
		return "ok";
	}
	fixHistory4IE.push=function(url){
		with(fixHistory4IE){
			var id=++currentCacheIndex;
			//alert("<<"+id+":"+url);
			cache[id]=url;
			historyIframe.src="historyIframe.html?id="+id+"&time="+new Date();			
		}
	}
	fixHistory4IE.topUrlObserver=window.setInterval(function(){
		with(fixHistory4IE){
			var latestUrl=cache[currentCacheIndex];
			var currentUrl=top.location.toString();
			if(latestUrl==null || currentUrl!=latestUrl){
				push(currentUrl);
			}
		}
	},10);
}


/**
 * @title didyapp.png
 * @author huxiaodi(at)gmail.com
 * @usage
 * 	<img src="blank.png" onload="png(this,'filename_without_.png',support4IE6,supportMouseover,preload)" title="title" alt="title" />
 *	if sepcify support4IE6=true, and the getBrowerType() returns "old-ie", then the wrapper will load ie6/filename.png;
 *  if sepcify supportMouseover=true, the wrapper will add onmouseover and out listener and attach the file filename_over.png;
 *	if sepcify preload=true or the img tag has a class named 'button', the wrapper will preload mouseover pics, otherwise it will not.
 * configuration:
 * 	define png.baseUrl, the base url of your pictures, "style/L" default;
 */
var png=top.png=function(img,name,support4IE6,supportMouseover,preload){
		png.pngs[png.pngs.length]=[img,name,support4IE6,supportMouseover,preload];
		png.imageRedirect(img,name,support4IE6,supportMouseover,preload);	
}

png.pngs=[];
png.baseUrl="style/L";
png.imageRedirect=function(img,name,support4IE6,mouseover,preload){
		var browserType=getBrowserType();		
		var url,url_over;
		
		if(!!!img.title && img.className.indexOf("button")<0){
			img.title="[Illustration:"+name+"]";			
		}
		if(!!!img.alt && img.className.indexOf("button")<0){			
			img.alt="[Illustration:"+name+"]";
		}
		if(support4IE6 && browserType=="old-ie"){
			url=png.baseUrl+"/ie6/"+name+".png";
			url_over=png.baseUrl+"/ie6/"+name+"_over.png";
		}else{
			url=png.baseUrl+"/"+name+".png";
			url_over=png.baseUrl+"/"+name+"_over.png";
		}
		if(preload || img.className.indexOf("button")>=0){
			new Image().src=url_over;
		}
		img.onload=null;
		img.src=url;
		if(mouseover==true){			
			var obj=img;
			img.onmouseover=function(){ obj.src=url_over};
			img.onmouseout=function(){ obj.src=url};
		}	
}

/**
 *	@title didyapp.urlObserve
 *  @author huxiaodi(at)gmail.com
 *	@desca
 *		to observe the change of the anchor part of the url.
 *	@usage
 *		urlObserve(param,onchange,observer);
 *		onchange is a listener function with parameters (oldValue,newValue);
 */
var urlObserve=top.urlObserve=function(param,onchange,observer,immediately){
	urlObserve.listeners[param]=[onchange,observer];	
	if(immediately && !!urlObserve.cachedParams[param]){
		onchange.call(observer,urlObserve.cachedParams[param],urlObserve.cachedParams[param]);
	}
	urlObserve.observer=urlObserve.observer||window.setInterval(function(){		
	//urlObserve.cachedUrl=urlObserve.cachedUrl||"";
		var url=top.location.toString();
		//if(url=="" || url!=urlObserve.cachedUrl){
			//urlObserve.cachedUrl=url;
			var urlParams=getUrlParams(url);
			for(var key in urlParams){
				var oldValue=urlObserve.cachedParams[key];
				var newValue=urlParams[key];				
				if(oldValue==null || oldValue!=newValue){
					
					if(urlObserve.listeners[key] && typeof urlObserve.listeners[key][0]=="function"){				
						newValue=urlObserve.listeners[key][0].call(urlObserve.listeners[key][1],oldValue,newValue)||newValue;
					
					}
					urlObserve.cachedParams[key]=newValue;
										
				}
			}				
		//}		
	},10);	
}

urlObserve.listeners=urlObserve.listeners||{};
urlObserve.cachedParams=urlObserve.cachedParams||{};
urlObserve.cachedUrl=urlObserve.cachedUrl||"";

/**
 * @title didy.Array
 * @author huxiaodi(at)gmail.com
 */
Array.prototype.clone=function(){
	return [].concat(this);
}
Array.prototype.indexOf=function(obj){
	var result=-1;
	for (var i=0;i<this.length;i++){
		if(this[i]==obj){
			result=i;
			break;
		}
	}
	return result;
};
Array.prototype.contains=function(obj){
	return (this.indexOf(obj)!=-1);
};
Array.prototype.append=function(obj,nodup){
	if(!(nodup && this.contains(obj))){
		this[this.length]=obj;
		return true;
	}
	else{
		return false;
	}
};

Array.prototype.remove=function(obj){
	var index=this.indexOf(obj);
	if(index>-1){
		this.splice(index, 1);
	}
};
Array.prototype.insertBefore=function(obj,index){
	if(isNaN(index) || index<0)
		index=0;
	if(index>this.length)
		index=this.length;
	for(var i=this.length;i>index;i--){
		this[i]=this[i-1];
	}
	this[index]=obj;
};
Array.prototype.removeAt=function(index){
	if(isNaN(index)||index>this.length) return false;
	this.splice(index, 1);
	return true;
};
Array.prototype.clear=function(){
	this.splice(0, this.length);
}
/**
 * @title didy.Hashtable
 * @author huxiaodi(at)gmail.com
 */
var Hashtable=function(){
	this.initialize();
	return this;
};
Hashtable.prototype={
	_keys:null,
	_values:null,
	initialize:function(){
		this._keys=new Array();
		this._values=new Array();
	},
	put:function(key,value){
		this._keys.append(key);
		var index=this._keys.indexOf(key);
		this._values[index]=value;
	},
	remove:function(key){
		var index=this._keys.indexOf(key);
		var value=this._values[index];
		this._keys.remove(key);
		this._values.remove(value);
	},
	get:function(key){
		var index=this._keys.indexOf(key);
		if(index!=-1){
			return this._values[index];
		}
		return null;
	},
	keys:function(){
		return this._keys;
	},
	values:function(){
		return this._values;
	}
}
/**
 * tranform an array-like object to an didy.Array object;
 */
function $A(arrayAble){
	var array=new Array();
	for(var i=0;i<arrayAble.length;i++){
		array.append(arrayAble[i]);
	}
	return array;
}
/**
 * tranform an hashtable-like object to an didy.Hashtable object;
 */
function $H(hashtableAble){
	var hashtable=new Hashtable();
	if(hashtableAble instanceof Hashtable){
		hashtable._keys=hashtableAble._keys.clone();
		hashtable._values=hashtableAble._values.clone();
	}
	else{
		for(var key in hashtableAble){
			var value=hashtableAble[key]
			if(Object.prototype[key] && Object.prototype[key]==value) continue;
			hashtable.put(key,hashtableAble[key]);
		}
	}
	return hashtable;
}

/**
 * @title EventRouter 2.1
 * @author huxiaodi(at)gmail.com
 * @desca an event driven model, can manage native events and cumstomer events, cross-browsers supported.
 */
var ER=top.ER=new Object();
ER.createListener=function(observer,eventHandler,params,runOnce){
	var listener=new Object();
	listener.observer=observer;
	listener.eventHandler=eventHandler;
	listener.params=params;
	listener.runOnce=runOnce;
	listener.subscribe=function(signal){	
		var listener=this;
		ER.subscribe(signal,listener);
	}.bind(listener);
	listener.unsubscribe=function(signal){	
		var listener=this;
		ER.unsubscribe(signal,listener);
	}.bind(listener);
	return listener;
};

ER.addListener=function(eventSource,eventTypes,listener){
	if(typeof eventTypes!="string") return;
	var observer=listener.observer;
	var router=null;
	if(typeof eventSource.router=="undefined" || eventSource.router==null){
		eventSource.router=new Hashtable();
	}
	router=eventSource.router;
	eventTypes=eventTypes.split(/,/g);
	var eventCallBackFunc=ER.createEventCallBackFunc(eventSource);
	listener.eventCallBackFunc=eventCallBackFunc;
	for(var i=0;i<eventTypes.length;i++){
		var eventType=eventTypes[i];
		var list=null;
		if(router.get(eventType)==null){
			list=new Array();
			router.put(eventType,list);
			if(eventSource.addEventListener){
				eventSource.addEventListener(eventType.replace(/^on/,""),eventCallBackFunc,false);
			}
			else if(eventSource.attachEvent){
				eventSource.attachEvent("on"+eventType.replace(/^on/,""),eventCallBackFunc);
			}
		}
		else{
			list=router.get(eventType);
		}
		list.append(listener,true);
	}
};
ER.createEventCallBackFunc=function(eventSource){
	return function(event){
		event=event||window.event;
		Event.extend(event);
		ER.triggerFromDom(event,eventSource);
	};
}
ER.triggerFromDom=function(event,eventSource){
	var eventType=null;
	if(event && event.type){
		eventType="on"+event.type.replace(/^on/g,"");
		if(!event.preventDefault){
			event.preventDefault=function(){
				event.returnValue = false;
			};
		}
		if(!event.stopPropagation){
			event.stopPropagation=function(){
				event.cancelBubble = true;
			};
		}
		ER.trigger(eventSource,event,eventType);
	}
};
ER.trigger=function(eventSource,event,eventTypes){
	var router=eventSource.router;
	if(router){
		eventTypes=eventTypes.split(/,/g);
		for(var i=0;i<eventTypes.length;i++){
			var eventType=eventTypes[i];
			var list=router.get(eventType);

			if(list){
				for(var listIndex=0;listIndex<list.length;listIndex++){
					var listener=list[listIndex];

					if(listener){
						var observer=listener.observer;
						var params=listener.params;
						listener.eventHandler.call(observer,event,eventType,observer,eventSource,params);
						if(listener.runOnce){
							ER.removeListener(eventSource,eventType,listener);
						}
					}

				}
			}
		}
	}
};
ER.removeListener=function(eventSource,eventTypes,listener){
	var router=eventSource.router;
	var eventCallBackFunc=listener.eventCallBackFunc;
	if(router){
		eventTypes=eventTypes.split(/,/g);
		for(var i=0;i<eventTypes.length;i++){
			var eventType=eventTypes[i];
			if(!eventType){
				eventSource.router=null;
			}
			else{
				var list=router.get(eventType);
				if(list!=null){
					list.remove(listener);
				}
				if(list==null || list.length==0){
					router.remove(eventType);
					if(eventSource.removeEventListener){
						eventSource.removeEventListener(eventType.replace(/^on/,""),eventCallBackFunc,false);
					}
					else if(eventSource.detachEvent){
						eventSource.detachEvent("on"+eventType.replace(/^on/,""),eventCallBackFunc);
					}
				}
			}
		}
	}
};
ER.subcribe=function(path,listener){
	ER.snp=ER.snp||new Object();
	var router=ER.snp[path]=ER.snp[path]=new Array();
	router[router.length]=listener;
};
ER.unsubscribe=function(path,listener){
	for(var key in ER.snp){
		if(path==key){
			ER.snp[key].remove(listener);
			return;
		}
	}
}
ER.publish=function(path,event){
	var router;
	if(ER.snp && (router=ER.snp[path])){
		for(var i=0;router[i];i++){
			var observer=listener.observer;
			var params=listener.params;
			listener.eventHandler.call(observer,event,eventType,observer,eventSource,params);
			if(listener.runOnce){
				ER.unsubscribe(path,listener);
			}
		}
	}
};
/**
 * prototype extending of Function
 * do something about the closure.
 */
 /**
 * transform a function to a ER listener, used for ER.addListener, ER.subsribe,...
 */
Function.prototype.asListener= function(observer,params,runOnce) {
	var eventHandler = this;
	return  ER.createListener(observer, eventHandler, params, runOnce);
}
/**
 * a typically bind method, bind "this" context and others params to a funciton
 * @return a function
 */
Function.prototype.bind=function(/*thisObject,otherParams*/){
	if(typeof arguments[0]=="undefined") return this;
	var __method = this;
	var args =[].concat($A(arguments));
	var object = arguments[0];
	args.removeAt(0);
	return function() {
		return __method.apply(object, $A(args.concat($A(arguments))));
	}
}

/**
 *
 *
 *
 */
 var Cookies=new Object();
Cookies.enCodeStr=function(str){
	return str;
	var strRtn="";

	for (var i=0;i<str.length;i++){
		strRtn+=str.charCodeAt(i);
		if (i) strRtn+="a"; 
	}
	return strRtn;
};
Cookies.deCodeStr=function(str){
	return str;

	var strArr;
	var strRtn="";

	strArr=str.split("a");

	for (var i=0;i<strArr.length;i++)
		strRtn+=String.fromCharCode(eval(strArr[i]));

	return strRtn;

};
//13701188401 an jun zhi

Cookies.put=function(name,value,expireMinutes){
	if(!expireMinutes){
		expireMinutes=60*24*365*10;
	}
	var exp=new Date();
	exp.setTime(exp.getTime()+expireMinutes*60*1000);
	document.cookie=name+"="+window.escape(Cookies.enCodeStr(value))+" ; expires="+exp.toGMTString()+";";
};
Cookies.get=function(name){
	if (document.cookie.length>0){
		var c_start=document.cookie.indexOf(name + "=");
		if (c_start!=-1){
			c_start=c_start + name.length+1;
			var c_end=document.cookie.indexOf(";",c_start);
			if(c_end==-1){
				c_end=document.cookie.length;
			}
			return Cookies.deCodeStr(unescape(document.cookie.substring(c_start,c_end)));
		}
	}
	return null;
};
