var doMore =
{
	Ajax :
	{
		Request : function(isAsync)
		{
			// Public Properties
			this.RequestType = "GET";
			this.IsAsync = (isAsync == undefined ? true : isAsync);
			
			// Public Methods
			
			// Retrieves the data from a given URL.
			this.Get = function(responseHandler, responseHandlerArgs, url)
			{
				return MakeRequest(false, this.RequestType, this.IsAsync, responseHandler, responseHandlerArgs, url);
			}

			this.GetProperty = function(responseHandler, responseHandlerArgs, assemblyName, classOrStructName, propertyName)
			{
				var url = execHandler + "?Type=Get&Assembly=" + assemblyName + "&Object=" + classOrStructName + "&Member=" + propertyName;
				return MakeRequest(true, this.RequestType, this.IsAsync, responseHandler, responseHandlerArgs, url);
			}

			// Constructs a given .NET object & returns it as a javascript object.
			this.ConstructObject = function(responseHandler, responseHandlerArgs, assemblyName, classOrStructName, constuctorSignature)
			{
				// Build constuctor args (all args after the ones defined in this function signature)
				var constructorParams = "";
				for(var i=5; i<arguments.length; i++)
				{
					if (constructorParams != "") constructorParams += "^"; 
					constructorParams += arguments[i];
				}
				var url = execHandler + "?Type=Construct&Assembly=" + assemblyName + "&Object=" + classOrStructName + "&Signature=" + constuctorSignature + "&Params=" + escape(constructorParams);
				return MakeRequest(true, this.RequestType, this.IsAsync, responseHandler, responseHandlerArgs, url);
			}

			// Calls a static .NET method & returns the result as a javascript object.
			this.CallMethod = function(responseHandler, responseHandlerArgs, assemblyName, classOrStructName, methodName, methodSignature)
			{
				if (methodSignature)
				{
					// Build method args (all args after the ones defined in this function signature)
					var methodParams = "";
					for(var i=6; i<arguments.length; i++)
					{
						if (methodParams != "") methodParams += "^"; 
						methodParams += arguments[i];
					}
					var url = execHandler + "?Type=Call&Assembly=" + assemblyName + "&Object=" + classOrStructName + "&Member=" + methodName + "&Signature=" + methodSignature + "&Params=" + escape(methodParams);
				}
				else
				{
					var url = execHandler + "?Type=Call&Assembly=" + assemblyName + "&Object=" + classOrStructName + "&Member=" + methodName;
				}
				return MakeRequest(true, this.RequestType, this.IsAsync, responseHandler, responseHandlerArgs, url);
			}

			// Gets the HTTP response code for a given URL. This is always a synchronous call.
			this.GetResponseCode = function(url)
			{
				request = GetHttpRequester();
				request.open("GET", url + (url.indexOf("?") == -1 ? "?" : "&") + "cacheReset=" + Math.random(), false);
				request.send(null);
				return request.status;
			}
			
			// Private Members
			var execHandler = "/AjaxHandler.axd";
			var request = null;

			var GetHttpRequester = function()
			{
				var requester = null;
				if (window.XMLHttpRequest)
				{
					try { requester = new XMLHttpRequest(); }
					catch(e) { requester = null; }
				}
				else if (window.ActiveXObject)
				{
					try { requester = new ActiveXObject("Msxml2.XMLHTTP"); }
					catch(e)
					{
						try { requester = new ActiveXObject("Microsoft.XMLHTTP"); }
						catch(e) { requester = null; }
					}
				}
				return requester;
			}
			
			var MakeRequest = function(isJson, requestType, isAsync, responseHandler, responseHandlerArgs, url, requestBody)
			{
				request = GetHttpRequester();
				if (request != null)
				{
					function responder()
					{
						if (request.readyState == 4)
						{
							var res = parseResult();
							if (!(typeof(res) == "string" && res.indexOf("ERROR!") == 0))
							{
								responseHandler(res, responseHandlerArgs);
							}
						}
					}

					function parseResult()
					{
						if (isJson)
						{
							if (request.responseText.indexOf("ERROR!") == 0)
							{
								alert(request.responseText);
								return request.responseText;
							}
							else
							{
								var json = null;
								eval("json = " + request.responseText);
								return json;
							}
						}
						else return request.responseText;
					}
					
					if (isAsync)
					{
						request.onreadystatechange = responder;
					}
					request.open(requestType, url + "&rand=" + Math.random(), isAsync);
					request.send((requestBody ? requestBody : null));
					if (!isAsync)
					{
						return parseResult();
					}
				}
			}
		}
	}
}