var xmlrequests = new Array();

function registerRequest(reqobj)
{
	xmlrequests[xmlrequests.length] = reqobj;	
	xmlrequests[reqobj.id] = reqobj;
}

/**
 * I had to rename this method. JS was getting confused about which method to call (weird)
 */
function documentReadyForAction(id)
{
	xmlrequests[id].ready();
}

function XmlRequest(callobj, id)
{
	this.id = id;
	registerRequest(this);
	this.callobj = callobj;
	this.xmlreq = this.getXMLRequest();
	this.urlOrForm = null;
	this.querystring = null;
	this.async = true;
}

XmlRequest.prototype.send = function(urlOrForm, querystring, async)
{
	this.urlOrForm = urlOrForm;
	this.querystring = querystring;
	if(async)
	{
		this.async = async;	
	}
	this.sendRequest();
}

XmlRequest.prototype.isReady = function()
{
	return(this.xmlreq && this.xmlreq.readyState == 4);
}

XmlRequest.prototype.ready = function()
{
	if(this.isReady())
	{	
	   this.callobj.documentReady();
	}
}

XmlRequest.prototype.getXMLDocument = function()
{
	return(this.xmlreq.responseXML);
}

XmlRequest.prototype.getText = function()
{
	return(this.xmlreq.responseText);
}

XmlRequest.prototype.sendRequest = function()
{
	if(this.urlOrForm.action) //is html form
	{
		this.xmlreq.open("POST", this.urlOrForm.action, this.async);
		this.xmlreq.setRequestHeader("Method", "POST "+this.urlOrForm.action+" HTTP/1.1");
		this.xmlreq.setRequestHeader("Content-Type",
			"application/x-www-form-urlencoded");
		this.querystring = getQueryStringFromForm(this.urlOrForm);
		//alert(this.querystring);
		this.xmlreq.send(this.querystring);
	}
	else if(this.querystring)
	{
		this.xmlreq.open("POST", this.urlOrForm, this.async);
		this.xmlreq.setRequestHeader("Method", "POST "+this.urlOrForm+" HTTP/1.1");
		this.xmlreq.setRequestHeader("Content-Type",
			"application/x-www-form-urlencoded");
		this.xmlreq.send(querystring);
	}
	else
	{
		this.xmlreq.open("GET", this.urlOrForm, this.async);
		this.xmlreq.send(null);
	}
}

XmlRequest.prototype.getXMLRequest = function()
{
	var xmlreq;	
	
   if(window.XMLHttpRequest)   // branch for native XMLHttpRequest object
   {
		xmlreq = new XMLHttpRequest();
   }
   else if (window.ActiveXObject)  // branch for IE/Windows ActiveX version
   {
      xmlreq = new ActiveXObject("Microsoft.XMLHTTP");
   }
  
   if(xmlreq)
   {
  	   xmlreq.onreadystatechange = new Function("documentReadyForAction('" + this.id + "');");
   }
	else
	{
	  alert("Runway requires a browser with XML support, " +
	          "such as IE5+/Windows, Firefox, Safari or Netscape 6+.");
   }  
	return(xmlreq);
}

function XslRequest(callobj, id)
{
	this.callobj = callobj;	
	this.xmlreq = new XmlRequest(this, id + "__xml");
	this.xslreq = new XmlRequest(this, id + "__xsl");
	this.processedFragment;
}

XslRequest.prototype.send = function(xslurl, xmlurl)
{
	this.xmlreq.send(xmlurl);
	this.xslreq.send(xslurl);
}

XslRequest.prototype.documentReady = function()
{
	if(this.xmlreq.isReady() && this.xslreq.isReady())
	{
		if(window.ActiveXObject)
		{
			this.processedFragment = this.xmlreq.getXMLDocument().transformNode(this.xslreq.getXMLDocument());
		}
		else
		{
      var xsltProcessor = new XSLTProcessor();
      xsltProcessor.importStylesheet(this.xslreq.getXMLDocument());
      this.processedFragment = xsltProcessor.transformToFragment(this.xmlreq.getXMLDocument(), document);
		}
		this.callobj.documentReady();
	}
}

XslRequest.prototype.addFragmentTo = function(eleobj)
{
	if(window.ActiveXObject)
	{
		eleobj.innerHTML = this.processedFragment;
	}
	else
	{
		eleobj.appendChild(this.processedFragment);
	}
}

function getQueryStringFromForm(formobj)
{
	var datastring = new StringBuffer("");
	for(var i=0; i<formobj.elements.length; i++)
	{
		appendInputQuery(datastring, formobj.elements[i]);
	}
	return(datastring.string);
}

function appendInputQuery(buffer, inputobj)
{
	if(inputobj.type)
	{	
		if(inputobj.type == "checkbox" || inputobj.type == "radio")
		{
			if(inputobj.checked) { 
				buffer.appendParameter(inputobj.name, inputobj.value);
			} 
		}		
		else if(inputobj.type == "select-one")
		{
			buffer.appendParameter(inputobj.name, inputobj.options[inputobj.selectedIndex].value);	
		}
		else if(inputobj.type == "select-multiple")
		{
			for(var i=0; i<inputobj.options.length; i++)
			{
				if(inputobj.options[i].selected)
				{
						buffer.appendParameter(inputobj.name, inputobj.options[i].value);
				}
			}
		}
		else
		{
			buffer.appendParameter(inputobj.name, inputobj.value);
		}
	}
}

//Stringbuffer
function StringBuffer(str)
{
	this.string = str;
}

StringBuffer.prototype.appendParameter = function(namestr, valuestr)
{
	if(this.string.length!=0)
	{
		this.string = this.string + "&";
	}
	this.string = this.string + escape(namestr) + 
	"=" +
	escape(valuestr);
}

StringBuffer.prototype.append = function(valuestr)
{
	this.string = this.string + valuestr;
}
