var xmlHttp = new Array();
var xmlIDX = new Array(0);
xmlIDX[0] = 1;

function getXmlHttpObject() {
	var xmlsend = xmlIDX.length;
	
	for (var i = 0; i < xmlIDX.length; i++) {
		if (xmlIDX[i] == 1) {
			xmlIDX[i] = 0;
			xmlsend = i;
			break;
		}
	}
	
	xmlIDX[xmlsend] = 0;
	
	try {
		xmlHttp[xmlsend] = new XMLHttpRequest();
	}
	catch (e) {
		try {		
			xmlHttp[xmlsend] = new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch (e) {
			try {
				xmlHttp[xmlsend] = new ActiveXObject("Microsoft.XMLHTTP");	
			}
			catch (e) {
				alert('This page uses functionallity not compatible with this browser, this page may not behave as expected.');
			}
		}
	}
	
	return (xmlsend);
}

function finishRemote(xmli, grdestination, func, passResp) {
	var elem = $(grdestination);
	
	if (elem == null) {
		/*	If it can't find the div under the current hieracy, it loops up through parent nodes
			and then checks all children to cover all elements present on the page. */
		var elemFound = false;
		elem = $(thisid);
		
		if (elem) {
			while (elemFound == false || (elem.id.toLowerCase() != grdestination.toLowerCase())) {			
				for (var cn = 0; cn < elem.childNodes.length; cn++) {					
					var child = elem.childNodes[cn];
					
					if (elemFound == false && child.id != null && child.id != "") {
						if (child.id.toLowerCase() == grdestination.toLowerCase()) {						
							elem = elem.childNodes[cn];
							elemFound = true;
						}
					}
				}
				
				if (elemFound == false) {
					elem = elem.parentNode;
				}
			}
		}
	}
	
	if (elem) {
		elem.innerHTML = xmlHttp[xmli].responseText;
	}
	
	if (func && typeof func == "function") {
		if (passResp) {
			func(xmlHttp[xmli].responseText);
		}
		else {
			func();
		}
	}
	
	xmlIDX[xmli] = 1;
	xmlHttp[xmli] = null;
}

function getAPage(grurl, grdestination, method, params, contenttype, thisid, async, func, passResp) {
	//The boolean async argument determines whether the call is async or not, if set to false
	//then the javascript will wait until the call has completed before continuing, if set to true
	//then the javascript will proceed anyway - in this case you must place the onreadystatechange code in place
	//to know when the call has come back.
	method = method.toUpperCase();
	params = encodeURI(params);
	
	if (method != "POST" && method != "GET") {
		method = "POST";
	}
	
	if (method == "GET") {
		grurl = grurl + "?" + params;
		params = null;
	}
	
	if (!contenttype && method == "POST") {
		contenttype = "application/x-www-form-urlencoded";
	}
	
	//If using Firefox, sending synchronously will not work.
	if (async != true && async != false) {
		async = true;
	}
	
	var xmli = getXmlHttpObject();
	xmlHttp[xmli].open(method, grurl, async);
	
	if (xmlHttp[xmli]) {
		xmlHttp[xmli].open(method, grurl, async);
		
		// I don't know why, but this breaks when I use GET method
		if (method == "POST") {
			if (contenttype) {
				xmlHttp[xmli].setRequestHeader("Content-Type", contenttype);
			}
			else {
				xmlHttp[xmli].setRequestHeader("Content-Type", "text/xml"); 
			}
		}
		
		if (typeof xmlHttp[xmli].overrideMimeType != "undefined") { 
			xmlHttp[xmli].overrideMimeType("text/html"); 
		}
		
		if (async) {
			// This fails for no reason if call is not asynchronous
			xmlHttp[xmli].onreadystatechange = function() {	
				// This bit modified so that it works with Firefox. 
				// Firefox cant see parent div ID's from within dynamically generated DIV content
				if (xmlHttp[xmli].readyState == 4 || xmlHttp[xmli].readyState == "complete") {
					finishRemote(xmli, grdestination, func, passResp);
				}
			}
		}
		
		xmlHttp[xmli].send(params);
		
		if (!async) {
			finishRemote(xmli, grdestination, func, passResp);
		}
		
		return true;
	}
	
	return false;
}