/*
 * SharePath Tier0 suite
 * Copyright (c) Correlsense Inc.
 * All rights reserved.
 */

/*
 * Usage:
 * To be portable, create XMLHttpObject in the following order.
 * Doing so will also enable the interception mechanism.
 *
function getHttpRequest() {
	var xmlhttp = null;

	if (window.XMLHttpRequest) {
		xmlhttp = new window.XMLHttpRequest();
	}               
	else {          
		try {           
			xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
		}       
		catch (e) {     
			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		}
	}       

	return xmlhttp;
}
 *
 */

(function() {
	if (
		(window.XMLHttpRequest && !window.XMLHttpRequest.prototype) ||
		(!window.XMLHttpRequest && window.ActiveXObject)
	) {
		function XMLHttpRequest() {
			this.xmlhttp = null;
			try {
				this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
			}
			catch (e) {
				this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			}
		}
		XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {this.xmlhttp.open(method, url, async, user, pass);};
		XMLHttpRequest.prototype.setRequestHeader = function(header, value) {this.xmlhttp.setRequestHeader(header, value);};
		XMLHttpRequest.prototype.getResponseHeader = function(header) {return this.xmlhttp.getResponseHeader(header);};
		XMLHttpRequest.prototype.getResponseHeaders = function() {return this.xmlhttp.getResponseHeaders();};
		XMLHttpRequest.prototype.send = function(data) {this.xmlhttp.send(data);};
		XMLHttpRequest.prototype.abort = function() {this.xmlhttp.abort();};

		XMLHttpRequest.prototype.readyState = 0;
		XMLHttpRequest.prototype.status = 0;
		XMLHttpRequest.prototype.responseText = "";
		XMLHttpRequest.prototype.responseXML = "";
		XMLHttpRequest.prototype.onreadystatechange = null;
		window.XMLHttpRequest = XMLHttpRequest;
	}
})();

function _sp_t0_xml_update_msxml(obj) {
	if (obj.xmlhttp) {
		obj.readyState = obj.xmlhttp.readyState;
		try {obj.status = obj.xmlhttp.status;}catch(e){}
		try {obj.responseText = obj.xmlhttp.responseText;}catch(e){}
		try {obj.responseXML = obj.xmlhttp.responseXML;}catch(e){}

		if (obj.onreadystatechange) {
			obj.xmlhttp.onreadystatechange = obj.onreadystatechange;
		}
	}
}

function _sp_t0_ajax_send(xmlhttp) {
	var end = new Date();
	var remote_id = null;
	try{remote_id = xmlhttp.getResponseHeader("X-SharePath-RUM-RemoteID");}catch(e){}
	if (_SP_SUPPORT_OLD_MODE) {
		try{if (remote_id == null) {remote_id = xmlhttp.getResponseHeader("X-SharePathEventID");}}catch(e){}
	}
	_sp_t0_sendTier0(
		xmlhttp.status,
		xmlhttp._sp_t0_begin,
		xmlhttp._sp_t0_request_return != null ? xmlhttp._sp_t0_request_return : end,
		end,
		xmlhttp._sp_t0_url,
		remote_id
	);
}

function _sp_t0_xml_onreadystatechange(e, me) {
	if (typeof(e) != "undefined" && e != null && e.type == "sptier0test") {
		e.initEvent("sptier0test-ack", true, true);
		return;
	}

	_sp_t0_xml_update_msxml(me);

	if (me._sp_t0_skip != true) {
		switch(me.readyState) {
			case 3:
				me._sp_t0_request_return = new Date();
			break;
			case 4:
				_sp_t0_ajax_send(me);
			break;
		}
	}

	try {
		me._sp_t0_onreadystatechange.handleEvent(e);
	}
	catch(e) {
		// chrome+IE have no event sink
		try {
			if (me._sp_t0_onreadystatechange != null) {
				me._sp_t0_onreadystatechange();
			}
		}
		catch(e) {}
	}
}

(function(open) {
	XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
		open.call(this, method, url, async, user, pass);
		if (this._sp_t0_skip != true) {
			this._sp_t0_url = url;
			this._sp_t0_async = async;
			if (_SP_SUPPORT_OLD_MODE) {
				try{this.setRequestHeader("X-SharePathEventID", "supported");} catch(e){}
			}
			try{this.setRequestHeader("X-SharePath-RUM-Enabled", "true");}catch(e){}
		}
	};
}) (XMLHttpRequest.prototype.open);

(function(send) {
	XMLHttpRequest.prototype.send = function(data) {
		this._sp_t0_begin = new Date();
		this._sp_t0_request_return = null;
		/* IE trigger event if in sync too */
		var me = this;
		var func = function(e) {_sp_t0_xml_onreadystatechange(e, me);};

		var already_hooked = false;
		if (this.onreadystatechange == func) {	/* IE, chrome */
			already_hooked = true;
		}
		try {					/* Firefox */
			var e = window.document.createEvent("HTMLEvents");
			e.initEvent("sptier0test", true, true);
			e.originalTarget = me;
			this.onreadystatechange.handleEvent(e);
			if (e.type == "sptier0test-ack") {
				already_hooked = true;
			}
		}
		catch(e) {}
		if (!already_hooked) {
			this._sp_t0_onreadystatechange = this.onreadystatechange;
			this.onreadystatechange = func;
		}

		_sp_t0_xml_update_msxml(this);
		send.call(this, data);
		_sp_t0_xml_update_msxml(this);
		if (this._sp_t0_skip != true && !this._sp_t0_async) {
			_sp_t0_ajax_send(this);
		}
	};
}) (XMLHttpRequest.prototype.send);

