var loadPool=new Array();
var reqList=new Array();
var LIMIT_REQUEST_NUMBER=16;

function Loader(){
	this.md5;
	this.xhr;
}

function aReq(url,fcompl,par,ferr){
	if(reqList.length==LIMIT_REQUEST_NUMBER){
		if(ferr)ferr(599,'Limit request number: '+LIMIT_REQUEST_NUMBER);
		return;
	}
	var _par='';
	if(par){		var par_arr=new Array;
		par_arr=par;
		_par=createEscString(par_arr);
	}else{_par='';}
	var hash=hex_md5(url+_par);
	for(var i=0;i<reqList.length;i++)
		if(reqList[i]==hash){
			if(ferr)ferr(598,'Request process md5: '+hash);
			return;
		}
	var loader=null;
	if(loadPool.length==0){
		loader=getLoader();
	}else{
		loader=loadPool.pop();
	}
	if(loader){
		loader.md5=hash;
		reqList.push(loader.md5);
		loader.xhr.onreadystatechange=function(){
			with(loader.xhr){
				if(readyState==4){
					for(var i=0;i<reqList.length;i++)
						if(reqList[i]==loader.md5){
							reqList.splice(i,1);
							break;
						}
					onreadystatechange=function(){};
						switch(status){
							case 200:
								responseXML.hasChildNodes()?fcompl(responseXML):fcompl(responseText);
								break;
							default:
								ferr?ferr(status,statusText):derr(status,statusText);
								break;
						}
					abort();
					loadPool.push(loader);
				}
			}
		}
	}else{
		if(ferr)ferr(597,'Get loader fail: '+url);
		return;
	}
	loader.xhr.open('POST',url,true);
	loader.xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	loader.xhr.setRequestHeader('Charset', 'windows-1251');
	loader.xhr.send(_par);
}

function sReq(url,fcompl,par,ferr){
	if(reqList.length==LIMIT_REQUEST_NUMBER){
		if(ferr)ferr(599,'Limit request number: '+LIMIT_REQUEST_NUMBER);
		return
	}
	var _par='';
	if(par){
		var par_arr=new Array;
		par_arr=par;
		_par=createEscString(par_arr);
	}else{_par='';}
	var hash=hex_md5(url+_par);
	for(var i=0;i<reqList.length;i++)
		if(reqList[i]==hash){
			if(ferr)ferr(598,'Request process md5: '+hash);
			return
		}
	var loader=null;
	if(loadPool.length==0){
		loader=getLoader();
	}else{
		loader=loadPool.pop();
	}
	if(loader){
		loader.md5=hash;
		reqList.push(loader.md5);
	}else{
		if(ferr)ferr(597,'Get loader fail: '+url);
		return;
	}
	loader.xhr.open('POST',url,false);
	loader.xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
	loader.xhr.setRequestHeader('Charset','windows-1251');
	try{
		loader.xhr.send(_par);
	}catch(err){
		ferr?ferr(0,'Transport error'):derr(0,'Transport error');
		with(loader.xhr){
			for(var i=0;i<reqList.length;i++)
				if(reqList[i]==loader.md5){
					reqList.splice(i,1);
					break;
				}
			abort();
			loadPool.push(loader);
		}
		return;
	}
	with(loader.xhr){
		for(var i=0;i<reqList.length;i++)
			if(reqList[i]==loader.md5){
				reqList.splice(i,1);
				break;
			}
		try{
			switch(status){
				case 200:
					responseXML.hasChildNodes()?fcompl(responseXML):fcompl(responseText);
					break;
				default:
					ferr?ferr(status,statusText):derr(status,statusText);
					break;
			}
		}catch(err){ferr?ferr(0,'Transport error'):derr(0,'Transport error');}
		abort();
		loadPool.push(loader);
	}
}

function derr(num,msg){window.status=num+' '+msg;}

function getLoader(){
	var loader=null;
	var xhr=null;
	if(window.XMLHttpRequest){
		try{xhr=new XMLHttpRequest()}
		catch(e){}
	}else if(window.ActiveXObject){
		try{xhr=new ActiveXObject("Msxml2.XMLHTTP")}
		catch(e){
			try{xhr=new ActiveXObject("Microsoft.XMLHTTP")}
			catch(e){}
		}
	}
	if(xhr){
		loader=new Loader();
		loader.xhr=xhr;
	}
	return loader
}

function createEscString(arr){
	var temp=new Array();
	for(var key in arr){temp[temp.length]=key+'='+escapeToWin1251(arr[key])}
	return temp.join('&');
}

function escapeToWin1251(str){
	/*str=str.replace(/&/g,'%26');
	str=str.replace(/ /g,'%20');
	str=str.replace(/=/g,'%3d');
	str=str.replace(/\+/g,'%2b');
	str=str.replace(/№/g,'%b9');
	str=str.replace(/\;/g,'%3b');
	str=str.replace(/Ё/g,'%a8');
	str=str.replace(/ё/g,'%b8');
	str=str.replace(/©/g,'%a9');
	str=str.replace(/[А-Яа-я]/g,function(symbol){return '%'+Number(symbol.charCodeAt(0)-0x0350).toString(16);});*/
	return str;
}