// Ajax framework by Mike Alexander 2010

/* ************************************************* USAGE *********************************************************** */
/*                                                                                                                     */
/*    function aj_setHandler(name, url, async)         - creates a new handler with the specified name and URL         */
/*                                                                                                                     */
/*    aj_startHandler(name, command, callback, params) - send the command to the specified handler,                    */
/*                                                       with the specified parameters, using the                      */
/*                                                       specified callback handler function                           */
/*                                                                                                                     */
/*    aj_getResponse(handlerName)                      - gets the response                                             */
/*                                                                                                                     */
/*    aj_getResponseLines(handlerName)                 - gets the response, split into lines                           */
/*                                                                                                                     */
/*    aj_flush(handlerName)                            - flushes the handler                                           */
/*                                                                                                                     */
/* ******************************************************************************************************************* */
 


function aj_handler(url, async){
  this.xhr = null;
  this.url = url;
  this.async = async;
  this.xstatus = 0;
  this.xstate = 0;  
  this.ready = true;  
  this.cancelled = false;
  this.responseLines = null;
  var self = this;
  
  // flushes the object and its data
  this.flush = function(){
    self.xhr = null;
	self.responseLines = null;
  }
  
  // aborts the current operation
  this.abort = function(){
    if (self.xstate<4 && self.xhr) self.xhr.abort();
	this.ready = true;
	this.cancelled = true;
    self.flush();
  }
  
  // starts a query and registers the callback
  this.start = function(command, callback, params){  
    self.command = command;
    self.callback = callback;  
    try {  // Firefox, Opera 8.0+, Safari  
      this.xhr=new XMLHttpRequest();
    }
    catch (e) {  // Internet Explorer  
      try {    
        this.xhr=new ActiveXObject("Msxml2.XMLHTTP");    
      }
      catch (e) {
        try {
          this.xhr=new ActiveXObject("Microsoft.XMLHTTP");      
	    }
        catch (e) {
          alert("Your browser does not support AJAX!");      
	      return false;      
	    }
      }
    }
  		      
    var rn = "gcac" + (Math.random()*1234567);  // random ref
    var getparams = "rn="+rn+"&ajcom="+command;
    for (var i in params){
	  var val=params[i];	  
	  var ui = i.replace("/ /g", "_");
	  getparams += "&"+ui+"="+(aj_urlencode(val));  
	}  
    var theurl = self.url+"?"+getparams;
	document.lastajajaxurl = theurl;	
    self.xhr.open("GET",theurl,self.async);
    self.xhr.send(null);  		
	var sself = self;
	self.xhr.onreadystatechange=function() 
	{  
	  if (sself.cancelled) return;    
	  sself.xstate = sself.xhr.readyState;
      if (sself.xstate==4) {
		sself.xstatus = sself.xhr.status;				               // get response http status
	    if (sself.xstatus >= 400 || sself.xstatus==0)
	      sself.responseLines = new Array("1", "ERROR", ("server error "+sself.xstatus+" occurred"));
	    else 		  
		  sself.responseLines = sself.xhr.responseText.split("\r\n");  // get response as array
	  }  
	  sself.ready = false;	  // flag: state needs processing
	}	
  }    
}

// start the response monitor
function aj_start_monitor(first){
  if (first) alert("Monitor started");
  for (var i in document.aj_handlers){
    var jifobj = document.aj_handlers[i];
	if (jifobj.ready) continue;
	jifobj.ready = true;
	if (jifobj.xstate==4) {
	  eval(jifobj.callback+"();");
	}  
  }
  document.aj_monitor_id = window.setTimeout("aj_start_monitor();", 100);
}

// add an ajax handler
function aj_setHandler(name, url, async){
  if (!document.aj_handlers) {
    document.aj_handlers = new Object();
    aj_start_monitor();	
  }	
  var handler = new aj_handler(url, async);
  document.aj_handlers[name]=handler;
}

// start an ajax handler request
function aj_startHandler(name, command, callback, params){
  if (!document.aj_handlers[name]) return false;
  var handler = document.aj_handlers[name];
  handler.start(command, callback, params);
}

// get a handler by name
function aj_getHandler(name){
  try {
    return document.aj_handlers[name];
  }
  catch(ex) { return false; }	
}

// get response text from handler by name
function aj_getResponse(name){
  var handler = aj_getHandler(name);
  if (!handler) return false;
  if (handler.xstate!=4) return false;
  return handler.xhr.responseText;
}

// get response text as array of lines from handler by name
function aj_getResponseLines(name){
  var handler = aj_getHandler(name);
  if (!handler) return false;
  if (handler.xstate!=4) return false;
  return handler.responseLines;
}

// flush a handler
function aj_flush(name){
  var handler = aj_getHandler(name);
  if (!handler) return false;
  if (handler.xstate!=4) return false;
  handler.flush();
  return true;
}

function aj_flushAll(){
  if (!document.aj_handlers) return;
  for (var i in document.aj_handlers){
    document.aj_handlers[i].flush();
  }
}

function aj_abortAll(){
  if (!document.aj_handlers) return;
  for (var i in document.aj_handlers){
    document.aj_handlers[i].abort();
  }
}

function aj_unload(){
  aj_flushAll();
  if (document.aj_monitor_id) window.clearTimeout(document.aj_monitor_id);
}

function aj_urlencode(str) {
return escape(str).replace(/\+/g,'%2B').replace(/%20/g, '+').replace(/\*/g, '%2A').replace(/\//g, '%2F').replace(/@/g, '%40');
}
