/*##request*/
function LynxRequest(url, engine){
	if(typeof url != "string"){
		this._init(url);
	  if(engine==undefined)this.makeRequest();
	}else{
		this.type = "POST";
		this.url = url || "";
		this.returnCall = function(){};
		this.params = "";
		this.jsParams = new Array();
		this.async = true;
		this.dataType = 'XML';
		if(engine==undefined || engine=='XHR')this._createXHR();
		else this._createIFRAME(engine);
		this.catBack = false;
	}
}

LynxRequest.prototype.addParam = function(new_param, value){
	new_param = encodeURIComponent(new_param);
	value = encodeURIComponent(value);
	if(this.params.length==0)this.params = new_param+'='+value;
	else this.params += '&'+new_param+'='+value;
}

LynxRequest.prototype.addParams = function(params){
	for(var i=0,len=params.length;i<len;++i){
		this.addParam(params[i][0],params[i][1]);
	}
}

LynxRequest.prototype.addParamsX = function(params){
	for(var name in params){
		if(name.substr(0,1)=='@')this.addParamsX(params[name]);
		else this.addParam(name,params[name]);
	}
}

LynxRequest.prototype.addJsParam = function(new_param){
	this.jsParams.push(new_param);
}

LynxRequest.prototype.addJsParams = function(){
	for(var i=0,len=arguments.length;i<len;++i){
		this.jsParams.push(arguments[i]);
	}
}

LynxRequest.prototype.makeRequest = function(){
	if(this.xhr!=null)this._makeXRequest();
	else if(this.ifr!=null)this._makeIRequest();
	else return false;
}

LynxRequest.prototype.abort = function(){
	if(this.xhr!=null)this.xhr.abort();
	if(this.timeout)clearTimeout(this.timeout);
	this.timeout = null;
}

LynxRequest.prototype._init = function(data){
	this.type = data.type || "POST";
	this.url = data.url || "";
	this.returnCall = data.returnCall || function(){};
	this.params = '';
	if(data.params){
		if(typeof data.params == "string")this.params = data.params;
		else if(data.params.slice)this.addParams(data.params);
		else this.addParamsX(data.params);
	}
	this.jsParams = data.jsParams || [];
	this.async = data.async || true;
	this.dataType = data.dataType || 'XML';
	if(data.engine && data.engine!='XHR')this._createIFRAME(data.engine);
	else this._createXHR();
	this.catBack = data.catBack || false;
}

LynxRequest.prototype._createXHR = function(){
	if(window.XMLHttpRequest){
		this.xhr = new XMLHttpRequest();
		return true;
	}else{
		var ax = ['MSXML2.XMLHTTP.6.0','MSXML2.XMLHTTP.5.0','MSXML2.XMLHTTP.3.0','Microsoft.XMLHTTP'];
		for(var i=0,ei;ei=ax[i];++i){
			try{
				this.xhr = new ActiveXObject(ei);
				return true;
			}catch(e){}//alert("could not instatiate "+ei)}
		}
		this.xhr = null;
		return false;
	}
}

LynxRequest.prototype._createIFRAME = function(xif){
	if(xif){
		this.ifr = xif;
		return true;
	}
	var ifr = makeElement({tag:'iframe'});
	ifr.style.display = 'none';
	$('div','p')[0].appendChild(ifr);
	if(ifr)this.ifr = ifr;
	else this.ifr = null;
}

LynxRequest.prototype._makeXRequest = function(){
	var _me = this;
	if(this.type=='POST'){
		this.xhr.onreadystatechange = function(){ _me._handleXResponse(); };
		this.xhr.open('POST',this.url,this.async);
		this.xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
		this.xhr.setRequestHeader("Content-length", this.params.length);
		this.xhr.setRequestHeader("Connection", "close");
		this.xhr.send(this.params);
	}else if(this.type=='GET'){
		this.timeout = setTimeout(function(){_me._handleXTimeout();},2500);
		this.xhr.onreadystatechange = function(){ _me._handleXResponse(); };
		this.xhr.open('GET',this.url+'?'+this.params,this.async);
		this.xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded;charset=utf-8");
		this.xhr.send("");
	}
}

LynxRequest.prototype._makeIRequest = function(){
	var _me = this;
	var doc = this.ifr.contentWindow.document;
	this.ifr.onload = function(){_me._handleIResponse()};
	ifr.src = this.url+'?'+this.params;
}

LynxRequest.prototype._handleXResponse = function(){
	if(this.xhr.readyState == 4) {
		try{this.xhr.status}catch(e){
			//alert(e+'\n'+this.xhr.responseText);
			return;
		};
    if(this.xhr.status == 200) {
    	clearTimeout(this.timeout);
    	this.timeout = null;
    	if(this.catBack){
    		//alert('response: '+this.xhr.responseText);
    		var serverParams = ''+this.xhr.responseText.match(/\#\{.*\}\#/);
    		serverParams = serverParams.substring(2,serverParams.length-2);
				serverParams = serverParams.split(";");
  			var content = ''+this.xhr.responseText.replace(/\#\{.*\}\#/,"");
  			this.returnCall(content,this.jsParams,serverParams);
			}else if(this.dataType=='XML')this.returnCall(this.xhr.responseXML,this.jsParams);
    	else this.returnCall(this.xhr.responseText,this.jsParams);
    }else {
    	if(this.xhr.status==0)return;
    	switch(this.xhr.status){
    		case 0:
    			return;
    		case 12030:
    			this._handleX12030();
    			return;
    		default:
    			alert('err '+this.xhr.status);
				if(this.xhr.status==404){
						this.abort();
						return;
				}
    	}
    }
  }
}

LynxRequest.prototype._handleIResponse = function(){
	var body = this.ifr.contentWindow.document.body;
	this.returnCall(body,this.jsParams);
}

LynxRequest.prototype._handleXTimeout = function(){
	this.abort();
	var _me = this;
	//if(confirm('timeout, aborted, trying again'))
	this.timeout = setTimeout(function(){_me._makeXRequest();},100);
}

LynxRequest.prototype._handleX12030 = function(){
	this.abort();
	var _me = this;
	//if(confirm('12030, aborted, trying again'))
	this.timeout = setTimeout(function(){_me._makeXRequest();},100);
}

/*##requestManager*/
function LynxRequestManager(){}

LynxRequestManager.prototype.makeRequest = function(data,key){
	if(arguments.length==1)return new LynxRequest(data);
	var _me = this;
	if(this[key]==undefined)this[key] = new Array();
	if(data.returnCall){
		var tmp_func = data.returnCall;
		data.returnCall = function(xml,jsPar){tmp_func(xml,jsPar); _me._call(key);};
	}else data.returnCall = function(){_me._call(key)};
	if(data.makeRequest)this[key].push(data);
	else this[key].push(new LynxRequest(data,true));
	if(this[key].length==1)this._call(key);
}

LynxRequestManager.prototype._call = function(key){
	if(this[key]!=undefined && this[key].length>0)this[key].shift().makeRequest();
}


