/**
 *	Simple AJAX Engine (SAE)
 *	Copyright (C) 2008  Allan Cheong (allancth@hotmail.com)
 *
 *	Disclaimer:
 *	This program is free software: you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation, either version 3 of the License, or
 *	any later version.
 *
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *	GNU General Public License for more details. 
 *
 *	Version:	7th May 2008	1.0.0		Initial version
 *				8th May 2008	1.0.1		Added new property in Ajax - isXml
 *				14th May 2008	1.1.0		Added new object - Parameter
 *											Added validations and exceptions
 *				15th May 2008	1.2.0		Added new method in Ajax - setFail()
 *											Amended method in Ajax - setSuccess()
 *											Added new object - RequestException
 *											Added new method in Ajax - setAwaiting()
 */

/**
 *	isBrowser
 *
 *	Helper method to determine the browser type. If 
 *	the parameter value is <code>msie</code> and the 
 *	return value is <code>true</code>, it means that 
 *	the browser the user is using is Microsoft 
 *	Internet Explorer.
 */
function isBrowser(varBrowserType) {
	return (navigator.appVersion.indexOf(varBrowserType.toUpperCase()) >= 0);
}

/**
 *	Parameter
 *
 *	An object to store the parameter of an HTTP post, 
 *	which consists of the identifier and the variable.
 */
function Parameter(varName, varValue) {
	this.ParameterName = varName;
	this.ParameterValue = varValue;
}

/**
 *	Ajax
 *
 *	AJAX wrapper object. Usage Example:
 *	try {
 *		var varAjax = new Ajax('http://www.url.com/ajax-url.jsp');
 *		varAjax.addParam('param1', var1);
 *		varAjax.addParam('param2', var2);
 *		varAjax.setMethod('POST');
 *		varAjax.setAsynchronous(true);
 *		varAjax.setReturnXml(true);
 *		varAjax.setAwaiting(
 *			function() {
 *				// code your stuffs here
 *			}
 *		);
 *		varAjax.setSuccess(
 *			function(varResponse) {
 *				// code your stuffs here
 *			}
 *		);
 *		varAjax.setFail(
 *			function(varException) {
 *				// code your stuffs here
 *			}
 *		);
 *		varAjax.run();
 *	}
 *	catch (e) {
 *		alert(e);
 *	}
 */
  
