/**
 * A script to facilitate the use of XMLHttpRequest by providing accessors.
 *
 * @sdoc sdoc/xmlhttp.sdoc
 */


(function () {	// anonymous closure

	var factory = null;
	
	//-----------------------------------------/ ActiveX XMLHttpRequest /-
	// IE6 appears to have some memory-leak problems if you create a new
	// XMLHttpRequest object for each new call. To avoid this problem,
	// request-objects are pooled and re-used whenever possible.
	
	var ActiveXFactory = function () {
		this.pool = [];
	};

	ActiveXFactory.prototype.create = function () {
		for (var index in this.pool) {
			if (this.pool[index].readyState == 4) {
				return this.pool[index];
			}
		}

		var xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
		this.pool.push (xmlhttp);
		return xmlhttp;
	};



	//------------------------------------------/ Native XMLHttpRequest /-
	// Native XMLHttpRequest objects don't seem to suffer from the above
	// problem. In fact, re-using them appears to cause problems in some
	// browsers. As such, a new one is made for each call.

	var NativeFactory = function () {
	};

	NativeFactory.prototype.create = function () {
		return new window.XMLHttpRequest ();
	};



	//------------------------------------------------/ Initialisation /-

	if (window.XMLHttpRequest) {
		factory = new NativeFactory ();
	} else {
		factory = new ActiveXFactory ();
	}



	//---------------------------------------------/ XMLHttpPostRequest /-

	var XMLHttpPostRequestImpl = function (destination, content, onresponse, onerror) {
		var xmlhttp = factory.create ();
	
		// open first, then set onreadystatechange. This ensures correct re-use
		// behaviour in IE
		xmlhttp.open('POST', destination, true);
	
		xmlhttp.onreadystatechange = function () {
			if (xmlhttp.readyState == 4) {
				var status = 0;

				try {
					status = xmlhttp.status;
				} catch (e) {
					// in case of problems firefox can throw an exception trying to read status and statusText
				}

				if (status == 200) {
					onresponse (unescape (xmlhttp.responseText));
					xmlhttp = null;
				} else {
					onerror (xmlhttp.status, xmlhttp.statustext, xmlhttp.responseText);
					xmlhttp = null
				}
			}
		};
	
		xmlhttp.setRequestHeader ('Content-Type', 'text/plain; charset=UTF-8'); // benodigd voor POST
		xmlhttp.setRequestHeader ('Connection', 'close');	// zie documentatie over XMLHttpRequest fout 12031
		xmlhttp.send(escape (content));
	};

	/** @id XMLHttpPostRequest */
	XMLHttpPostRequest = function (destination, content, onresponse, onerror) {
		var retries = 0;
		var errmsg = '';
		var sendrequest = function () {
			XMLHttpPostRequestImpl (destination, content, onresponse, sendfail);
		};
		var sendfail = function (status, statustext, response) {
			switch (status) {
				// Unknown error? Retry just in case
				case 0:
				// dropped connections
				case 12029:
				case 12030:
				case 12031:
				// connection closed by server
				case 12152:
					retries++;
					if (retries >= 10) {
						onerror (status, statustext, response);
					} else {
						window.setTimeout (sendrequest, 1000);
					}
					break;
				default:
					onerror (status, statustext, response);
			}
		};
		// sending the request immediately seems to fail if it was initiated (directly or
		// indirectly) by an iframe which has since then been removed (odds are that it
		// tries to send it from the iframe instead of from the main-window). Delaying
		// the sending of the request through a 1 milli-second timeout seems to solve that
		// problem (probably manages to switch some kind of internal context due to it).
		window.setTimeout (sendrequest, 1);
	};

}) ();
