/**
 * rageAjax class designed to ease dynamic client-server communication.
 * Created by Łukasz Drożdż
 * 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.9b, 2010-01-10
 **/
 
if(!window.__rageLib){
  window.__rageLib = {};
  window.__rageLib.instances = {};
}

__rageLib.rageAJAXController = function(){};

__rageLib.rageAJAXController.prototype = {
  ajax: [],
  getNextId: function(){
    return this.ajax.length; 
  },
  addAJAX: function(ax){
    var idx = this.getNextId();
    this.ajax[idx] = ax;
    return idx;
  }
};

__rageAJAXController = new __rageLib.rageAJAXController();

__rageLib.rageAJAX = function(params){        
  this.params = new Array();
  this.XmlHttpRequestObject = null;
  
  this.queue = new Array();
  this.postParamsQueue = new Array();

  this.requestURL = null; //proper method of supplying get
  this.postParams = null; //, //??
  
  this.defaultOnChange = null; //??
  this.onSuccess = null; //??
  this.controllerIdx = null; //OK
  
  //alert(this.params['O']);
  this.construct();
  if(params) 
    this.create(params);
  
};

__rageLib.rageAJAX.prototype = {
  //XmlHttpRequestObject: null,  //ok
  //params: [],  //main obj params
  
  //queue: [],  //OK
  //postParamsQueue: [], //OK

  //requestURL: null, //proper method of supplying get
  //postParams: null, //??
  
  //defaultOnChange: null, //??
  //onSuccess: null, //??
  //controllerIdx: null, //OK
  
  toString: function(){ return 'rageAjax Object'; },
  construct: function(){  //PROBABLY OK
    this.controllerIdx = __rageAJAXController.addAJAX(this);
    this.defaultOnChange = this.stdOnChangeProcess;
  },
  createXmlHttpRequestObject: function(){  //OK
	  var xmlHttp;
	  try{
	    xmlHttp = new XMLHttpRequest();
	  }catch(e){
		  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{
  		 	  xmlHttp = new ActiveXObject(XmlHttpVersions[i]);
  			}catch (e) {}
		  }
    }
	  if (!xmlHttp) alert("Error creating the XMLHttpRequest object.");
   	else return xmlHttp;
  },
  setXmlHttpRequestObject: function(obj, params){ //OK
    if(!obj) return false;
    
    if(params){
	    //this.XmlHttpRequestParam['REQUEST_MODE'] = params['REQUEST_MODE'] ? params['REQUEST_MODE'] : 'POST';
	    this.params['URL'] = params['URL'] ? params['URL'] : null;
	    this.params['URL_MAKER'] = params['URL_MAKER'] ? params['URL_MAKER'] : '';
	    this.params['ON_READY'] = params['ON_READY'] ? params['ON_READY'] : this.defaultOnChange;
	    this.params['ON_SUCCESS'] = params['ON_SUCCESS'] ? params['ON_SUCCESS'] : '';
      //if(this.controllerIdx == 1) alert(__rageAJAXController.ajax[0].params['ON_SUCCESS']);
    }
    
    
    return this.XmlHttpRequestObject = obj;
  },
  setURL: function(new_url){
    this.params['URL'] = new_url;
  },
  makeURL: function(){ //OK
   	if(this.params['URL_MAKER']){
	    var f_urlMaker = this.params['URL_MAKER'];
	    return f_urlMaker();
	  }else{
	    return this.params['URL'] ? this.params['URL'] : null;
	  }
  },
  addToQueue: function(){
    this.queue.push(this.makeURL());
    this.postParamsQueue.push(this.postParams ? this.postParams : '');
  },
  getQueueLength: function(){
    return this.queue.length;
  },
  process: function(postParams){
    //alert(this.controllerIdx+this.params['ON_SUCCESS']);
    if(postParams != undefined){
      this.postParams = postParams;
    }
    try{
      if(!this.XmlHttpRequestObject) return false;
      if(this.XmlHttpRequestObject.readyState != 0 && this.XmlHttpRequestObject.readyState != 4){
        this.addToQueue();
        setTimeout('__rageAJAXController.ajax[\''+this.controllerIdx+'\'].checkQueue()', 100);
        return;
      }
	    this.sendRequest();
	  }catch(e){}
  },
  checkQueue: function(){
    if(this.XmlHttpRequestObject.readyState != 0 && this.XmlHttpRequestObject.readyState != 4){
      setTimeout('__rageAJAXController.ajax[\''+this.controllerIdx+'\'].checkQueue()', 100);
    }else this.sendRequest();
  },
  sendRequest: function(){
    try{ // try to connect to the server
      if(this.queue.length){
        var requestURL = this.queue.shift();
        this.postParams = this.postParamsQueue.shift();
      }else{
        var requestURL = this.makeURL();
      }
      eval('var temp = '+((this.params['ON_READY']+'').replace('"AJAX_IDX"', this.controllerIdx).replace('\\"AJAX_IDX\\"', ''+this.controllerIdx)));
      //alert(temp);
      //alert(__rageAJAXController.ajax[1].params.ON_SUCCESS);
      this.XmlHttpRequestObject.open('POST', 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;
      
      this.XmlHttpRequestObject.send(this.postParams);
	  }catch(e){
	    alert("Can't connect to server:\n" + e.toString());
	  }
  },
  stdOnChangeProcess: function(){
    var AjaxObject = __rageAJAXController.ajax['"AJAX_IDX"'];
    var XmlHttp = AjaxObject.getXMLObject();
    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.params['ON_SUCCESS']){
            //alert(AjaxObject.controllerIdx + AjaxObject.params['ON_SUCCESS']);
            var f = AjaxObject.params['ON_SUCCESS'];  f(XmlHttp);
          }else{
            //alert(XmlHttp.responseText);
          }
        }catch(e){ // display error message
          if(AjaxObject.params['ON_ERROR']){
            //var f = AjaxObject.params['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);
      }
    }
	},
  create: function(params){ 
    var t = this.createXmlHttpRequestObject();
    return this.setXmlHttpRequestObject(t, params);
  },
  getObject: function(nameFlag, xmlObjOnly){
    var temp = null;
    if(!nameFlag) temp = this;
    else  		   temp = __tempRageAjaxRefs[nameFlag] ? __tempRageAjaxRefs[nameFlag] : this;
    return xmlObjOnly ? temp.XmlHttpRequestObject : temp;
  },
  getXMLObject: function(nameFlag){
    var temp = null;
    if(!nameFlag) temp = this;
    else  		   temp = __tempRageAjaxRefs[nameFlag] ? __tempRageAjaxRefs[nameFlag] : this;
    return temp.XmlHttpRequestObject;
  }
};

/*
  var params = new Array();
  params['URL'] = 'los.php';
  params['ON_SUCCESS'] = function(XmlHttp){ alert(XmlHttp.responseText); };
  
  var test = new __rageLib.rageAJAX(params);
  test.process();
*/