//This provides an abstraction of the AJAX browser mess.
//For such a popular technique, it'd be nice if they standardized it!

//This becomes the constructor, where we determine how we make requests.
function SafeXMLRequest() {
	requestobject = null;
	useiframe = false;
	frameinterval = null;
	
	//This is a public variable indicating a two parameter callback function to be fired on completion.
	//The first parameter is the returned status code.
	//The second contains the data returned.
	recvcallback = null;
	
	createNewRequest();
	
	//Set up our class' methods.
	this.abort = abortRequest;
	this.open = openRequest;
	this.setCallback = setCallbackRequest;
}

function createNewRequest() {
	if (useiframe) {
		//No need to create a new request object.
		return;
	}
	
	try {
		//Try creating the request as a new object first.
		requestobject = new XMLHttpRequest();
	}
	catch (err) {
		try {
			//OK, they're probably using IE.
			requestobject = new ActiveXObject("Microsoft.XMLHTTP");
		}
		catch(err) {
				//Meh, use an iframe.
				requestobject = document.createElement("iframe");
				requestobject.style.width = "1px";
				requestobject.style.height = "1px";
				requestobject.style.position = "absolute";
				requestobject.style.left = "-1000px";
				document.body.appendChild(requestobject);
				useiframe = true;
		}
	}
	
	if (!useiframe) {
		requestobject.onreadystatechange = stateHandler;	//Do not call this directly!
	}
	else {
		//Try it on a timer.
		frameinterval = setInterval(stateHandler, 50);
	}
}

//This sort of messy looking code is the "future of Javascript"!
//It'd help if we had something like a class keyword to work with.

function abortRequest() {
	if (useiframe) {
		requestobject.src="about:blank";
	}
	else {
		requestobject.abort();
	}
}

function openRequest(method, url) {
	if (useiframe) {
		//Ignore method; iframes must use GET.
		requestobject.src=url;
	}
	else {
		//Create a request.
		var querystring = null;
		var qpos = url.indexOf("?");
		if (qpos >= 0) {
			//Question mark found.
			querystring = url.substring(qpos+1);
			url = url.substring(0, qpos);
		}
		
		requestobject.open(method, url);
		if (method == "POST") {
			requestobject.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
		}
		else {
			//Don't cache pages.
			requestobject.setRequestHeader('Cache-Control', 'no-cache');
		}
		
		requestobject.send(querystring);
	}
}

function setCallbackRequest(callbackfunction) {
	recvcallback = callbackfunction;
}

function stateHandler() {
	if (!useiframe && requestobject.readyState != 4) {
		//We don't care if it's still in progress.
		return;
	}

	if (useiframe) {
		var doccontent = (requestobject.contentDocument) ? requestobject.contentDocument.body : requestobject.contentWindow.document.body;
		
		if (doccontent != null) {
			recvcallback(null, doccontent.innerHTML);
			clearInterval(frameinterval);
		}
	}
	else {
		recvcallback(requestobject.status, requestobject.responseText);
	}
	
	//Prepare for the next request.
	createNewRequest();
}
