/**
 * rageAjax class designed to ease dynamic client-server communication.
 * Created by £ukasz Dro¿d¿, Faculty of Physics, Warsaw University of Technology
 * In case of any suggestions/questions please contact me at: lucas.drozdz@gmail.com
 * Released under LGPL license - as long as You keep this authoring comment, feel free to modify/distribute this class as your need.
 * Version 0.8, 2007-09-27
 **/
var __tempRageAjaxRefs = new Array();

function rageAjax(name, params, debugFlag){
   /* PRIVATE VARIABLES & FUNCTIONS */
   var XmlHttpRequestObject;
   var XmlHttpRequestParam; ;
   var debug;
   var ajaxName;
   var busy;
   var queue;

   var requestMode;
   var requestURL;
   var postParams;
   var defaultOnChange
   var onSuccess;

   /* PRIVILEGED METHODS  */
   this.toString = function(){ return 'rageAjax Object'; }
   this.construct = function(nameMe, debugFlag){
      this.XmlHttpRequestObject = null;
      this.XmlHttpRequestParam = new Array();
      this.debug = true && debugFlag;
      this.requestMode = 'POST';
      this.requestURL = '';
      this.ajaxName = nameMe ? nameMe : '__STD__';
      this.defaultOnChange = this.stdOnChangeProcess;
      this.busy = false;
      this.queue = new Array();       //url (GET) queue
      this.postQueue = new Array();   //POST queue
      this.methodQueue = new Array(); //next method type
   }

   this.createXmlHttpRequestObject = function(){
	   var xmlHttp;
	   try{  // this should work for all browsers except IE6 and older
	     xmlHttp = new XMLHttpRequest(); // try to create XMLHttpRequest object
	   }catch(e){ // assume IE6 or older
		   var XmlHttpVersions = new Array("MSXML2.XMLHTTP.6.0",
											"MSXML2.XMLHTTP.5.0",
											"MSXML2.XMLHTTP.4.0",
											"MSXML2.XMLHTTP.3.0",
											"MSXML2.XMLHTTP",
											"Microsoft.XMLHTTP");
		   for (var i=0; i<XmlHttpVersions.length && !xmlHttp; i++){ // try every prog id until one works
				try{ // try to create XMLHttpRequest object
			 	  xmlHttp = new ActiveXObject(XmlHttpVersions[i]);
				}catch (e) {}
		   }
     }
	   if (!xmlHttp) alert("Error creating the XMLHttpRequest object.");
   	   else return xmlHttp;
   }

   this.setXmlHttpRequestObject = function(obj, params){
     if(!obj) return null;
     if(params){
	     this.XmlHttpRequestParam['REQUEST_MODE'] = params['REQUEST_MODE'] ? params['REQUEST_MODE'] : 'POST';
	     this.XmlHttpRequestParam['URL'] = params['URL'] ? params['URL'] : null;
	     this.XmlHttpRequestParam['URL_MAKER'] = params['URL_MAKER'] ? params['URL_MAKER'] : '';
	     this.XmlHttpRequestParam['ON_READY'] = params['ON_READY'] ? params['ON_READY'] : this.defaultOnChange;
	     this.XmlHttpRequestParam['ON_SUCCESS'] = params['ON_SUCCESS'] ? params['ON_SUCCESS'] : '';
     }
     return this.XmlHttpRequestObject = obj;
   }

   this.makeURL = function(){
   	if(this.XmlHttpRequestParam['URL_MAKER']){
		   var f_urlMaker = this.XmlHttpRequestParam['URL_MAKER'];
		   return f_urlMaker();
		}else{
		   return this.XmlHttpRequestParam['URL'] ? this.XmlHttpRequestParam['URL'] : null;
		}
   }
   
   this.addToQueue = function(){
     this.queue.push(this.makeURL());
     this.postQueue.push(this.postParams ? this.postParams : '');
     this.methodQueue.push(this.XmlHttpRequestParam['REQUEST_MODE'] ? this.XmlHttpRequestParam['REQUEST_MODE'] : 'POST');
   }

   this.getQueueLength = function(){
     return this.queue.length;
   }

   this.process = function(){
      try{
        if(!this.XmlHttpRequestObject) return false;
        if(this.XmlHttpRequestObject.readyState != 0 && this.XmlHttpRequestObject.readyState != 4){
          this.addToQueue();
          setTimeout('__tempRageAjaxRefs[\''+this.ajaxName+'\'].checkQueue()', 100);
          return;
        }
		    this.sendRequest();
		  }catch(e){
		    
		  }
   }

   this.checkQueue = function(){
       if(this.XmlHttpRequestObject.readyState != 0 && this.XmlHttpRequestObject.readyState != 4){
          setTimeout('__tempRageAjaxRefs[\''+this.ajaxName+'\'].checkQueue()', 100);
       }else this.sendRequest();
   }

   this.sendRequest = function(s){
   
   		try{ // try to connect to the server

		    if(this.queue.length){
		      var requestURL = this.queue.shift();
		      var requestMode = this.methodQueue.shift();
		      this.postParams = this.postQueue.shift();
		    }else{
					var requestURL = this.makeURL();
					var requestMode = this.XmlHttpRequestParam['REQUEST_MODE'] ? this.XmlHttpRequestParam['REQUEST_MODE'] : 'POST';
				}
				
		    var onReady = this.XmlHttpRequestParam['ONREADY'] ?
			              this.XmlHttpRequestParam['ONREADY'] : this.defaultOnChange;

			__tempRageAjaxRefs[this.ajaxName] = this; //.XmlHttpRequestObject;
			eval('var temp = '+((onReady+'').replace('"AJAX_OBJ"', this.ajaxName).replace('\\"AJAX_OBJ\\"', this.ajaxName)));

			this.XmlHttpRequestObject.open(requestMode, requestURL, true);
			if(this.postParams){
			  this.XmlHttpRequestObject.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
				this.XmlHttpRequestObject.setRequestHeader("Content-length", this.postParams.length);
	      this.XmlHttpRequestObject.setRequestHeader("Connection", "close");
			}
			this.XmlHttpRequestObject.onreadystatechange = temp;
			
			if(this.postParams){
			  this.XmlHttpRequestObject.send(this.postParams);
		  }else
		    this.XmlHttpRequestObject.send(null);

		}catch(e){
			alert("Can't connect to server:\n" + e.toString());
		}
   }

   this.stdOnChangeProcess = function(){
	    var AjaxObject = __tempRageAjaxRefs['"AJAX_OBJ"'];
	    var XmlHttp = AjaxObject.getXMLObject(); //__tempRageAjaxRefs['"AJAX_OBJ"'].XmlHttpRequestObject;
			if (XmlHttp.readyState == 4){ // when readyState is 4, we are ready to read the server response
				if (XmlHttp.status == 200){ // continue only if HTTP status is "OK"
					try{ // do something with the response from the server
					  if(AjaxObject.XmlHttpRequestParam['ON_SUCCESS']){
							var f = AjaxObject.XmlHttpRequestParam['ON_SUCCESS'];  f(XmlHttp);
						}else
							alert(XmlHttp.responseText);
					}catch(e){ // display error message
						if(AjaxObject.XmlHttpRequestParam['ON_ERROR']){
							var f = AjaxObject.XmlHttpRequestParam['ON_ERROR'];  f(XmlHttp);
						}else
							alert("Error reading server availability:\n" + e.toString());
					}
				}else{ // display status message
					alert("Error reading server availability:\n" + XmlHttp.statusText);
				}
				AjaxObject.busy = false;
			}
	}

   //PUBLIC METHODS
   this.create = function(params){
     return this.setXmlHttpRequestObject(this.createXmlHttpRequestObject(), params);
   }

   this.getObject = function(nameFlag, xmlObjOnly){
     var temp = null;
     if(!nameFlag) temp = this;
     else  		   temp = __tempRageAjaxRefs[nameFlag] ? __tempRageAjaxRefs[nameFlag] : this;
     return xmlObjOnly ? temp.XmlHttpRequestObject : temp;
   }

   this.getXMLObject = function(nameFlag){
     var temp = null;
     if(!nameFlag) temp = this;
     else  		   temp = __tempRageAjaxRefs[nameFlag] ? __tempRageAjaxRefs[nameFlag] : this;
     return temp.XmlHttpRequestObject;
   }

   /*construct*/
   this.construct(name, debugFlag);
   this.create(params);
   /*construct*/

}

