// JavaScript Document
var Ajax = {
	Default : {
		// onData handles the response data from the server
		onComplete : function(){},
		onSuccess : function(){},
		onStateChange : function(){},
		onRequest : function(){},
		// onError handles the response data if the server returns an error
		onError : function(XHR){
			alert("(Ajax) Server Error " + XHR.status + ": " + XHR.responseText)
		},
		onClose : function(){},
		userStore : {},
		returnXML : false,
		method : "GET",
		mimeType : "text/plain",
		noCache : true
	},
	XHR:function(){
		return Try.these(
			function() { return new XMLHttpRequest() },
			function() { return new ActiveXObject("Msxml2.XMLHTTP") },
			function() { return new ActiveXObject("Microsoft.XMLHTTP") }
		) || false;
	},
	Error : function(errTxt){
		alert("AJAX ERROR!\n\n" + errTxt);
		return false;
	},
	Strings:{
		ErrNoURL:"No URL was provided for this Ajax call.",
		ErrNoAjaxSupport:"Your browser does not support Ajax!\n\nPlease upgrade your browser or download the FireFox browser at http://getfirefox.com",
		ErrBadInput:"Bad input, the data you tried to send was not formatted correctly."
	}
};

Ajax.Request = new Class({
	initialize : function(settings){
		Object.inherit(this, Ajax.Default, settings );
	}
});

Ajax.Request.implement({
	sender : function(settings){
		var http = new Ajax.XHR();
		if(!http) return Ajax.Error(Ajax.Strings.ErrNoAjaxSupport);
		
		// Add no-cache data
		if(!!settings.noCache){
			settings.data += "&nocache=" + (new Date()).getTime();
		};
		var GETdata = (settings.method.toUpperCase()=="GET")?"?"+settings.data:"";
		var POSTdata = (settings.method.toUpperCase()=="POST")?settings.data:"";
		
		
		//	=================================================================================
		//	MAKING THE REQUEST
		//	================================================================================= 
		http.open(settings.method, settings.url + GETdata, true);
		
		//	-------------------------------------------------- 
		//	Setup the handler 
		http.onreadystatechange = function(){
			settings.onStateChange(http);
			if(http.readyState == 4){
				settings.onComplete(http);
				//	-------------------------------------------------- 
				//	If HTTP status was 200 (OK) then call onComplete 
				if(http.status == 200){
					settings.onSuccess( (settings.XML) ? http.responseXml : http.responseText, settings.userStore );
					
				//	-------------------------------------------------- 
				//	If HTTP status was 200 (OK) then call onComplete 
				}else if(typeof(settings["on" + http.status]) == "function"){
					settings["on" + http.status]( http, settings.userStore );
				}else{
					settings.onError( http, settings.userStore );
				};
				// Kill connection object
				http.abort(); http = null;
				settings.onClose();
				settings = null;
			};
		};
		if(http.overrideMimeType) http.overrideMimeType(settings.mimeType);
		http.setRequestHeader("Connection","close");
		
		if(POSTdata.length > 0){
			http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
			http.setRequestHeader("Content-length", POSTdata.length);
		};
		this.onRequest( http, settings.userStore );
		http.send(POSTdata);
	},
	hook: function(settings){
		this.sender(settings);
	},
	send : function( data, settings ){
		var settings = Object.inherit( {}, this, settings );
		settings.send = null;
		settings.sender = null;
		//	=================================================================================
		//	PARSE THE DATA
		//	Check if the DATA is a form object, if so, parse it's data. 
		//	================================================================================= 
		var dataArr=[];
		if(data.elements){
			for (var i = 0, d = data.elements; i<d.length; i++){
				dataArr.push((d[i].name || d[i].id) + "=" + escape(d[i].value));
			};
			// If the form specifies a method, let it overwrite the existing one.
			if(data.method!=null && data.method!="") settings.method = data.method.toUpperCase();
			if(data.action!=null && data.action!="") settings.url = data.action;
			
		//	-------------------------------------------------- 
		// 	Excape non-form (object) data. 
		}else if(typeof(data)=="object"){
			// parse attributes and escape their values
			for (var i in data){
				dataArr.push(i + "=" + escape(data[i]));
			};
			
		//	-------------------------------------------------- 
		//	Escape string data 
		}else if(typeof(data)=="string"){
			dataArr = data.split("&");
			for(var i = 0; i < dataArr.length; i++ ){
				var dA = dataArr[i].split("=");
				dataArr[i] = dA[0] + "=" + escape(dA[1]);
			};
			
		//	-------------------------------------------------- 
		//	If none of the above data types were sent return an error 
		}else return Ajax.Error(Ajax.Strings.ErrBadInput);
		settings.data = dataArr.join("&");
		this.hook(settings);
		settings = null;
	}
});

Ajax.Request.implement({
	addForm : function( formObject ){
		var form = (formObject.elements) ? formObject : ( $(formObject).elements ) ? $(formObject) : false ;
		if( !form ) return Ajax.Error( Ajax.Strings.ErrFormInvalid );
		var ajaxObject = this;
		form.onsubmit = function(){ajaxObject.send(form);return false;
		};
	}
});
