var XMLRequester=new Object();
 
XMLRequester.DOMDocument=null;
XMLRequester.handlers=new Array();
XMLRequester.oXmlHttp=null;
XMLRequester.additionalHeaders=new Array();
XMLRequester.connectorPath="";
XMLRequester.processing=false;
XMLRequester.sendQueue=new Array();
XMLRequester.HTTPReqType = "get";
XMLRequester.POSTReqs = null;

XMLRequester = function() {
	var This=this;
	this.handlers=new Array();
	this.handlers[0]=new Array();
	this.handlers[0][0]="Debug"
	this.handlers[0][1]=This.debugXml;

	this.additionalHeaders=new Array();
	this.additionalHeaders[0]=new Array();
	this.additionalHeaders[0][0]="X-Application";
	this.additionalHeaders[0][1]="e4e-cms";

	this.sendQueue=new Array();

	this.connectorPath="";
	this.processing=false;
}

XMLRequester.prototype.debugXml= function ( xmlData ) {
	alert("Debug XML recieved.");
}


XMLRequester.prototype.registerHandler = function ( command, handler ) {

	for(var i=0;i<this.handlers.length;i++) {
		if (this.handlers[i][0]==command) {
			this.handlers[i][this.handlers[i].length]=handler;
			return;
		}
	}

	var nextIndex=this.handlers.length;
	this.handlers[nextIndex]=new Array();
	this.handlers[nextIndex][0]=command;
	this.handlers[nextIndex][1]=handler;
}


XMLRequester.prototype.getXmlHttpRequest = function() {
	//Gecko Browsers
	if ( window.XMLHttpRequest ) return new XMLHttpRequest() ;

	//Internet Explorer
	else if ( window.ActiveXObject ) return new ActiveXObject("MsXml2.XmlHttp") ;

	else alert("Sorry your web browser is not supported, \nPlease use either a Gecko based browser\n such as Mozilla/Firefox or Internet Explorer.");
}

XMLRequester.prototype.processNext = function() {
	this.processing=false;
	if (this.sendQueue.length>0) {

		//Pop the first element of the array off the top
		var args=this.sendQueue[0];
		for (var i=1; i<this.sendQueue.length; i++) this.sendQueue[i-1]=this.sendQueue[i];
		this.sendQueue.length--;

		var sArgs=""; var sep="";
		for(var i=0;i<args.length;i++) { sArgs=sArgs+sep+"args["+i+"]"; sep="," }
		eval("this.sendRequest("+sArgs+");");
	}
}

XMLRequester.prototype.alertMe = function () {
	alert(''+this.connectorPath);
}

XMLRequester.prototype.sendRequest = function ( command, queryString ) {

	if (this.processing) {
		//Leave the request to be dealt with later
		this.sendQueue[this.sendQueue.length]=arguments;
		return;
	}

	this.processing=true;

	//Get a new XmlHttp request object.
	this.oXmlHttp = this.getXmlHttpRequest();

	//If there is data in the query string argument make sure it is prefixed with &
	if (queryString.length>0 && queryString.substring(0,1)!="&") queryString="&" + queryString;

	//Compose the connector url & request string
	if (arguments.length==3) {
		//Allow a request to something other than the connector
		var connector=arguments[2];
	} else {
		var connector=this.connectorPath+"?Command=";
	}

	var queryURL = connector  + command + queryString

	if (this.HTTPReqType == "post") {
		this.oXmlHttp.open( "POST", queryURL, true);
	} else {
		//Get ready to perform a GET request for the XML response
		this.oXmlHttp.open( "GET", queryURL, true);		
	}

	//Add additional headers if specified
	if (this.additionalHeaders.length>0) {
		for(var i=0;i<this.additionalHeaders.length;i++) {
			if (this.additionalHeaders[i].length==2)
				this.oXmlHttp.setRequestHeader(this.additionalHeaders[i][0],this.additionalHeaders[i][1]);
		}
	}

	//Trick the garbage collector so we can use a reference to this object
	//in the ready state handler.
	var This = this;

	//Add a ready state handler
	this.oXmlHttp.onreadystatechange = function() {

		//When the XmlHttp object has finished
		if ( This.oXmlHttp.readyState == 4 ) {

			//If the response was a 404 (missing file)
			if (This.oXmlHttp.status==404) {
				alert("FATAL: Unable to find an appropriate connector. (404) - " + This.connectorPath);
				This.processNext(); return;
			}

			if (This.oXmlHttp.responseXML==null) {
				alert("Invalid response from the connector, recieved:\n\n" + This.oXmlHttp.responseText + "\n");
				This.processNext(); return;
			}

			//If the response was not a 400 then identify the originating command
			var xmlResponse = new XMLProcessor( This.oXmlHttp.responseXML );
			var connectorNode = xmlResponse.DOMDocument.getElementsByTagName("Connector");
            if ((connectorNode) && (connectorNode.length>0)) connectorNode=connectorNode[0];

			var configNode = xmlResponse.DOMDocument.getElementsByTagName("Config");
            if ((configNode) && (configNode.length>0)) configNode=configNode[0];

			var command=null;

			if (connectorNode!=null) {
				command=connectorNode.attributes.getNamedItem('command').value;
			} else if (configNode!=null) {
				command="Config";
			} else {
				alert("FATAL: Invalid connector response, no connector element found. Recieved:\n\n"+This.oXmlHttp.responseText);
				This.processNext(); return;
			}

			if (command == "" || command == null) {
				alert("FATAL: Unable to determine what the recieved response was for (Connector command attribute missing.)");
				This.processNext(); return;
			} else {
//  				alert(This.oXmlHttp.responseText);
				if (command!="Config") This.processNext();
				//Pass the data to all registered handlers of this message type
				for(var i=0;i<This.handlers.length;i++) {
					if (This.handlers[i][0]==command) {
						for(var j=1;j<This.handlers[i].length;j++) {
							This.handlers[i][j]( xmlResponse );
						}
					}
				}
			}
		}
	}
	this.oXmlHttp.send(this.POSTReqs);
}
