var iRemoteProcedure=0;
var tRemoteProcedures={};
function RemoteProcedure(sUrl,fnOnLoad,fnOnPatience,fnOnChange){
	this.req=null;
	this.fnOnLoad=null;
	this.id=++iRemoteProcedure;
	tRemoteProcedures[this.id]=this;
	this.timer=null;
	this.call(sUrl,fnOnLoad,fnOnPatience,fnOnChange);
}
RemoteProcedure.prototype.call=function(url,fnOnLoad,fnOnPatience,fnOnError){
	this.fnOnLoad=fnOnLoad;
	this.fnOnPatience=fnOnPatience;
	this.fnOnError=fnOnError;
	this.timer=window.setTimeout('tRemoteProcedures['+this.id+'].showPatience()',500);
	var sRand=(url.indexOf('?')==-1?'?':'&')+'Rand='+Math.random();
   sRand = (url.indexOf('nocache')==-1?sRand:'');
	if (window.XMLHttpRequest){
		this.req=new XMLHttpRequest();
		this.req.onreadystatechange=new Function('tRemoteProcedures['+this.id+'].processReqChange()');
		this.req.open("GET",url+sRand,true);
		this.req.send(null);
	} else if (window.ActiveXObject){
		this.req=new ActiveXObject("Microsoft.XMLHTTP");
		if (this.req){
			this.req.onreadystatechange=new Function('tRemoteProcedures['+this.id+'].processReqChange()');
			this.req.open("GET",url+sRand,true);
			this.req.send();
		}
	}
}
RemoteProcedure.prototype.showPatience=function(){
	this.clearTimeout();
	if(this.fnOnPatience)
		this.fnOnPatience();
}
RemoteProcedure.prototype.clearTimeout=function(){
	if (this.timer!=null){
		window.clearTimeout(this.timer);
		this.timer=null;
	}
}
RemoteProcedure.prototype.processReqChange=function(){
	if (this.req.readyState==4){ // 4 means "loaded"
		this.clearTimeout();
		if (this.req.status==200){ // 200 means "OK"
			if(this.fnOnLoad)
				this.fnOnLoad(this.req.responseXML);
		}
		else
			if(this.fnOnError)
				this.fnOnError(this);
			else
				alert("Error " + this.req.status + "\n" + this.req.statusText + "\n\n" + this.req.responseText.replace(/\r\n/g,''));
	}
}
function xmlChildNodes(oParent,sChildName){
	var tNodes=[];
	var e=oParent.firstChild;
	while(e!=null){
		if(e.nodeName==sChildName)
			tNodes.push(e);
		e=e.nextSibling;
	}
	return tNodes;
}
function xmlAttributes(oNode){
	var tAttributes={};
	for (var i=0; i<oNode.attributes.length; ++i)
		tAttributes[oNode.attributes.item(i).name]=oNode.attributes.item(i).value;
	return tAttributes;
}