var Ajax = {
	AbortRequest: function (XHR) {
		if(XHR != "") {
			XHR.onreadystatechange = function () {}
			XHR.abort();
			Ajax.HideLoadingIndicator(XHR);
			XHR = null;
		}
	},
	AsyncRequest: function (method, page, data, callback, indicateLoading, returnXHR) {
		var XHR;
		if(window.XMLHttpRequest) XHR = new XMLHttpRequest();
		else if(window.ActiveXObject) XHR = new ActiveXObject("Microsoft.XMLHTTP");
		XHR.open(method, page + ((method == "GET")?((page.indexOf("?") == -1)?"?":"&") + Ajax.Constants.Get():""), true);
		XHR.onreadystatechange = function () {
			switch (XHR.readyState) {
				case 1:
					if(indicateLoading) {
						Ajax.CallStack.push(XHR);
						window.setTimeout(Ajax.ShowLoadingIndicator, 500);
					}
					break;
				case 4:
					if(indicateLoading) Ajax.HideLoadingIndicator(XHR);
					try {
						if(XHR.status == 200) {
							if(callback) {
								var RequestResponse = Ajax.CreateRequestResponse(XHR.responseText, callback.Args);
								if(!callback.Scope) callback.Success(RequestResponse);
								else callback.Success.apply(callback.Scope, [RequestResponse]);
							}
						}
						else {
							var error = (XHR.status == 500)?XHR.responseText:XHR.statusText;
							if(callback && callback.Failure) callback.Failure(error);
							else alert(error);
						}
					}
					catch(e) {
						XHR.abort();
					}
					callback = null;
					XHR = null;
					break;
			}
		}
		if(method == "POST") {
			var constants = Ajax.Constants.Get();
			XHR.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
			XHR.send(constants + ((constants != "" && data != "")?"&":"") + data);
		}
		else XHR.send(null);
		if(returnXHR) return XHR;
	},
	CreateRequestResponse: function (response, args) {
		var Obj = new Object();
		Obj.Response = response;
		if(args) Obj.Args = args;
		return Obj;
	},
	CallStack: [],
	Constants: {
		Collection: [],
		Get: function () {
			if(Ajax.Constants.Collection.length > 0) return Ajax.Constants.Collection.map(function (el) {
				return el.join("=");
			}).join("&");
			return "";
		},
		Set: function () {
			var args = Ajax.Constants.Set.arguments;
			var len = args.length, i = 0;
			while(i < len) {
				Ajax.Constants.Collection.push([args[i], encodeURIComponent(args[i + 1])]);
				i += 2;
			}
		}
	},
	HideLoadingIndicator: function (XHR) {
		var i = Ajax.CallStack.indexOf(XHR);
		if(i != -1) Ajax.CallStack.splice(i, 1);
		if(Ajax.CallStack.length == 0) Innect.Style.Set(Innect.$("LoadingIndicator"), "display", "none");
		XHR = null;
	},
	ShowLoadingIndicator: function () {
		if(Ajax.CallStack.length > 0) Innect.Style.Set(Innect.$("LoadingIndicator"), "display", "block");
	},
	SyncRequest: function (method, page, data) {
		var XHR;
		if(window.XMLHttpRequest) XHR = new XMLHttpRequest();
		else if(window.ActiveXObject) XHR = new ActiveXObject("Microsoft.XMLHTTP");
		XHR.open(method, page + ((method == "GET")?((page.indexOf("?") == -1)?"?":"&") + Ajax.Constants.Get():""), false);
		if(method == "POST") {
			XHR.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
			XHR.send(Ajax.Constants.Get() + ((data)?"&" + data:""));
		}
		else XHR.send(null);
		var response = XHR.responseText;
		if(XHR.status == 200) return response;
		alert(XHR.statusText);
		XHR = null;
	},
	ToQuery: function () {
		var args = Ajax.ToQuery.arguments;
		var data = [];
		var len = args.length, i = 0;
		while(i < len) {
			data.push(args[i] + "=" + encodeURIComponent(args[i + 1]));
			i += 2;
		}
		return data.join("&");
	}
}