/* For more information about the XMLHttp object creation below, visit: http://jibbering.com/2002/4/httprequest.html */
function getXMLHttpRequestObject()
{
	var XMLHttp = false;
	/*@cc_on @*/
	/*@if (@_jscript_version >= 5)
	// JScript gives us Conditional compilation, we can cope with old IE versions.
	// and security blocked creation of the objects.
	try {
		XMLHttp = new ActiveXObject("Msxml2.XMLHTTP");
	} catch (e) {
		try {
			XMLHttp = new ActiveXObject("Microsoft.XMLHTTP");
		} catch (E) {
			XMLHttp = false;
		}
	}
	@end @*/
	if (!XMLHttp && !Object.isUndefined(XMLHttpRequest)) {
		XMLHttp = new XMLHttpRequest();
	}
	return XMLHttp;
}

// Makes a (A)synchronous Javascript And XML HTTP request.
// @var url: a fully formed URL
// @options: an object containing any of these values:
// - async: the call should be asynchronous (the function waits for the http request to finish);
//   if this parameter is not defined, the function checks for callback functions; if these are found, async is true, otherwise false
// - method: 'GET' or 'POST' or such; default: 'GET'
// - funcSuccess: a function to be called when the async. request returns with OK; default: false
// - funcFailed: a function to be called when the async. request was aborted or did not return OK; default: false
// - returnType: the response will be returned as 'text' or 'xml'; default: 'text'
// - cache: allow the browser to cache the results: default: false
// - message: the contents of a POST request; may contain the requests variables in this form: number=133&category=16
// - parameters: parameters to be passed to the callback function
// If the function is called sync. the HTTP response will be returned, or false if something went wrong;
// If the function is called async. funcSuccess is called with the response as parameter, or funcFailed is case something went wrong
function ajax(url, options)
{
	var xmlhttp = getXMLHttpRequestObject();
	if (!xmlhttp) return;
	if (!!Object.isUndefined(options)) options = {};

	var method = !Object.isUndefined(options['method']) ? options['method'].toLowerCase() : 'get';
	var funcSuccess = !Object.isUndefined(options['funcSuccess']) ? options['funcSuccess'] : false;
	var funcFailed = !Object.isUndefined(options['funcFailed']) ? options['funcFailed'] : false;
	var returnType = !Object.isUndefined(options['returnType']) ? options['returnType'].toLowerCase() : (method == 'head' ? 'headers' : 'text');
	var cache = !Object.isUndefined(options['cache']) ? options['cache'] : false;
	var message = !Object.isUndefined(options['message']) ? options['message'] : null;
	var parameters = !Object.isUndefined(options['parameters']) ? options['parameters'] : {};
	var async = !Object.isUndefined(options['async']) ? options['async'] : true;

	xmlhttp.open(method, url, async);
	if (!cache) xmlhttp.setRequestHeader("If-Modified-Since", "Wed, 15 Nov 1995 04:58:08 GMT");
	if (method == 'post') xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	if (async) {
		xmlhttp.onreadystatechange = function() {
			if (xmlhttp.readyState == 4) {
				if (xmlhttp.status == 200 && xmlhttp.statusText == "OK" && funcSuccess) {
					if (returnType == 'text') funcSuccess(xmlhttp.responseText, parameters);
					else if (returnType == 'xml') funcSuccess(xmlhttp.responseXML, parameters);
					else if (returnType == 'headers') funcSuccess(ajaxParseHeaders(xmlhttp.getAllResponseHeaders()), parameters);
				} else if (funcFailed) {
					funcFailed(parameters);
				}
			}
		}
		xmlhttp.send(message);
	} else {
		xmlhttp.send(message);
		if (xmlhttp.status == 200 && xmlhttp.statusText == "OK") {
			if (returnType == 'text') return xmlhttp.responseText;
			else if (returnType == 'xml') return xmlhttp.responseXML;
			else if (returnType == 'headers') return ajaxParseHeaders(xmlhttp.getAllResponseHeaders());
		} else {
			return false;
		}
	}
}
// Turns headerString into an associative array of headers (names are turned into lower-case)
function ajaxParseHeaders(headerString)
{
	var lines = headerString.split('\n');
	var headers = new Array();
	for (var i=0; i<lines.length; i++) {
		var line = lines[i];
		var index = line.indexOf(':');
		headers[line.substring(0, index).toLowerCase()] = line.substr(index+1);
	}
	return headers;
}
