/* AJAX */
/* (C) 2006 Alexandru Ionut Lixandru */
/* Email: alex.lixandru@gmail.com */
/* You may use, copy, distribute, modify... do whatever you want with this file */
/* For commercial applications, this notice should (ideally) stay intact */

/****** ajaxObject *********************************************************************
*
*  - PROPERTIES:
*	- requestMethod      (default: GET; possible values: GET, POST, FAKEPOST)
*	- requestFile        (the requested file; cannot be empty, must be a valid URI)
*	- responseType       (default: TEXT; possible values: TEXT; XML - to change it use method setResponseType)
*	- response           (the response from the server)
*	- postForm           (id of the form, when using POST method)
*	- error              (false if no errors occured or a description of the error)
*          - status
*
*  - METHODS:
*	- makeRequest();     (call this method after creating the object and setting the properties)
*	- abort();     (aborts the current request)
*	- addParam();        (call this method for each parameter you want to send through GET)
*	- setResponseType( type );        (call this method whenever you want to change the response type to XML ot TEXT)
*	- onComplete();      (define the function to execute when the request is completed and OK)
*	- onLoading();       (define the function to execute when the request is loading)
*	- onLoaded();        (define the function to execute after the request was loaded)
*	- onInteractive();   (define the function to execute when the request is in the interactive state)
*
*
****** How to use (critical statements)*************************************************
*
* var req = new ajaxObject();
* req.requestFile = "../dh/js/external/testFile_1.html";
* req.addParam('action', 'delete');
* req.addParam('id', '01');
* // or you can use directly: req = new ajaxObject( 'GET', 'myfile.php?action=list&categid=1', 'XML' );
* req.onComplete = function() {
*       document.getElementById('content1').innerHTML = req.response;
*       //write your code here
*       req = false;
* }
* req.makeRequest();
*
***************************************************************************************/


function ajaxObject(method_ , file_ , response_, form_) {
	this.postForm = "";
	this.status = "0";
	if (method_ == null) this.requestMethod = "GET";  //POST, GET, FAKEPOST ;)
	else {
		this.requestMethod = method_;
		if (form_ == null) { this.error = "You haven't specify a valid form ID for POST method"; return false; }
		else this.postForm = form_;
	}

	if (file_ == null) this.requestFile = "";
	else this.requestFile = file_;
	
	this.queryString = '';
	
	if (response_ == null) this.responseType = "TEXT";
	else this.responseType = response_;

	this.error = false;
	this.req = false;

	var selfInstance = this;
	selfInstance.initialise();
}

ajaxObject.prototype.initialise = function() {
	if (window.XMLHttpRequest) { // Mozilla, Safari, ...
		try {
			this.req = new XMLHttpRequest();
			if (this.req.overrideMimeType) {
				if (this.responseType.toUpperCase() == "XML") { this.req.overrideMimeType('text/xml'); }
				else { this.req.overrideMimeType('text/html'); }
			}
		}
		catch(e) { this.req = false; this.error = "Browser unsuported"; }
	}
	else if (window.ActiveXObject) { // IE
		try { this.req = new ActiveXObject("Msxml2.XMLHTTP"); }
		catch (e) {
			try { this.req = new ActiveXObject("Microsoft.XMLHTTP"); }
			catch (e) { this.req = false; this.error = "Browser unsuported"; }
		}
	}
	
	if (!this.req) {
		this.error = 'Internal error. Cannot initiate the request to the server. Please use Mozilla or Microsoft Internet Explorer';
		return false;
	}
}

ajaxObject.prototype.setResponseType = function(respType) {
	if ( respType ) {
		if ( respType.toUpperCase() == "XML" ) {
			this.responseType = "XML";
			if (this.req.overrideMimeType) { this.req.overrideMimeType('text/xml');	}
		}
		else {
			this.responseType = "TEXT";
			if (this.req.overrideMimeType) { this.req.overrideMimeType('text/html'); }
		}
	}
}

ajaxObject.prototype.abort = function() {
	if ( this.req ) this.req.abort();
	this.queryString = '';
}

ajaxObject.prototype.makeRequest = function() {
	var selfInstance = this;
	var str;

	var rnd77g = Math.random();
	if ( selfInstance.requestFile.indexOf("?") > 0 ) selfInstance.queryString = "&rnd=" + rnd77g;
	else if ( selfInstance.queryString.indexOf("?") > 0 ) selfInstance.queryString += "&rnd=" + rnd77g;
	else selfInstance.queryString = "?rnd=" + rnd77g;
	
	if (this.requestMethod.toUpperCase() == "POST") {
		str = getForm(this.postForm);
		try {
			this.req.open("POST", this.requestFile + this.queryString, true);
			this.req.setRequestHeader("Connection", "close");
			this.req.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
			this.req.setRequestHeader("Content-Length", str.length);
		}
		catch (e) { this.error = "Error while trying to make the request to the server!"; return false; }
	}
	else if (this.requestMethod.toUpperCase() == "FAKEPOST") {
		str = getForm(this.postForm)
		this.req.open("GET", this.requestFile + this.queryString + "&" + str, true);
	}
	else { this.req.open("GET", this.requestFile + this.queryString, true); }



	this.req.onreadystatechange = function() {
		selfInstance.status = selfInstance.req.readyState;
		try {
		switch (selfInstance.req.readyState){
			case 1:
				selfInstance.onLoading();
				break;
			case 2:
				selfInstance.onLoaded();
				break;
			case 3:
				selfInstance.onInteractive();
				break;
			case 4:
				if (selfInstance.req.status == 200) {
					if (selfInstance.responseType.toUpperCase() == "XML") { selfInstance.response = selfInstance.req.responseXML; }
					else { selfInstance.response = selfInstance.req.responseText; }
					selfInstance.onComplete();
				}
				else {
					selfInstance.error = "Error " + selfInstance.req.status;
					return false;
				}
				break;
		}
		}
		catch( e ) {
			selfInstance.error = 'Caught Exception: ' + e.description;
		}
	}

	this.req.send(str);
}

ajaxObject.prototype.addParam = function(pName, pValue) {
	this.queryString += "&" + pName + "=" + pValue;
}
ajaxObject.prototype.onLoading = function() { };
ajaxObject.prototype.onLoaded = function() { };
ajaxObject.prototype.onInteractive = function() { };
ajaxObject.prototype.onComplete = function() { };

function getForm(fID) {
	var str = "";
	var lastElemName = "";
	var fv = "";
	var fn = "";
	var els = "";
	var fobj = document.getElementById(fID);
	for(var i = 0;i < fobj.elements.length;i++) {
		els = fobj.elements[i];
		fv = els.value;
		fn = els.name;
		switch(els.type) {
			case "text":
			case "hidden":
			case "password":
			case "textarea":
				str += fn + "=" + encodeURIComponent(fv) + "&";
				break;
			case "radio":
				if(els.checked) str += fn + "=" + encodeURIComponent(fv) + "&";
				break;
			case "checkbox":
				if (els.checked) {
					// Continuing multiple, same-name checkboxes
					if (fn == lastElemName) {
						// Strip of end ampersand if there is one
						if (str.lastIndexOf('&') == str.length-1) {
						str = sre.substr(0, str.length - 1);
					}
					// Append value as comma-delimited string
					str += "," + encodeURIComponent(fv);
					}
					else { str += fn + "=" + encodeURIComponent(fv); }
					str += "&";
					lastElemName = fn;
				}
				break;
			case "select-one":
				str += fn + "=" +
				els.options[els.selectedIndex].value + "&";
				break;
		} // switch
	} // for
	str = str.substr(0,(str.length - 1));
	return str;
}