 /****************************************************************************
  * AJAX Wrapper
  *
  * Author: Timothy M. Crider (timcrider@gmail.com)
  *
  * Description:
  *  Multiple AJAX handler, written to handle the problem of the old single
  * 'req' format. Each indivual request is identified by using a unique
  * namespace. Global variable 'TA' is created at the end of this file.
  *
  *****************************************************************************
  *
  * TODO
  * 
  * Add Error Stack
  *
  *****************************************************************************
  *
  * EXAMPLE
  *
  *<html>
  * <head>
  *  <script src="main.js" type="text/javascript"></script>
  *  <script src="t_ajax.js" type="text/javascript"></script>
  *  <script type="text/Javascript">
  *   function g33x()
  *   {
  *     if (!(r = TA.fetchText('g33x')))
  *         return false;
  *
  *      $$('putHere').innerHTML = r;
  *   }
  *
  *   TA.addRequest('g33x', 'timDat.txt', g33x);
  *
  *  </script>
  *</head>
  *<body>
  *<input type="button" value="G33X" onClick="TA.send('g33x');">
  *<br>
  *<div id="putHere">This is main content</div>
  *</body>
  *</html>
  *
  ****************************************************************************/

 //////////////////////////////////////////////////////////////////////////////
 //
 // AJAX STRUCT
 //
 //////////////////////////////////////////////////////////////////////////////
 function t_ajax_request(ns, url, _function)
 {
    this.req       = null;        // Request Pointer
    this.ns        = ns;          // Namespace Identifier
    this.url       = url;         // Web Address
    this.method    = "GET";       // Posting Method (to be added)
    this.result    = false;       // Resulting HTML/XML/Text
    this._function = _function;   // Request Processing Function
 } // End 't_ajax_request'

 //////////////////////////////////////////////////////////////////////////////
 //
 // INIT AJAX CONTAINER
 //
 //////////////////////////////////////////////////////////////////////////////
 function t_ajax()
 {
    // Variables
    this.req  = Array(); // Request Stack
    this.size = 0;       // Request Stack Size
    this.requests = 0;   // Total Requests Processed

    // Methods
    this.getLength   = t_ajax_getLength;      // Get Request Stack Length
    this.findRequest = t_ajax_findRequest;    // Find Request In Stack
    this.addRequest  = t_ajax_addRequest;     // Add Requeest To Stack
    this.send        = t_ajax_processRequest; // Send Request
    this.fetchText   = t_ajax_responseText;   // Fetch Request Text
    this.fetchXML    = t_ajax_responseXML;    // Fetch Request XML
 } // End 'init_t_ajax'

 //////////////////////////////////////////////////////////////////////////////
 //
 // Get size of the request stack
 //
 //////////////////////////////////////////////////////////////////////////////
 function t_ajax_getLength()
 {
    // Return the size of the request stack
    return this.req.length;
 } // End 't_ajax_getLength'

 //////////////////////////////////////////////////////////////////////////////
 //
 // Find the request in the stack
 //
 //////////////////////////////////////////////////////////////////////////////
 function t_ajax_findRequest(ns)
 {
    // Cycle through request stack
    for (var i = 0; i < this.getLength(); i++)
    {
       // Compare request namespace to current stack
       if (ns == this.req[i].ns)
          return this.req[i];
    }

    // Namespace not in stack
    return false;
 } // End 't_ajax_findRequest'

 //////////////////////////////////////////////////////////////////////////////
 //
 // Add a request to the stack
 //
 //////////////////////////////////////////////////////////////////////////////
 function t_ajax_addRequest(ns, url, _function)
 {
    // Find Current Request
    var _c = this.findRequest(ns);

    // If request exists, update the request info
    if (_c)
    {
       _c.url       = url;
       _c._function = _function;
       return;
    }

    // Create the new request and push it on the stack
    var _t = this.getLength();
    this.req[_t] = new t_ajax_request(ns, url, _function);

    return;
 } // End 't_ajax_addRequest'

 //////////////////////////////////////////////////////////////////////////////
 //
 // Process the request and handle result storage
 //
 //////////////////////////////////////////////////////////////////////////////
 function t_ajax_processRequest(ns)
 {
    // Find the current request
    var t_ns = this.findRequest(ns);

    // Test Stack
    if (!t_ns)
    {
       return false;
    }

    // Test for AJAX compat
    if(window.XMLHttpRequest)
    {
       // Try to create the request
       try
       {
          t_ns.req = new XMLHttpRequest();
       }
       catch(e)
       {
          t_ns.req = false;
       }
    }
    else if(window.ActiveXObject)
    {
       try
       {
          t_ns.req = new ActiveXObject('Msxml2.XMLHTTP');
       }
       catch(e)
       {
          try
          {
             t_ns.req = new ActiveXObject('Microsoft.XMLHTTP');
          }
          catch(e)
          {
             t_ns.req = false;
          }
       }
    }

    // Check request creation
    if (t_ns.req)
    {
       // Assign processing function
       t_ns.req.onreadystatechange = t_ns._function;

       // Setup the request
       t_ns.req.open(t_ns.method, t_ns.url, true);

       // Send the request
       t_ns.req.send('');

       // Count the request
       this.requests++;
    }

    return;
 } // End 't_ajax_processRequest'

 //////////////////////////////////////////////////////////////////////////////
 //
 // Process Text Output
 //
 //////////////////////////////////////////////////////////////////////////////
 function t_ajax_responseText(ns)
 {
    // Fetch the request
    var r = TA.findRequest(ns);  

    // Check to make sure request exists
    if (!r.req)
       return null;

    // Check for response 
    if (r.req.responseText)
    {
       // Store response 
       var out = r.req.responseText;

       // Reset the request. (Fix for double assignment)
       r.req = false;

       return out;
    }

    return;
 } // End 't_ajax_responseText'

 //////////////////////////////////////////////////////////////////////////////
 //
 // Process XML Output
 //
 //////////////////////////////////////////////////////////////////////////////
 function t_ajax_responseXML(ns)
 {
    // Fetch the request
    var r = TA.findRequest(ns);  

    // Check to make sure request exists
    if (!r.req)
       return null;

    // Check for response
    if (r.req.responseXML)
    {
       // Store response
       var out = r.req.responseXML;

       // Reset the request. (Fix for double assignment)
       r.req = false;

       return out;
    }

    return;
 } // End 't_ajax_responseXML'


 function emptySend(url)
 {
	TA.addRequest('__throwaway__', url, _emptyFunction);
	TA.send('__throwaway__');
 }

 //////////////////////////////////////////////////////////////////////////////
 //
 // Create The TA object (global)
 //
 //////////////////////////////////////////////////////////////////////////////
 var TA = new t_ajax();