function Ajax(varURL) {
	var varParameters = new Array();
	var varAwaiting = null; // will execute this function when awaiting response
	var varSuccess = null; // will execute this function when POST is successful
	var varFail = null; // will execute this function when POST is unsuccessful
	var isXml = false; // by default AJAX returns XML document
	var isAsynchronous = true; // by default AJAX is Asynchronous
	var varMethod = 'POST'; // by default method is POST
	
	/**
	 *	setMethod
	 *
	 *	Method of Ajax object to set the POST/GET method
	 *	of a request.
	 */
	this.setMethod = function(varValue) {
		if (typeof varValue == 'string') {
			varMethod = varValue;
		}
		else {
			throw 'Invalid arguments [String expected]: Ajax.setMethod(string)';
		}
	}
	
	/**
	 *	setAsynchronous
	 *
	 *	Method of AJax object to set whether the request 
	 *	should be made asynchronous. If it is asynchronous, 
	 *	the javascript will still be intepreted after the 
	 *	send method has been invoked. Otherwise, it will 
	 *	continue only after the browser has received the 
	 *	response from the server.
	 */
	this.setAsynchronous = function(varValue) {
		if (typeof varValue == 'boolean') {
			isAsynchronous = varValue;
		}
		else {
			throw 'Invalid arguments [Boolean expected]: Ajax.setAsynchronous(boolean)';
		}
	}
	
	/**
	 *	setReturnXml
	 *
	 *	Method of an Ajax object. Provides the flexibility 
	 *	for the response of a server. If setReturnXml is true, 
	 *	the engine expect an XML string as a response and the 
	 *	response will be parsed as an XML DOM object.
	 */
	this.setReturnXml = function(varValue) {
		if (typeof varValue == 'boolean') {
			isXml = varValue;
		}
		else {
			throw 'Invalid arguments [Boolean expected]: Ajax.setReturnXml(boolean)';
		}
	}
	
	/**
	 *	addParam
	 *
	 *	Method of an Ajax object to add parameters to the 
	 *	request made to a server.
	 */
	this.addParam = function(varName, varValue) {
		if (typeof varName == 'string' &&
			(typeof varValue == 'string' || typeof varValue == 'number')) {

			var varParam = new Parameter(varName, varValue);
			varParameters[varParameters.length] = varParam;
		}
	}
	
	/**
	 *	setAwaiting
	 *
	 *	Method of an Ajax object to define the function 
	 *	which will be executed after a request has been 
	 *	made and while awaiting for the server response.
	 */
	this.setAwaiting = function(varValue) {
		if (typeof varValue == 'function') {
			varAwaiting = varValue;
		}
		else {
			throw 'Invalid arguments [Function expected]: Ajax.setAwaiting(function)';
		}
	}
	
	/**
	 *	setSuccess
	 *
	 *	Method of an Ajax object to define the function
	 *	which will be executed after a request has been 
	 *	made and the response returned is successful.
	 */
	this.setSuccess = function(varValue) {
		if (typeof varValue == 'function') {
			varSuccess = varValue;
		}
		else {
			throw 'Invalid arguments [Function expected]: Ajax.setSuccess(function)';
		}
	}
	
	/**
	 *	setFail
	 *
	 *	Method of an Ajax object to define the function
	 *	which will be executed after a request has been 
	 *	made and the response returned is unsuccessful.
	 */
	this.setFail = function(varValue) {
		if (typeof varValue == 'function') {
			varFail= varValue;
		}
		else {
			throw 'Invalid arguments [Function expected]: Ajax.setFail(function)';
		}
	}
	
	/**
	 *	run
	 *
	 *	Main method of an Ajax object which should be 
	 *	invoked at the point when a request should be 
	 *	made to the server.
	 */
	this.run = function() {
		if (typeof varSuccess == 'function') {
			var xmlHttp = getXmlHttpRequest(); // creates XMLHttpRequest object
			var varTarget = varURL + getParameters(); // construct target URL
			var isAwaiting = true; // this is to make sure the varAwaiting function is being executed only once
			
			xmlHttp.open(varMethod, varTarget, isAsynchronous);
			xmlHttp.onreadystatechange = function() {
				if (xmlHttp.readyState < 4) { // in process of making request
					if (typeof varAwaiting == 'function' && isAwaiting) { // executes varAwaiting function if available
						varAwaiting();
						isAwaiting = false;
					}
				}
				else if (xmlHttp.readyState == 4) { // request made and response received
					if (xmlHttp.status == 200) { // status is OK
						var varResponse = xmlHttp.responseText;
						
						if (isXml) { // parse response to XML document if necessary
							varResponse = parseXML(varResponse);
						}
						varSuccess(varResponse); // executes varSuccess function
					}
					else { // status is NOT OK
						var varException = new RequestException(xmlHttp.status);
						if (typeof varFail == 'function') { // executes varFail function if available
							varFail(varException);
						}
						else { // otherwise, display alert
							alert(varException.getMessage());
						}
					}
				}
			}
			
			xmlHttp.send(null);
		}
		else {
			throw 'Undefined function';
		}
	}
	
	/**
	 *	RequestException
	 *
	 *	Private helper object for Ajax to display an 
	 *	error message.
	 */
	function RequestException(varStatus) {
		var varMessage = new String();
		
		switch (varStatus) {
			case 301:
				varMessage = 'Moved Permanently';
				break;
			case 302:
				varMessage = 'Found (the request was redirected to another URL/URI)';
				break;
			case 305:
				varMessage = 'Use Proxy (the request must use a proxy to access the resource requested)';
				break;
			case 401:
				varMessage = 'Unauthorized';
				break;
			case 403:
				varMessage = 'Forbidden';
				break;
			case 404:
				varMessage = 'Not Found';
				break;
			default:
				varMessage = 'Unknown Error';
				break;
		}
		
		varMessage = 'Error: ' + varMessage + '\nStatus: ' + varStatus;
		
		this.getMessage = function() {
			return varMessage;
		}
	}
	
	/**
	 *	getParameters
	 *
	 *	Private helper method for Ajax to construct
	 *	a string of parameters in a URL.
	 */
	function getParameters() {
		var varString = new String();
		
		for (var i = 0; i < varParameters.length; i++) {
			if (i == 0) {
				varString = '?';
			}
			else {
				varString += '&';
			}
			
			varString += varParameters[i].ParameterName + '=' + varParameters[i].ParameterValue;
		}
		
		return varString;
	}
	
	/**
	 *	getXmlHttpRequest
	 *
	 *	Private helper method to create XMLHttpRequest object, 
	 *	which is the core of AJAX concept.
	 */
	function getXmlHttpRequest() {
		var xmlHttp = null;
		
		try {
			xmlHttp = new XMLHttpRequest();
		}
		catch (e) {
			try {
				xmlHttp = new ActiveXObject('Msxml2.XMLHTTP');
			}
			catch (e) {
				try {
					xmlHttp = new ActiveXObject('Microsoft.XMLHTTP');
				}
				catch (e) {
					alert('The browser you are using does not support AJAX. Please update the version of you browser.');
				}
			}
		}
		
		return xmlHttp;
	}
	
	/**
	 *	parseXML
	 *
	 *	Pirvate helper method to parse XML text to 
	 *	XML document object.
	 */
	function parseXML(varXmlText) {
		var varXmlDocument;
		
		if (window.ActiveXObject) { // IE
			varXmlDocument = new ActiveXObject('Microsoft.XMLDOM');
			varXmlDocument.async = 'false';
			varXmlDocument.loadXML(varXmlText);
		}
		else { // Mozilla, Firefox, Opera, etc.
			var parser = new DOMParser();
			varXmlDocument = parser.parseFromString(varXmlText, 'text/xml');
		}
		
		if (varXmlDocument.documentElement) {
			return varXmlDocument.documentElement;
		}
		else {
			return varXmlDocument;
		}
	}
}
function validateField(form,field) {
	try {
		var url = "";
		url = "/security/warranty_validation.jsp?" + field.name + "=" + field.value;
		var varAjax = new Ajax(url);
		varAjax.setMethod('POST');
		varAjax.setAsynchronous(true);
		varAjax.setReturnXml(false);
		varAjax.setAwaiting( function() {
			// code your stuffs here
				document.getElementById(field.name+ "_").innerHTML = "<span align=center><img src='/images/ajax-loader.gif'>Validating</span>";
			});
		varAjax.setSuccess( function(varResponse) {
			// code your stuffs here
				if (varResponse.indexOf("-") != -1){
					document.getElementById(field.name+ "_").innerHTML = "<span align=center><img src='/images/wrong.gif'></span>" + varResponse;
					document.getElementById(field.name).style.fontWeight = "bold";
					document.getElementById(field.name).style.backgroundColor = "#FFF2BF";
				}else{
					document.getElementById(field.name+ "_").innerHTML = "<span align=center><img src='/images/correct.gif'></span>";
					document.getElementById(field.name).style.fontWeight = "normal";
					document.getElementById(field.name).style.backgroundColor = "#FFFFFF";
				}
			});
		varAjax.setFail( function(varException) {
			// code your stuffs here
			});
		var exs = varAjax.run();
	} catch (e) {
		alert(e);
	}
}
function displayDispatched(form,field,x11,sc,x11s) {
	try {
		var url = "";
		url = "/security/displayDispatched.jsp?x11="+ x11s + "&x11s="+ x11 + "&s=" + field.value;
		var varAjax = new Ajax(url);
		varAjax.setMethod('POST');
		varAjax.setAsynchronous(true);
		varAjax.setReturnXml(false);
		varAjax.setAwaiting( function() {
			// code your stuffs here
				document.getElementById("resultPane").innerHTML = "<span align=center><img src='/images/ajax-loader.gif'></span>";
			});
		varAjax.setSuccess( function(varResponse) {
			// code your stuffs here
					document.getElementById("resultPane").innerHTML = varResponse;
			});
		varAjax.setFail( function(varException) {
			// code your stuffs here
			document.getElementById("resultPane").innerHTML = varException;
			});
		var exs = varAjax.run();
		
	} catch (e) {
		alert(e);
	}
}