//HTTPRequest class

//global variable to hold HTTPRequest objects as they need to access themselves globally
HTTPRequest.objects = new Array();

//constructor
function HTTPRequest()
{
	this.id = HTTPRequest.objects.length;
	HTTPRequest.objects[this.id] = this;
	this.object;
	
	this.timeout = 0; //in milliseconds
	this._timeout;
	this._onreturn;
	this._ontimeout;
	this.headers = {};
	this.responseText;
	this.responseXML;
	
	//support for multiple requests TBA
	this.multipleRequests = false;
	this.overrideRequests = false;
}

//NOT USED
//initialise after finished setting up
HTTPRequest.prototype.init = function()
{
	var self = this;

	this.createObject();

}

//tries to create the HTTPRequest object 
HTTPRequest.prototype.createObject = function()
{
	var self = this;
	var object;

	if (HTTPRequest.is_ie)
	{
		try 
		{
			object = new ActiveXObject("Msxml2.XMLHTTP")
		} 
		catch (e) 
		{
			try 
			{
				object = new ActiveXObject("Microsoft.XMLHTTP")
			} 
			catch (E) {}
		}
	}
	else {
		try {
			object = new XMLHttpRequest();
		} 
		catch (e) {}
	}
	
	if (! object)
	{
		this.object = null;
	}
	else
	{
		this.object = object;
		this.object.onreadystatechange = function()
		{
			self.__onreadystatechange();
		}
	}
	
	return this.currentObject();
}

//destroys the current HTTPRequest object
HTTPRequest.prototype.destroyObject = function()
{
	this.object = null;
}

//returns if we have are already have an object to process
HTTPRequest.prototype.currentObject = function()
{
	return (this.object != null);
}

//set a header to pass, will overwrite any previous header of same name
HTTPRequest.prototype.setHeader = function(label, value)
{
	this.headers.push[label] = value;
}

//call a page
HTTPRequest.prototype.open = function(url, content) //, method)
{
	//check if we aren't allowed to override a current request
	if (this.currentObject()) return false;
	
	//need to create a new object
	if (! this.createObject()) return false;
	
	//currently, only valid method I can find is get?? HEAD
	method = "GET";
	
	this.object.open(method, HTTPRequest.URLPreventCache(url), true);

	//add any headers that were set earlier this morning...
	for (label in this.headers)
	{
		this.object.setRequestheader(label, this.headers[label]);
	}
	
	if (this.timeout > 0)
	{
		this._timeout = setTimeout("HTTPRequest.objects["+this.id+"]._ontimeout()", this.timeout);
	}
	
	this.object.send(content);
}

//method has timed out, process error
HTTPRequest.prototype._ontimeout = function()
{
	clearTimeout(this._timeout);
	
	if (! this.currentObject()) return false;
	
	this.object.abort();
	
	if (this.onupdate)
	{
		this.onupdate(null, "Request has timed out");
	}
}

//abort the request
HTTPRequest.prototype.abort = function()
{
	if (! this.currentObject()) return false;
	
	this.object.abort();
	
	this.destroyObject();
}

//handle the retrieving of the information
HTTPRequest.prototype.__onreadystatechange = function()
{
	var error = null;

    //check if loaded
    if (this.object.readyState == 4) 
    {
    	clearTimeout(this._timeout);

        //check if everything went ok
        if (this.object.status == 200) 
        {
    		this.responseText = this.object.responseText;
    		this.responseXML = this.object.responseXML;
        } 
        else 
        {
            error = this.object.statusText;
        }
        
		if (this.onupdate)
		{
			this.onupdate(this.object.responseText, error);
		}
	
		this.destroyObject();
    }
}

//get a response header, can only be done in the onupdate function
HTTPRequest.prototype.getHeader = function(label)
{
	//need to catch anytime someone tries to do this outside the onupdate function
	try
	{
		return this.object.getResponseHeader(label);
	}
	catch(e)
	{
		return false;
	}
}

//IE has some wicked caching issues, so we need to supply unique url each time
HTTPRequest.URLPreventCache = function(url)
{
	return url + (url.match("\\?") ? "&" : "?") + Math.floor(Math.random() * 32);
}

//Browser definition stuff
HTTPRequest.is_ie = !!document.all;

// bk: added js equivalent of php print_r(obj);
function print_r(theObj){
  if(theObj.constructor == Array ||
     theObj.constructor == Object){
    document.write("<ul>")
    for(var p in theObj){
      if(theObj[p].constructor == Array||
         theObj[p].constructor == Object){
document.write("<li>["+p+"] => "+typeof(theObj)+"</li>");
        document.write("<ul>")
        print_r(theObj[p]);
        document.write("</ul>")
      } else {
document.write("<li>["+p+"] => "+theObj[p]+"</li>");
      }
    }
    document.write("</ul>")
  }
}

/**
 * Function : dump()
 * Arguments: The data - array,hash(associative array),object
 *    The level - OPTIONAL
 * Returns  : The textual representation of the array/hash/object.
 * This function was inspired by the print_r function of PHP.
 * This will accept some data as the argument and return a
 * text that will be a more readable version of the
 * array/hash/object that is given.
 * Docs: http://www.openjs.com/scripts/others/dump_function_php_print_r.php
 * usage: alert(dump(assoc));
 * ## This belongs in utilities.js, but that wasn't loaded on the page I needed it..
 */
function dump(arr,level) {
	var dumped_text = "";
	if(!level) level = 0;

	//The padding given at the beginning of the line.
	var level_padding = "";
	for(var j=0;j<level+1;j++) level_padding += "    ";

	if(typeof(arr) == 'object') { //Array/Hashes/Objects
		for(var item in arr) {
			var value = arr[item];

			if(typeof(value) == 'object') { //If it is an array,
				dumped_text += level_padding + "'" + item + "' ...\n";
				dumped_text += dump(value,level+1);
			} else {
				dumped_text += level_padding + "'" + item + "' => \"" + value + "\"\n";
			}
		}
	} else { //Stings/Chars/Numbers etc.
		dumped_text = "===>"+arr+"<===("+typeof(arr)+")";
	}
	return dumped_text;
}
