function HttpClient() { }
HttpClient.prototype = {
	// type GET,POST passed to open
	requestType:'GET',
	// when set to true async calls are made
	isAsync:false,

	// where an XMLHttpRequest instance is stored
	xmlhttp:false,

	// what is called when a successful async call is made
	callback:false,

	// what is called when send is called on XMLHttpRequest
	// set your own function to onSend to have a custom loading effect
	onSend:function() {
		document.getElementById('HttpClientStatus').style.display = 'block';
	},

	// what is called when when readyState 4 is reached, this is called before your callback
	onLoad:function() {
		document.getElementById('HttpClientStatus').style.display = 'none';
	},

	// what is called when an http error happens
	onError:function(error) {
		alert(error.message);
	},
	
	// method to initialize an xmlhttpclient
	init:function() {
		try {
		    // Mozilla / Safari
		    this.xmlhttp = new XMLHttpRequest();
		} catch (e) {
			// IE
			var XMLHTTP_IDS = new Array(
			'MSXML2.XMLHTTP.5.0',
			'MSXML2.XMLHTTP.4.0',
			'MSXML2.XMLHTTP.3.0',
			'MSXML2.XMLHTTP',
			'Microsoft.XMLHTTP' );
			var success = false;
			for (var i=0;i < XMLHTTP_IDS.length && !success; i++) {
				try {
					this.xmlhttp = new ActiveXObject(XMLHTTP_IDS[i]);
					success = true;
				} catch (e) {}
			}
			if (!success) {
				throw new Error('Unable to create XMLHttpRequest.');
			}
		}
	},

	// method to make a page request
	// @param string url  The page to make the request too
	// @param string payload  What your sending if this is a POST request
	makeRequest: function(url,payload) {
		if (!this.xmlhttp) {
			this.init();
		}
/*
		try {
			netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
		} catch (e) {
			alert ("Permission UniversalBrowserRead denied.");
		}
*/
		this.url = url;
		try {
			this.xmlhttp.open(this.requestType,url,this.isAsync);
		} catch (e) {
			alert ("HttpClient: " + e + "\nURL '" + url + "'");
			return false;
		}

		// set onreadystatechange here since it will be reset after a completed call in Mozilla
		var self = this;
		this.xmlhttp.onreadystatechange = function() { self._readyStateChangeCallback(); }

		this.xmlhttp.send(payload);

		if (!this.isAsync) {
			return this.xmlhttp.responseXML;
		}

		return true;
	},

	// method to abort a page request
	abortRequest: function() {
		if (this.xmlhttp)
			this.xmlhttp.abort ();
	},	

	// internal method used to handle ready state changes
	_readyStateChangeCallback:function() {
		switch(this.xmlhttp.readyState) {
			case 2:
				this.onSend();
				break;
			case 4:
				this.onLoad();
				if (this.xmlhttp.status == 200) {
					if (this.callback)
						this.callback(this.xmlhttp.responseText);
				}
				else {
					this.onError(new Error('HTTP Error Making Request: ' + 
											this.url + 
											' ['+this.xmlhttp.status+'] '+ 
											this.xmlhttp.statusText));
				}
			break;
		}
	}
}

/******************************************************************************
getBaseDir ()
	Helper to return the base directory on the web site.
******************************************************************************/

function getBaseDir ()
{
	// Get our base directory on the web site.

	var	n = location.pathname.lastIndexOf ('/');

	return n >= 0 ? location.pathname.substr (0, n + 1) : "/";
}

/******************************************************************************
SendToDB (uri, xml, RespFunction, context, uriSrcDir)
	Send or queue data to the database.
******************************************************************************/

	// Create a queue of updates waiting to be sent.

	var	bClientBusy = false;
	var	LastSentRespFunction = null;
	var	LastContext = null;
	var	httpSendQueue = new Array ();

function SendToServer (uri, xml, RespFunction, context, uriSrcDir)
{
	if (!uriSrcDir)
		uriSrcDir = srcdir;

	uri = uriSrcDir + uri;

	if (!bClientBusy)
		DoSendToServer (uri, xml, RespFunction, context);
	else
		httpSendQueue.unshift ([uri, xml, RespFunction, context]);
}

/******************************************************************************
DoSendToServer (uri, xml, RespFunction, context)
	Send data to the database.
******************************************************************************/

	var	httpClient = new HttpClient ();
	var	srcdir = getBaseDir ();

function DoSendToServer (uri, xml, RespFunction, context)
{
	bClientBusy =  true;
	httpClient.isAsync = true;
	httpClient.requestType = 'POST';
	httpClient.callback = DBResponseRcvd;
	LastSentRespFunction = RespFunction;
	LastContext = context;
	httpClient.makeRequest (uri, xml, 'text/xml');
}

/******************************************************************************
DBResponseRcvd (responseText)
	A response was received from the database.
******************************************************************************/

function DBResponseRcvd (responseText)
{
	if (LastSentRespFunction) {

		if (LastContext)
			LastSentRespFunction.call (LastContext, responseText, 
										httpClient.xmlhttp.responseXML);
		else
			LastSentRespFunction (responseText, httpClient.xmlhttp.responseXML);

		LastSentRespFunction = null;
		LastContext = null;
	}

	if (httpSendQueue.length > 0) {
		var	queueinfo = httpSendQueue.pop ();
		DoSendToServer (queueinfo [0], queueinfo [1], queueinfo [2], queueinfo [3]);
	} else
		bClientBusy =  false;
}

