//---------------------------------------------------------------------------------------
// 包含JavaScript语言扩展，和每个页面必须的2个静态类Cleanup,Instance
//---------------------------------------------------------------------------------------

//Global object of the whole system
if(typeof Yz=="undefined")
	var Yz={};

//目前系统只考虑兼容IE和Firefox类似的浏览器，因此只定义了这一个全局变量
//来判断浏览器兼容问题，其他的留在以后扩展
Yz.isIE=/*@cc_on!@*/false;
Yz.isOpera=window.opera ? true : false;
Yz.isGecko=navigator.userAgent.match(/gecko\//gi)!=null;

if(Yz.isIE)
{
	Yz.IEVersion=parseFloat(navigator.appVersion.split("MSIE")[1]);
}

//getElementById alias
function $(eltId,doc){return (doc || document).getElementById(eltId);}
//----------------------------------------------------------------------------------------
//Extensions to the JavaScript Core.
//----------------------------------------------------------------------------------------
//{{{
String.prototype.isIn=function(arr)
{
	if(typeof arr=="string")arr=[arr];
	for(var i=0,l=arr.length;i<l;i++)
	{
		if(this==arr[i])return true;
	}
	return false;
}
String.prototype.startsWith=function(val){return (this.substr(0,val.length)==val);},
String.prototype.endsWidth=function(val,ignoreCase)
{
	var L1=this.length,L2=val.length;if(L2>L1)return false;
	if (ignoreCase)
	{
		var re = new RegExp(val+"$","i"); return re.test(this) ;
	}
	return (L2==0 || this.substr(L1-L2, L2)==val);
}
String.prototype.remove=function(startIndex,count)
{
	var s=''; if(startIndex>0)s=this.substring(0,startIndex);
	if(startIndex+count<this.length)
		s+=this.substring(startIndex+count,this.length);
	return s ;
}
//We are not using \s because we don't want "non-breaking spaces to be caught".
String.prototype.trim=function(){return this.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g,"");}
String.prototype.ltrim=function(){return this.replace(/^[ \t\n\r]*/g,"");}
String.prototype.rtrim=function(){return this.replace(/[ \t\n\r]*$/g,"");}
String.prototype.replaceEx=function(regExp,replacement,thisPointer)
{
	if(typeof replacement=="function")
		return this.replace(regExp,
				function()
				{
					return replacement.apply(thisPointer||this,arguments);
				}
			);
	else
		return this.replace(regExp,replacement);
}
String.prototype.isNumeric=function(){return this.match(/^[+-]?\d*[.]?\d*$/gi)!=null;}
String.prototype.isInteger=function(){return this.match(/^[+-]?\d*$/gi)!=null;}
String.prototype.isEmail=function()
{
	return (this.match(/^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/gi)!=null);
}
String.prototype.hasGB=function(){return this.match(/^(.*)([^\x00-\xff])(.*)$/gi)!=null;}
String.prototype.round=function(n){return parseFloat(this).toFixed(n);}
String.prototype.byteLength=function(){return this.replace(/[^\x00-\xff]/gi,'xx').length;}

function parseDate(str)
{
	var r = str.match(/^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2}) (\d{1,2}):(\d{1,2}):(\d{1,2})$/);
		if(r==null)return null; 
	var d = new Date(r[1], r[3]-1,r[4],r[5],r[6],r[7]);
	var v=(d.getFullYear()==r[1]&&(d.getMonth()+1)==r[3]&&d.getDate()==r[4]&&d.getHours()==r[5]&&d.getMinutes()==r[6]&&d.getSeconds()==r[7]);
	if(!v)return null;
	return d;
}

function validateDateTime(str)
{
	if(str.length<=10)str+=" 00:00:00";
	var r = str.match(/^(\d{1,4})(-|\/)(\d{1,2})\2(\d{1,2}) (\d{1,2}):(\d{1,2}):(\d{1,2})$/);
	if(r==null)return false; var d = new Date(r[1], r[3]-1,r[4],r[5],r[6],r[7]);
	var v=(d.getFullYear()==r[1]&&(d.getMonth()+1)==r[3]&&d.getDate()==r[4]&&d.getHours()==r[5]&&d.getMinutes()==r[6]&&d.getSeconds()==r[7]);
	if(!v)return false;
	
	return d;
}

Array.prototype.addItem=function(item)
{
	var i=this.length; this[i]=item; return i ;
}
Array.prototype.indexOf=function(value)
{
	for (var i=0;i<this.length;i++)
	{
		if(this[i]==value)return i;
	}
	return -1 ;
}
Array.prototype.insert = function(val,index)
{
	var arr=this;
	index=parseInt(index);
	if(isNaN(index) || index<0 || index>=arr.length)
	{
		arr.push(val);return arr.length-1;
	}
	if(index==0){arr[0]=val; return 0;}
	arr=arr.slice(0,index-1).concat([val]).concat(arr.slice(index,-1));
	return index;
} 
//}}}
//---------------------------------------------------------------------------------------


