//******************************************************************************/
//																				/
// All parts of this file - including, but not limited to, images, layout, 		/
// code, and scripts - are copyright R.F.J. Vring (ArVee). 						/
// All code is (c) ArVee, 2005-2006 unless otherwise noted in the source code. 	/
// No parts may be used without the expressed, written consent of ArVee. 		/
// Partially or wholly reproducing portions of this file without written  		/
// consent is strictly prohibited.												/
//																				/
// (c) 2005, 2006 R.F.J. Vring (ArVee) (arvee_at_notebook@hotmail.com)			/
//																				/
//******************************************************************************/

//------------------------------------------------------------------------------/
// typical usage:																/
//		var x = new xmlhttp();													/
//			if (x.isEmpty()) {													/
//				alert('failed to initialize xmlhttp object');					/
//				return;															/
//				}																/
//			x.oncomplete = function () {										/
//				alert('hi!');													/
//				}																/
//			x.head('./default.aspx');											/
//------------------------------------------------------------------------------/

function xmlhttp () {

	var m_xmlhttp = undefined;
	var m_index = -1;

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
	// methods																	/
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
	this.get = function (T) {
		this.__init();
		var sessionInfo = this.__sessionInfo();
		this.m_xmlhttp.open('GET',T + (T.indexOf('?') > 0 ? '&' : '?') + "dt=" + new Date().getTime() + sessionInfo,true);
		this.m_xmlhttp.send(null);
		};
	// variable number of arguments !											/
	// the extra arguments are pushed into the request header					/
	this.post = function (T,payload) {
		this.__init();
		var sessionInfo = this.__sessionInfo();
		this.m_xmlhttp.open('POST',T + (T.indexOf('?') > 0 ? '&' : '?') + "dt=" + new Date().getTime() + sessionInfo,true);
		this.m_xmlhttp.setRequestHeader('Content-Length', sessionInfo.length + payload.length + "");
		var i, n; for (i = 2, n = arguments.length; i < n; i += 2) {
			this.m_xmlhttp.setRequestHeader(arguments[i], arguments[i + 1]);
			}
		this.m_xmlhttp.send(payload + sessionInfo);
		};
	this.head = function (T) {
		this.__init();
		var sessionInfo = this.__sessionInfo();
		this.m_xmlhttp.open('HEAD',T + (T.indexOf('?') > 0 ? '&' : '?') + "dt=" + new Date().getTime() + sessionInfo,true);
		this.m_xmlhttp.send(null);
		};
	this.isEmpty = function () {
		return (this.m_xmlhttp === undefined);
		};
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
	// event handlers. override at will.										/
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
	this.onuninitialized = function () {
		};
	this.onloading = function () {
		};
	this.onloaded = function () {
		};
	this.oninteractive = function () {
		};
	this.oncomplete = function () {
		alert(this.m_xmlhttp.getAllResponseHeaders());
		};
	this.onerror = function () {
		alert(this.m_xmlhttp.getAllResponseHeaders());
		};
	this.onprogress = function () {
		};
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
	this.runScripts = function () {
		var scripts = isEmpty(this.m_xmlhttp.responseXML)
			? null
			: this.m_xmlhttp.responseXML.getElementsByTagName("string");
		if (isEmpty(scripts) || !scripts.length) {
			try {
				eval(this.m_xmlhttp.responseText);
				}
			catch (ex) {
				}
			}
		else {
			var i, n; for (i = 0, n = scripts.length; i < n; i++) {
				try {
					eval(scripts[i].firstChild.nodeValue);
					}
				catch (ex) {
					}
				}
			}
		};
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
	this.getResponseText = function () {
		var scripts = isEmpty(this.m_xmlhttp.responseXML)
			? null
			: this.m_xmlhttp.responseXML.getElementsByTagName("STRING");
		if (isEmpty(scripts) || !scripts.length) {
			try {
				return(this.m_xmlhttp.responseText);
				}
			catch (ex) {
				}
			}
		scripts = isEmpty(this.m_xmlhttp.responseXML)
			? null
			: this.m_xmlhttp.responseXML.getElementsByTagName("BOOLEAN");
		if (isEmpty(scripts) || !scripts.length) {
			try {
				return(this.m_xmlhttp.responseText);
				}
			catch (ex) {
				}
			}
		else {
			var i, n; for (i = 0, n = scripts.length; i < n; i++) {
				try {
					return(scripts[i].firstChild.nodeValue);
					}
				catch (ex) {
					}
				}
			}
		return "";
		};
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
	// internal. 																/
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
	this.__sessionInfo = function () {
		if (isEmpty(document.session) === false) {
			if (isEmpty(document.session.info) === false) {
				return "&s=" + escape(JSON.stringify(document.session.info));
				}
			}
		return "&s=";
		};
	this.__sessionInfoEx = function () {
		if (isEmpty(document.session) === false) {
			return (JSON.stringify(document.session));
			}
		return "";
		};
	this.__handler = function () {
		if (this.m_index === -1) {
			this.onerror();
			return;
			}
		this.onprogress();
		switch (this.m_xmlhttp.readyState) {
			// uninitialized													/
			case 0: 
				this.onuninitialized();	
				return false;
			// loading															/
			case 1: 
				this.onloading();
				return false;
			// loaded															/
			case 2: 
				this.onloaded();
				return false;
			// interactive 														/
			case 3: 
				this.oninteractive();
				return false;
			// complete															/
			case 4: 
				this.oncomplete();
				this.__destroy(); 
				return false;
			}
		this.onerror();
		return this.__destroy();
		};
	this.__init = function () {

		this.m_index = -1; var i, n; for (i = 0, n = document.xmlhttp.length; i < n; i++) {
			if (isEmpty(document.xmlhttp[i])) {
				this.m_index = i; 
				break;
				}
			}
		if (this.m_index == -1) {
			this.m_index = document.xmlhttp.length;
			}
		document.xmlhttp[this.m_index] = this;
		eval('this.m_xmlhttp.onreadystatechange = function () { document.xmlhttp[' + this.m_index + '].__handler(); }');
		};
	this.__destroy = function () {
		if (this.m_index != -1) {
			document.xmlhttp[this.m_index] = undefined;
			}
		this.m_index = -1;
		var i, n; for (i = 0, n = document.xmlhttp.length; i < n; i++) {
			if (isEmpty(document.xmlhttp[i]) === false) {
				return;
				}
			}
		};
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
	// constructor 																/
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
	try {
		this.m_xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
		} 
	catch (e) {
		try {
			this.m_xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			} 
		catch (E) {
			this.m_xmlhttp = undefined;
			}
		}
	if (this.m_xmlhttp === undefined && typeof XMLHttpRequest != 'undefined') {
		this.m_xmlhttp = new XMLHttpRequest();
		}	
	if (isEmpty(this.m_xmlhttp) === false) {
		if (isEmpty(document.xmlhttp)) {
			document.xmlhttp = [];
			}
		}
	}
