	/** { [object.window.Ajax]
	* This file contains an object that enables a quick and easy
	* connection to the XMLHTTPRequest object for ajax sites.
	*
	* @author :: Scott Mcdonald
	* @created :: Monday, October 16, 2006
	* @version :: V2.0
	* @example: var a = new Ajax()
	* @dependency :: [function.window.Catch]
	* @dependency :: [function.window.trace]
	* @dependency :: [function.window.CloseActiveAjaxConnection]
	* @dependency :: [function.window.TimeoutActiveConnections]
	* @dependency :: [function.window.getPepper]
	*/
	if(!window.ajaxOpenConnections){window.ajaxOpenConnections = new Array();}
	function Ajax(){
		try {
			/* Properties
			*/
				this.typename = "object.window.Ajax";
				this.public = true;
				/* indicates if this object can be recycled for further use */
				this.connected = false;
				this.name = this.id =	"AjaxConnectionObject" + window.ajaxOpenConnections.length;
				window.ajaxOpenConnections[window.ajaxOpenConnections.length] = this;
				this.ConObj = undefined;
				this.ValueList = new Array();
				this.method = "Get";
				this.async = true;
				this.code = 0; /* will be used to set the error codes when sending so on failure the errorlog can have proper information */
				this.debug = false;
				this.url = "";
				this.timeout = -1;
				this.timeoutId = undefined;
				this.timeoutWarningWindow;
				this.info = "";
				this.canceled = false; /* keeps track of a canceled request. this prevents an onFailed from being called */
				this.anchor = undefined;
				this.connections = window.ajaxOpenConnections;
				this.length = window.ajaxOpenConnections.length;

			/* Handlers
			*/
				this.onSuccess = new Function();
				this.onFailed = new Function();
				this.onAbort = new Function();

			/* Methods
			*/
				/** returns if the object is currently occupied
				*/
				this.occupied = function(){
					try {
						var occupied = this.ConObj.readyState;
						return (occupied && (occupied < 4));
					} catch(e){Catch(this.typename + ".occupied",e,true);};
				};

				this.processed =	function() {
					try {
						 if (this.ConObj.readyState == 4 && this.ConObj.status == 200) {
							 return(true);
						 } else {
							 return(false);
						 }
					} catch(e){Catch(this.typename + ".processed",e,true);}
				};

				this.query =	function(){
					try {
						var arr = new Array();
						for(var i=0;i<this.ValueList.length;i++){
							arr[arr.length] = this.ValueList[i].name + "=" + escape(this.ValueList[i].value);
						}
						return(arr.join("&"));
					} catch(e){Catch(this.typename + ".query",e,true);}
				};

				this.add =	function(strName, strValue){
					try {
						if(strName!=undefined && strValue!=undefined){
							var newVal = new Object();
							newVal.name = strName;
							newVal.value = strValue;
							this.ValueList[this.ValueList.length] = newVal;
							this.method = "POST";
						}
					} catch(e){Catch(this.typename + ".addPair([" + strName + "],[" + strValue + "])",e,true);}
				};

				this.get =	function(dilim){
					try {
						for(var i=0;i<this.ValueList.length;i++){
							if(this.ValueList[i].name == dilim){
								return(this.ValueList[i].value);
							};
						};
					} catch(e){Catch(this.typename + ".get",e,true);};
				};

				this.clearPost = function (){
					try {
						this.ValueList = new Array();
					} catch(e){Catch(this.typename + ".clearPost",e,true);}
				};

				/** determans if the status change of the connection object is "done" and if there is
				* a success return. if so, then it will call the onSuccess callback function passing the
				* XML And TEXT versions of the return. if it fails then it will call the onFailed callback and
				* pass
				*/
				this.callback = function(address,info){
					if(!address){address=""};
					if(!info){info=""};
					try {
						if(!this.ConObj){return;}
						if(this.ConObj.readyState==4){
							if(this.timeoutWarningWindow!=undefined){
								this.timeoutWarningWindow.close();
							}
							clearTimeout(this.timeoutId);
							try {
								if(this.ConObj.status == 200){
									this.connected = false;
									try {
										this.onSuccess(this.ConObj.responseXML, this.ConObj.responseText,address,info);
									} catch(e){
										/* Catch(this.typename + ".callback.3(" + address + "," + this.ConObj.responseText + ")",e,true); */
									}
								} else {
									if(this.debug){trace("ajax_callback: " + address + " :: status=" + this.ConObj.status);}
									try {
										if(!this.canceled){this.onFailed(this.ConObj,address,info,this.code);}
										this.canceled = false;
									} catch(e){Catch(this.typename + ".callback.2",e,true);}
								};
							} catch(e){Catch(this.typename + ".callback.1",e,true);}
						};
					} catch(e){Catch(this.typename + ".callback.base",e,true);}
				};

				this.KillAllProcesses = function(){
					for(var i in window.ajaxOpenConnections){
						try{window.ajaxOpenConnections[i].cancel();} catch(e){}
					}
				};

				this.close = function(){
					try {
						CloseActiveAjaxConnection(this);
					} catch(e){Catch(this.typename + ".close",e,true);}
				};

				this.reset = function(){
					try {
						this.url = "";
						this.info = "";
						this.code = 0;
						this.method = "Get";
						this.initEvents();
						this.ValueList = new Array();
					} catch(e){Catch(this.typename + ".reset",e,true);};
				};

				this.initEvents = function() {
					var target = this;
					this.onSuccess = function(o) {
						try {
							if (target.debug) { trace("Success: " + EncodeHTML(o.responseXML.status)); }
						} catch (e) {
							if (target.debug) { trace("Success: " + EncodeHTML(o.responseText)); }
						};
					};

					this.onFailed = function(o, a, i, c) {
						try {
							if (target.debug) {
								if (target.method == "GET") {
									window.open(target.url + "?" + unescape(target.query()), "debug", "width=500,height=500,scrollbars=yes,resizeable=yes");
								} else {
									var ajaxWindow = window.open("", "debug", "width=500,height=500,scrollbars=yes,resizeable=yes");
									//target.url + "?" + unescape(target.query())
									var html = "";
									html += "<html><title>Debug</title><body>";
									html += "<form id=\"DebugForm\" action=\"" + target.url + "\" method=\"POST\">";
									var iLoop = 0;
									var lLoop = target.ValueList.length;
									for (iLoop = 0; iLoop < lLoop; iLoop++) {
										try {
											trace(target.ValueList[iLoop].name);
											html += "<input type=hidden id=\"" + target.ValueList[iLoop].name + "\" name=\"" + target.ValueList[iLoop].name + "\" value=\"" + target.ValueList[iLoop].value + "\" />";
										} catch (e) { };
									};
									html += "</form>";
									html += "<sc" + "ript>document.forms[0].submit();</sc" + "ript>";
									html += "</body></html>";
									ajaxWindow.document.write(html);
								};
							};
						} catch (e) { Catch(target.typename + ".onFailed", e, true); };
					};
				};

				this.status = function(){
					try {
						if(this.ConObj){
							try {
								return(this.ConObj.status);
							} catch(e){return(-1);};
						} else {
							return(-1);
						};
					} catch(e){Catch(this.typename + ".status",e,true);};
				};

				this.connect =	function(){
					try {
						if(this.debug){trace(this.id + " :: creating connection");};
						/* first try to connect for non IE browsers
						*/
						try {
							this.ConObj = new XMLHttpRequest();
							this.ConObj.id = "ConObj";
							return(true);
						}
						/* if this throws an error, we're looking at IE so try to build an object for IE
						*/
						catch (e) {
							/* build a list of the versions of the activex component. we're going to try to use the most recent
							* this is contingent on updates to the client machine
							*/
								var _ieVersions = new Array(
									'MSXML2.XMLHTTP.6.0',
									'MSXML2.XMLHTTP.5.0',
									'MSXML2.XMLHTTP.4.0',
									'MSXML2.XMLHTTP.3.0',
									'MSXML2.XMLHTTP',
									'Microsoft.XMLHTTP'
								);
							var success = false;
							/* loop through the active x version list
							*/
							for (var i=0;i < _ieVersions.length && !success; i++) {
								/* attempt to make the connection with this control version, if it fails then
								*	we will try the next version.
								*/
								try {
									this.ConObj = new ActiveXObject(_ieVersions[i]);
									success = true;
								} catch (e) {};
							};
							/* if we've made it all the way through the list and there is still not a connection
							* then we can't get one
							*/
							if (!success) {return(false);};
							return(true);
						};
					} catch(e){Catch(this.typename + ".connect.base",e,true);};
				};

				this.send = function(address,info) {
					try {
						var target = this;
						if(this.debug){trace(this.id + " :: Sending Address: " + ((address==undefined)?this.url:address));};
						this.info = info;
						if(!address){address = this.url;} else {this.url = address};
						if(!address){if(this.debug){trace("Unable to send AJAX request. No address specified");return;};};
						if (!this.ConObj) {this.connect();};
						if (!this.occupied()) {
							try{
								if(this.method.toUpperCase()=="POST"){
									this.ConObj.open("POST",address,this.async);
								} else {
									this.ConObj.open("GET",address + ((address.indexOf("?")==-1)?"?":"&") + "pepperString=" + getPepper(),this.async);
								};
							} catch(e){Catch(this.typename+".send([" + address + "], [" + info + "])",e,true);};

							if(this.method.toUpperCase()=="POST"){
								this.ConObj.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
								this.ConObj.setRequestHeader("Content-length",this.query().length);
								this.ConObj.send(this.query());
							} else {
								this.ConObj.send((info)?info:this.query());
							};
							if(this.timeout>0){
								this.timeoutId = setTimeout("TimeoutActiveConnections(" + (window.ajaxOpenConnections.length-1) + ")", this.timeout);
							};
							if(this.async){
								this.ConObj.onreadystatechange = function(){
									target.callback(address,info);
								};
							} else {
								if (this.processed) {
									if(this.debug){trace("TODO: Handle Non Async Ajax");};
									return(this.ConObj.responseText);
								};
							};
						};
						return(false);
					} catch(e){Catch(this.typename + ".send.base",e,true);};
				};

				this.cancel = function(){
					try {
						if(this.debug){trace(this.id + " :: cancel");}
						this.canceled = true;
						if(this.ConObj){
							try{this.ConObj.abort();} catch(e){}
							try {
								this.onAbort();
							} catch(e){Catch(this.typename + ".cancel.onAbort",e,true);}
						}
					} catch(e){Catch(this.typename + ".cancel",e,true);}
				};

				this.toString = function(){
					try{
						r = "";
						r+="Name: " + this.id + "\n";
						r+="Asyncronious: " + this.async + "\n";
						r+="Method: " + this.method + "\n";
						r+="Debug: " + this.debug + "\n";
						r+="URL: " + this.url + "\n";
						r+="Query: " + this.query() +"\n";
						return(r);
					} catch(e){Catch(this.typename + ".toString",e,true);};
				};

				if(this.connect()){this.connected = true;};
				try {
					if(!window.ajaxOpenConnections){window.ajaxOpenConnections = new Array();};
					this.initEvents();
				} catch(e){Catch(this.typename + ".initEvents.Call()",e,true);};
			} catch(e){Catch(this.typename + ".main",e,true);};
		};
	/** } [object.window.Ajax] **/

	/** { [function.window.TimeoutActiveConnections]
	* @dependency :: [function.window.Catch]
	* @dependency :: [variable.window.tooltip]
	*/
	 function TimeoutActiveConnections(i){
		 try {
			var o = window.ajaxOpenConnections[i];
			if(o.status()!=200){
				o.timeoutWarningWindow = new ToolTip();
				o.timeoutWarningWindow.show({
					text: "The action has taken longer then expected to run.\n" +
					"Click \"ok\" to allow another " + (o.timeout/1000) + " seconds for the action\n" +
					"to complete",
					timeout:-1,
					anchor: o.anchor,
					onOK: function(){
						o.timeoutId = setTimeout("TimeoutActiveConnections(" + (i) + ")", o.timeout);
					},
					onCancel: function(){
						if(o.status()!=200){
							o.close();
						};
					}
				});
			};
		} catch(e){Catch("window.function.TimeoutActiveConnections",e,true);}
	};
	/** } [function.window.TimeoutActiveConnections] **/

	/** { [function.window.CloseActiveAjaxConnection]
	* @dependency :: [function.window.Catch]
	*/
	function CloseActiveAjaxConnection(o){
		try {
			var t = window.ajaxOpenConnections;
			var i = 0;
			var l = t.length;
			for(i;i<l;i++){
				if(t[i]==o){
					t[i].cancel();
					t[i] = undefined;
					t.splice(i,1);
				};
			};
		} catch(e){Catch("window.function.CloseActiveAjaxConnection",e,true);};
	};
	/** } [function.window.CloseActiveAjaxConnection] **/

	/** { [function.window.FreeAjax]
	 * @purpose - returns an open ajax object which is reporting finished, and public
	 * @param - bDoNotClear as Boolean :: default false, this will have the object remove all previous settings on init
	 * @return - object :: Instance of ajax object, if no open and public objects are found, will return a new instance
	 * @author - Scott McDonald
	 * @created = 10/1/2007:4:05 PM
	 * @dependency :: [function.window.Catch]
	 */
		function FreeAjax(bDoNotClear){
			try {
				var t = window.ajaxOpenConnections;
				var i = 0;
				var l = t.length;
				for(i;i<l;i++){
					if(t[i].status()==200 && t[i].public!=false){
						if(bDoNotClear!=true) { t[i].reset(); }
						return(t[i]);
					}
				}
				return(new Ajax());
			} catch(e){Catch(this.typename + "",e,true);}
		}
	/** } [function.window.FreeAjax] **/

	/** { [function.window.AjaxQuickCall]
	* @purpose :: creates an ajax object - method GET, Sends the call, and then closes the object with no interaction from
	* @param :: url as string - should contain any querystring variables
	* @param :: Arg Object ::
	* 	@Arg :: CallBack [function]
	* @return :: void
	* @Author :: Scott McDonald
	* @dependency :: [object.window.Ajax]
	* @dependency :: [function.window.Catch]
	*/
	function AjaxQuickCall(url, Arg){
		if(!Arg){Arg=new Object();}
		var callback = (Arg.callback);
		try {
			if(url){
				var ajax = new Ajax();
				ajax.debug = (Arg.debug==true);
				ajax.method = "GET";
				ajax.onSuccess = function(x,t){
					this.close();
					if(callback){
						callback(x,t);
					};
				};
				ajax.send(url);
			};
		} catch(e){Catch("window.function.AjaxQuickCall",e,true);};
	};
	/** } [function.window.AjaxQuickCall] **/