//---------------------------------------------------------------------------------------
//最后清理工作的静态类,每个页面都必须包含
//
//注意: 对于可以实例化的非静态类的对象，不要调用 Cleanup.AddItem方法添加对象到清理池，
//		因为在Instance管理类中当实例对象被删除的时候会自动调用对象的FinalRelease方法，
//		只要该类实现了FinalRelease方法，便可以自动进行最后的清理工作.
//		另外,最后清理的顺序是最后添加的对象最先清理.
//---------------------------------------------------------------------------------------
//{{{
var YzCleanup=
{
	queue		: [],
	initialized : false,
	initialize : function(win)
	{
		win=win || window;
		if(win.attachEvent)
			win.attachEvent('onunload',cleanupWorkFunction ) ;		
		else
			win.addEventListener('unload',cleanupWorkFunction,false ) ;
		
		YzCleanup.initialized=true;
	},
	
	add : function(dirtyItem,cleanFunction)
	{
		this.queue.push([dirtyItem,cleanFunction || dirtyItem.dispose]);
	},
	addFF : function(dirtyItem,cleanFunction)
	{
		this.queue.push([dirtyItem,cleanFunction]);
	}
}
Yz.cleanup=YzCleanup;

function cleanupWorkFunction()
{
	//alert(window.top.document.body.innerHTML);
	//try
	//{
		//利用Array.pop方法从数组的最末尾清理，保证Instance的清理工作是最后进行的
		var item=null;
		while((item=YzCleanup.queue.pop()))
		{
			item[1].call(item[0]);
			item[0]=null; item[1]=null;
			item=null; delete item;
		}
		YzCleanup.queue=null;
	//}
	//catch(e){alert(e.message);}
		
	//Util.CollectGarbage();
}
//}}}
//---------------------------------------------------------------------------------------

//---------------------------------------------------------------------------------------
// 管理对象实例的全局静态帮助类.
//
// 对于实例化的JavaScript对象,如果添加到该静态类的实例池中来，在页面结束的时候Instance会
// 自动对象的每个属性设为null,在这之前如果发现对象实现了FinalRelease方法，会自动该方法执
// 行对象自定义的清理动作.
//---------------------------------------------------------------------------------------
var YzInstance=
{
	count : 0,
	pool : {},
	add : function(inst)
	{
		var instId=(inst.getType ? inst.getType() : "")+"_"+Yz.util.newGuid();
		YzInstance.pool[instId]=inst;
		inst.handle=instId;
		YzInstance.count++;
		return instId;
	},
	get : function(instId){return YzInstance.pool[instId];},
	remove : function(instId)
	{
		var inst=YzInstance.pool[instId];
		if(inst)
		{
			if(typeof inst.dispose == "function")
				inst.dispose();
			
			for(var p in inst)inst[p]=null;
			inst.handle=null; inst=null; 
			YzInstance.pool[instId]=null; 
			delete YzInstance.pool[instId];
			
			YzInstance.count--;
		}
	},
	dispose : function()
	{
		for(var p in YzInstance.pool)
		{
			YzInstance.remove(p);
		}
		YzInstance.pool=null;
	}
}
Yz.instance=YzInstance;

//添加到Cleanup的清理队列中去,在这之前Cleanup的清理队列中还没有任何的对象
//基于Cleanup的清理顺序是后进先清理的堆栈式方式，所以Instance的的清理工作
//一定是在最后执行的
Yz.cleanup.add(Yz.instance);

//Request  URI without Filename
//example: URI: 	http://www.example.com/path/to/filename.html
//		   URIPath:	http://www.example.com/path/to/
Yz.URIPath=(function(){
	var url=document.URL;
		url=url.substring(0,url.lastIndexOf("/"))+"/";
		return url;
	})();
	

/*  make sure the ECMAScript 3.0 Number.toFixed() method is available  */
if (typeof Number.prototype.toFixed != "undefined") 
{
	(function(){
	    /*  see http://www.jibbering.com/faq/#FAQ4_6 for details  */
	    function Stretch(Q, L, c) 
	    {
	        var S = Q
	        if (c.length > 0)
	            while (S.length < L)
	                S = c+S;
	        return S;
	    }
	    function StrU(X, M, N) 
	    { 
	    	/* X >= 0.0 */
	        var T, S;
	        S = new String(Math.round(X * Number("1e"+N)));
	        if (S.search && S.search(/\D/) != -1)
	            return ''+X;
	        with (new String(Stretch(S, M+N, '0')))
	            return substring(0, T=(length-N)) + '.' + substring(T);
	    }
	    function Sign(X)
	    {
	        return X < 0 ? '-' : '';
	    }
	    function StrS(X, M, N) 
	    {
	        return Sign(X)+StrU(Math.abs(X), M, N);
	    }
	    Number.prototype.toFixed = function (n) { return StrS(this, 1, n) };
	})();
}