/**
 * Ajax Library
**/
var AjaxLoader = {
	attach: function (id, event , action){
		e = eId(id);
		if (e) eval("e."+event+" = function(){"+action+"};");					
	},
	formSubmit: function (formElementArg, options){
		var formElement = eId(formElementArg);
		encodedForm = FormTools.encode(formElement.id);
		//Set options
		options.requestVars = encodedForm;
		options.url = formElement.action;
		
		//Check if there are extra parameters to add into the requestVariable
		if (options.parameters){
			var parameters = new Array();
			for(param in options.parameters){
				paramVal = options.parameters[param];
				parameters.push(param+'='+encodeURIComponent(paramVal));
			}
			parameters = parameters.join('&');
			options.requestVars += '&'+parameters;
		}		
		//Run our ajax
		new Ajax(options);
	}, 
	feedbackAnimation: function (element,state){
		var e = eId(element);
		if (state == 'processing'){
			//Get height of this element.
			var myY = e.scrollHeight;
			var widthStyle ='';
			if (e.style.width){
				widthStyle = e.style.width;
			}
			var myX = e.scrollWidth;
			e.innerHTML = '';
			
			e.style.width = widthStyle == ''? myX+'px' : widthStyle;
			e.style.height = myY+'px';
			e.className = 'feedBack';	
		} else if (state == 'ready'){
			if (e){
				e.className = '';
				e.style.height = 'auto';
			}
		}
	}, 
	feedbackAnimationHP: function (element,state){
		var e = eId(element);
		if (state == 'processing'){
			//Get height of this element.
			var myY = e.scrollHeight;
			var widthStyle ='';
			if (e.style.width){
				widthStyle = e.style.width;
			}
			var myX = e.scrollWidth;
			e.innerHTML = '';
			
			e.style.width = widthStyle == ''? myX+'px' : widthStyle;
			e.style.height = myY+'px';
			e.className = 'feedBackHP';	
		} else if (state == 'ready'){
			if (e){
				e.className = '';
			}
		}
	}
}
/**
 * The Ajax Object
 * @param obj myParameters 
 */
var Ajax = function(myParameters){
	
	this.request = null;
	this.requestVars = null;	
	this.options = {
		url: null,
		method: 'post',
		requestVars: null,		
		async: true,
		feedbackFunction: null,
		feedbackElement: null,		
		updateElement: null,
		onReadyState: 'onReadyState'
	};
	//try {
		this.init();	
		this.loadParameters(myParameters);	
		this.send();
	//}
	//catch (e) {
		//alert(e);
	//}
	return false;
};

Ajax.prototype = {
	init: function (){
	    try { this.request = new ActiveXObject("Msxml2.XMLHTTP");  return 1; } catch (e) {}
	    try { this.request = new ActiveXObject("Microsoft.XMLHTTP"); return 1; } catch (e) {}
	    try { this.request = new XMLHttpRequest( ); return 1; } catch(e) {}	
	    alert("XMLHttpRequest not supported");
		return 0;
	},
	loadParameters: function (myParameters){ //Initialises the options from creation
		for (var property in myParameters){
			var prop = this.options[property] = myParameters[property] || this.options[property];
		};
	},
	send : function (){
		
		if (this.options.method == 'post'){			
		
			this.request.open('POST', this.options.url, this.options.async);
			this.request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');			
		} else {
			var randomInt = parseInt(Math.random()*999999);
			
			// add random number to URL to avoid cache problems
			this.options.url = this.options.url;
			
			this.request.open('GET', this.options.url, this.options.async);	
		}
		var self = this;
			
		this.request.onreadystatechange = function(){
			self.onReadyState.call(self);
		}
		
		this.request.send(this.options.requestVars);
	},
	onReadyState: function (){
		var readyState = this.request.readyState;
		if (readyState == 4){
			//Check if theres a feedback function and a feedback element
			if(this.options.feedbackElement != null){
				eval(this.options.feedbackFunction+'(\''+this.options.feedbackElement+'\',\'ready\');');	
			}
			if(this.request.status == 200 || this.request.status == 0) {				
				
				if (this.options.updateElement != null){
					 mye = eId(this.options.updateElement);							 			 
					 if (mye){
					 	mye.innerHTML = this.request.responseText;					 	
					 	this.evaluateJs(); 
					 }
				}
	        } else {
	            alert("Error: " + this.request.statusText);
	        }
	        this.cleanUp();
		} else {
			//Check if theres a feedback function and a feedback element
			if(this.options.feedbackElement != null){
				eval(this.options.feedbackFunction+'(\''+this.options.feedbackElement+'\',\'processing\');');	
			}
		}
	}, 	
	evaluateJs: function(){
		var scripts = this.request.responseText.match(/<script[^>]*?>[\S\s]*?<\/script>/g);
		if (scripts){
			for (i =0; i < scripts.length; i++){
				script = scripts[i];
				eval(script.replace(/^<script[^>]*?>/, '').replace(/<\/script>$/, ''));
			}
		}
	},
	cleanUp: function(){
		this.request = null;
	}
}



/**
 * Generic form tools. Mainly used to encode the form so it can be submitted via ajax
 */
var FormTools = {
	/**
	 * Encodes the form
	 */		
	encode: function (form){
		var encodedElements = new Array();
		form = eId(form);
		if (!form) return '';
		//Iterate through the form elements
		for (var i = 0; i < form.elements.length; i++){			
			enc = FormTools.encodeElement(form.elements[i]);
			if (typeof enc == 'string'){
				encodedElements.push(enc);
			}
		}
		
		encodedString = encodedElements.join('&');
		return(encodedString);
		
	},
	/**
	 * Encodes the element
	 */
	encodeElement: function(element){
		//check the type
		var ret = false;
		eType = element.type;
		
		if (eType == 'checkbox'){
			ret = FormTools.encodeCheckboxRadio(element);				
		} else if (eType == 'select-multiple'){
			
		} else {
			ret = FormTools.encodeSimple(element);
		}
		return ret;	
	},
	
	/**
	 * Encode simple fields such as text, textarea, hidden, 
	 */
	encodeSimple: function (element){
		ret = false;
		if (element.name){
			ret = element.name + '=' + encodeURIComponent(element.value);
		}
		return ret;
	},
	encodeCheckboxRadio: function (element){
		ret = false;
		if (element.checked){
			ret = element.name + '=' + encodeURIComponent(element.value);
		}
		return ret;
	}
}

/**
 * eId - get document element by id.
 * @param string - the name of the id
 * @return element
 */
var eId = function (e){
	var ret  = false;
	
	if (typeof e == 'string'){
		ret = document.getElementById(e) || false;
	} else if (typeof e == 'object'){
		ret = e;
	}
	return ret;
}