/*
    +----------------------------------------------------------------------+
    | JavaScript Function                                                  |
    +----------------------------------------------------------------------+
    | NAME: jax                                                            |
    |                                                                      |
    | AUTHOR: Chad Kuehn <chadkuehn@gmail.com>                             |
    |                                                                      |
    | DESCRIPTION:                                                         |
    |   Used for server interaction with JavaScript.                       |
    |                                                                      |
    | PARAMETERS:                                                          |
    |   callback = A callback function to be executed once data is         |
    |               retrieved.                                             |
    |   url      = The url to be executed.                                 |
    |   mode     = Boolean value for retrieval.  Retrieval mode can be     |
    |              asynchronously (true) or synchronously (false).         |
    |              In programming, asynchronous calls are those occurring  |
    |              independently of the main program flow.  Synchronous    |
    |              calls are executed simultaneously, appending to main    |
    |              program flow.                                           |
    |                                                                      |
    | DETAILS:                                                             |
    |   A callback function is not required.  If not desired then the url  |
    |   should be the first argument.  If no callback function is          |
    |   declared and you choose synchronous mode (false) then it will      |
    |   return the information immediately (e.g., res = jax();)            |
    |                                                                      |
    |   If using a callback, then put its name without quotes or           |
    |   parenthesis.  If it doesn't exist, or parameters are needed then:  |
    |     function(){alert('');}                                           |
    |     function(){whatever(100, true);}                                 |
    |                                                                      |
    |   Supportive browsers include: Microsoft Internet Explorer 5+,       |
    |   and browsers based on it (Mac OS versions not supported).          |
    |   Gecko-based browsers like Mozilla, Mozilla Firefox, SeaMonkey,     |
    |   Epiphany, Galeon and Netscape version 7.1+.  Browsers              |
    |   implementing the KHTML API version 3.2+, including                 |
    |   Konqueror 3.2+, and Apple Safari 1.2+. Mac OS X 10.3 is required   |
    |   for the Apple Safari 1.2.  Opera browsers 8+, including            |
    |   Opera Mobile 8.0+.                                                 |
    |                                                                      |
    |   http://en.wikipedia.org/wiki/Ajax_%28programming%29                |
    +----------------------------------------------------------------------+
    | Copyright (c) chadkuehn.com                                          |
    +----------------------------------------------------------------------+
*/

