
var globalXmlhttp = null;


function relayResponse( obj, data ) {
	if (typeof obj == 'object') {
		// Set the value attribute of an object to the responseText
		obj.value = data;
	}
	else if (typeof obj == 'function') {
		// Call a user defined function and pass it the responseText
		obj(data);
	}
	else if (typeof obj == 'string') {
		// Set an attribute of an object (described by a string) to the responseText (default to the 'value' attribute, if none is specified)
		var e = (obj + '.value').split('.').slice(-3, 2);
		document.getElementsByName(e[0])[0].setAttribute(e[1], data);
	}
}

function createXMLHttpRequest( existingXmlhttp ) {
	if (existingXmlhttp != null)
		return existingXmlhttp;
		
	try {
		// Mozilla, Firefox, Safari, Opera 8.0+, Netscape
		return new XMLHttpRequest();
	}
	catch (e){
		// Internet Explorer Browsers
		try {
			return new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch (e) {
			try {
				return new ActiveXObject("Microsoft.XMLHTTP");
			}
			catch (e) {
				return null; // The browser does not support XMLHTTP
			}
		}
	}
}

// remoteRequest  -  Does an asynchronous HTTP_GET or HTTP_POST
// 	obj  -  Object where the responce should be stored
//			- Can be a javascript function, the response data will be passed as an argument to the function
//			- Can be an html element with a value attribute, the response data will be stored in it's value
//			- Can be a string containing the name of an html element and attribute (i.e. "my_image.src")
//	request  -  The request data in HTTP_GET format
//	post - Indicates if the request should be done as an HTTP_POST (Optional, defaults to false)
function remoteRequest( obj, request, post, async ) {
	if (typeof post == 'undefined')
		post = false;
	if (typeof async == 'undefined')
		async = true;
		
	// It is not thread safe to use a global XMLHttpRequest, although it will usually work just fine
	// At this point we are using a common XMLHttpRequest object for synchronous calls only,
	// which should be OK if all synchronous calls are synchronized.  (Probably not a good assumption.)
	// [Question: So why do it?    Answer: Performance and rumors of memory leaks in some browsers]
	var xmlhttp = createXMLHttpRequest( ((async) ? null : globalXmlhttp) );
	
	if (xmlhttp == null)
		return null; // The browser does not support XMLHTTP
	
	// Create callback function that is triggered by the server
	// It's defined here because we need access to 'obj', which doesn't get passed to the callback
	function xmlhttpStateChange() {
		if (xmlhttp.readyState == 4)
			relayResponse(obj, xmlhttp.responseText);
	}
	
	if (typeof request == 'string') {
		if (post) {
			// Do an http POST
			request = request.split('?');
			xmlhttp.open("POST", request[0], async);
			xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
			xmlhttp.setRequestHeader("Content-length", request[1].length);
			xmlhttp.setRequestHeader("Connection", "close");
			if (async)
				xmlhttp.onreadystatechange = xmlhttpStateChange;
			xmlhttp.send(request[1]);
		}
		else {
			// Do an http GET
			xmlhttp.open("GET", request, async);
			if (async)
				xmlhttp.onreadystatechange = xmlhttpStateChange;
			xmlhttp.send(null);
		}
		
		if ( (!async) && (xmlhttp.status == 200) ) {
			if (obj == null)
				return xmlhttp.responseText;
			else
				relayResponse(obj, xmlhttp.responseText);
		}
	}
	
	return xmlhttp;
}
