/**************************************************************************/
/* JavaScript XMLHttpRequest                                              */
/* Programed By HGX Start From 2007-05-29                                 */
/* Last Modify Date:2007-06-04                                            */
/* Email:hgx127@163.com                                                   */
/**************************************************************************/
var ajax=buildCls();
ajax.prototype={
	initial:function(model){
		this.runModel             = (model)?model:'instead';
		this.nowPkg               = null;
		this.flushSpan            = 0.1;
		this.rollSpan             = 60;
		this.onRequest            = new Function(),
		this.onSuccess            = new Function(),
		this.onFailure            = new Function(),
		this.XHR                  = this.getXHR();
		this.autoExec             = buildCls();
		this.autoExec.prototype   = autoExec.prototype;
	},
	getXHR:function(){
		var XHR;
		var vers=["MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"];
		try{
			XHR=new XMLHttpRequest();
			if(XHR.overrideMimeType) XHR.overrideMimeType("text/xml");
		}catch(e){
			for(var i=0;i<vers.length;i++){
				try{
					XHR=new ActiveXObject(vers[i]);
					break;
				}
				catch(ex){}
			}
		}finally{return XHR||false};
	},
	package:function(pkg){
		var npk={
			encoding    : 'utf-8',
			method      : 'get',
			async       : true,
			data        : null,
			startAt     : 0,
			runTime     : 0,
			isWaiting   : false,
			callback    : new Function(),
			getMsg      : function(){var rp=[];for(var i in this){rp.push([i,this[i]])}return rp;}
		};
		if(!pkg||typeof(pkg)!="object") return npk;
		npk=extend(npk,pkg);
		return npk;
	},
	get:function(pkg){
		pkg=this.package(pkg);
		pkg.method='get';
		pkg.url=pkg.data?pkg.url+'?'+pkg.data:pkg.url;
		pkg.data=null;
		this.send(pkg);
	},
	post:function(pkg){pkg=this.package(pkg);pkg.method='post';this.send(pkg);},
	send:function(pkg){
		if(!this.XHR||!pkg) return;
		switch(this.runModel.toLowerCase()){
			case 'ordered':
				if(!this.interval)
					this.interval=new this.autoExec(buildFunc(this,'rollerOrdered'),this.flushSpan);
				if(pkg.isWaiting){
					if(this.isprocessing()){this.$catch.addFirst(pkg);return;}
				}else{this.$catch.addLast(pkg);return;}
				break;
			case 'interrupt':
				if(!this.interval) this.interval=new this.autoExec(buildFunc(this,'rollerInterrupt'),this.flushSpan);
				if(!pkg.isWaiting||this.isprocessing()){this.$catch.addLast(pkg);return;}
				break;
			case 'instead':
				if(this.isprocessing()) this.XHR.abort();
				break;
			case 'rolling':
				if(!this.interval) this.interval=new this.autoExec(buildFunc(this,'rollerRolling'),pkg.timeSpan?pkg.timeSpan:this.rollSpan);
				if(!pkg.isWaiting){this.$catch.addLast(pkg);return;}
				if(this.isprocessing()) return;
				break;
			default: return;
		}
		pkg.startAt=this.$T();
		this.nowPkg=pkg;
		this.XHR.open(pkg.method,pkg.url,pkg.async);
		if(pkg.method=='post') this.setHeaders('content-type','application/x-www-form-urlencoded;charset='+pkg.encoding);
		else this.setHeaders();
		this.XHR.onreadystatechange=buildFunc(this,'onReadyStateChange');
		this.XHR.send(pkg.data);
		this.onRequest.apply(this);
	},
	rollerOrdered:function(){
		var pkg=this.$catch.getFirst();
		if(!pkg){this.interval.stop();this.interval=null;return;}
		pkg.isWaiting=true;
		this.send(pkg);
	},
	rollerInterrupt:function(){
		var pkg=this.$catch.getLast();
		if(!pkg){this.interval.stop();this.interval=null;return;}
		pkg.isWaiting=true;
		this.send(pkg);
	},
	rollerRolling:function(){
		var pkg=this.$catch.remainLast();
		if(!pkg){this.interval.stop();this.interval=null;return;}
		pkg.isWaiting=true;
		this.send(pkg);
	},
	onReadyStateChange:function(){
		var pkg=this.nowPkg,xhr=this.XHR;
		if(xhr.readyState==4){
			if(xhr.status>=200&&xhr.status<300){
				pkg.callback.apply(this);
				this.onSuccess.apply(this);
				pkg.runTime=this.$T()-pkg.startAt;
			}else{
				this.onFailure.apply(this);
			}
		}
	},
	debugSend:function(pkg){
		var f=document.createElement("form"),fitem;
		f.setAttribute('name','debugForm');
		f.setAttribute('target','_blank');
		f.setAttribute('method',pkg.method?pkg.method:'post');
		f.setAttribute('action',pkg.url);
		var data=pkg.data.split('\&');
		for(var i=0;i<data.length;i++){
			fitem=document.createElement('input');
			fitem.setAttribute('type','hidden');
			fitem.setAttribute('name',data[i].split('\=')[0]);
			fitem.setAttribute('value',decodeURIComponent(data[i].split('\=')[1]));
			f.appendChild(fitem);
		}
		(document.body||document.documentElement).appendChild(f);
		f.submit();
	},
	$T:function(){return (new Date()).getTime();},
	isprocessing:function(){return(this.XHR.readyState!=0&&this.XHR.readyState!=4);},
	headers:{'X-Requested-With':'HGX-XMLHTTPRequest','Accept':'text/javascript,text/html,application/xml,text/xml,*/*'},
	setHeaders:function(hn,hv){
		for(var i in this.headers) this.XHR.setRequestHeader(i,this.headers[i]);
		if(arguments.length==2) this.XHR.setRequestHeader(hn,hv);
	},
	$catch:{
		list:[],
		addFirst:function(pkg){this.list.unshift(pkg);},
		addLast:function(pkg){this.list.push(pkg);},
		getFirst:function(){return this.list.shift();},
		getLast:function(){return this.list.pop();},
		remainLast:function(){
			if(this.length()>1) this.list=[this.getLast()];
			return this.list[0];
		},
		clearAll:function(){
			for(var i in this.list){
				this.list[i]=null;
			}
			list.length=0;
		},
		length:function(){return this.list.length}
	}
};