function jax()
{
  var oJax = createHttpRequest();
  var sBrowser = (document.all ? 'Explorer' : 'DOM');

  var callback;
  var sUri;
  var bAsync;

  var argCnt = arguments.length;
  switch(argCnt)
  {
    case 3:
      if((typeof arguments[0] == 'function') && (typeof arguments[1] == 'string') && (typeof arguments[2] == 'boolean'))
      {
        callback = arguments[0];
        sUri = arguments[1];
        bAsync = arguments[2];
      }
      break;
    case 2:
      if((typeof arguments[0] == 'function') && (typeof arguments[1] == 'string'))
      {
        callback = arguments[0];
        sUri = arguments[1];
        bAsync = true; 
      }
      else if((typeof arguments[0] == 'string') && (typeof arguments[1] == 'boolean'))
      {
        sUri = arguments[0];
        bAsync = arguments[1];
      }
      break;
    case 1:
      if(typeof arguments[0] == 'string')
      {
        sUri = arguments[0];
        bAsync = true;
      }
      break;
  }

  if(!sUri)
  {
    alert('Invalid jax call!');
    return;
  }


  // ----- unknown browser -----
  if (!oJax)
  {
    alert('Unsupported Browser!');
    return false;
  }
  switch (sBrowser)
  {
    case "Explorer":
     oJax.onreadystatechange = function()
     {
       if ((oJax.readyState == 4) && (oJax.status == 200))
       {
         var sRtnText = oJax.responseText;

         //--- login session timer
         //if(sUri.substr(0, 5) != '/misc')
         //{
         //  var win = window;
         //  while (win.opener != null)
         //  {
         //    win = win.opener;
         //  }
         //  var logdur = win.document.getElementById('login_duration').innerHTML;

         //  if ((sUri.substr(0, 17) != '/jax/get.username') && (sUri.substr(0, 11) != '/jax/logout'))
         //  {
         //    /*
         //    so when the login session expires, and we are display the re-login window,
         //    it uses ajax to fetch the current user name, so you ony have to enter the password.
         //    During that ajax call, we don't want the time to reset to 20:00 (or whatever), but
         //    remain at 0.
         //    */
         //    var flogtime = (logdur / 60) + ':00';
         //    obj = win.document.getElementById("logtime");
         //    if(obj != null)
         //    {
         //      obj.innerHTML = flogtime;
         //    }
         //  }

         //}
         // end login session timer


         if (callback)
         {
           callback(sRtnText);
         }
         else
         {
           if(!bAsync)
           {
             return sRtnText;
           }
         }
       }
     }
     break;
    default:
     oJax.onload = function()
     {
       var sRtnText = oJax.responseText;


       //--- login session timer
       //if(sUri.substr(0, 5) != '/misc')
       //{
         //var win = window;
         //while (win.opener != null)
         //{
         //  win = win.opener;
         //}
         //var logdur = win.document.getElementById('login_duration').innerHTML;
         //if ((sUri.substr(0, 17) != '/jax/get.username') && (sUri.substr(0, 11) != '/jax/logout'))
         //{
         //  /*
         //  so when the login session expires, and we are display the re-login window,
         //  it uses ajax to fetch the current user name, so you ony have to enter the password.
         //  During that ajax call, we don't want the time to reset to 20:00 (or whatever), but
         //  remain at 0.
         //  */
         //  var flogtime = (logdur / 60) + ':00';
         //  var obj = win.document.getElementById("logtime");
         //  if(obj != null)
         //  {
         //    obj.innerHTML = flogtime;
         //  }
         //}  
       //}
       // end login session timer



       if (callback)
       {
         callback(sRtnText);
       }
       else
       {
         if(!bAsync)
         {
           return sRtnText;
         }
       }
     }
     break;
  }

  var qpos = sUri.indexOf('?');
  var url = '';
  var params = '';
  if(qpos > -1)
  {
    url = sUri.substr(0, qpos);
    params = sUri.substr(qpos + 1);


    //removing uniqid
    var newparams = '';
    var uniq = '';
    params = params.replace(/&amp;/g, '&');
    var assignments = params.split('&');
    var assignmentCnt = assignments.length;
    for (var assignmentLoop = 0; assignmentLoop < assignmentCnt; assignmentLoop++)
    {
      var assignment = assignments[assignmentLoop];
      if(assignment.indexOf('=') == -1)
      {
        uniq = assignment;
      }
      else
      {
        if(newparams)
        {
          newparams += '&';
        }
        newparams += assignment;
      }
    }
    if(uniq == '')
    {
      uniq = uniqid();
    }

    params = newparams;
  }
  else
  {
    url = sUri;
    //url  += '?' + uniqid();
    params = 'jaxcall=1';
  }

  oJax.open('POST', url, bAsync);

  oJax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

  oJax.send(params);
  if((!callback) && (!bAsync))
  {
    return oJax.responseText;
  }
}


// -----------------------------------------------------------
//  function (createHttpRequest)
//   - creates HttpRequest depended on the browser
// -----------------------------------------------------------
function createHttpRequest()
{
  var oJax = false;
  // ----- IE -----
  if (window.ActiveXObject)
  {
    try
    {
      oJax = new ActiveXObject("Msxml2.XMLHTTP");
    }
    catch (e)
    {
      try
      {
        oJax = new ActiveXObject("Microsoft.XMLHTTP");
      }
      catch (e)
      {
        null;
      }
    }
  }
  // ----- non IE -----
  if (!oJax && window.XMLHttpRequest)
  {
   oJax = new XMLHttpRequest();
  }
  return oJax;
}

