///////////////////////////////////////////////////////////////////////////
// Module:  softo_general.js
// Purpose: General utility functions for DHTML integration.
/////////////////////////////////////////////////////////////////////////// 

////////////////////////////////////////////////
// XMLHttpRequest States:
// 
// State |  Description
// ====================
// 0        The request is not initialized
// 1        The request has been set up
// 2        The request has been sent
// 3        The request is in process
// 4        The request is completed
////////////////////////////////////////////////
var XMLHTTP_State_NotInitialized = 0;
var XMLHTTP_State_RequestSetUp = 1;
var XMLHTTP_State_RequestSent = 2;
var XMLHTTP_State_RequestInProcess = 3;
var XMLHTTP_State_RequestCompleted = 4;

////////////////////////////////////////////////
// Error Codes
var kErrorSuccess = 0;
var kErrorXMLHTTPRequestObjCreationFailure = 1;

// Global XMLHTTP Request Object.  
// Reasoning for being a global: 
//  Only need one per browser window, and since callback functions 
//  need to query the status of the object, a global object makes sense.
var g_xmlHttpRequestObj = null;

function addOnLoadEvent(iFunction)
{
  var old_onload_fctn = window.onload;
  if (typeof window.onload != 'function')
  {
    window.onload = iFunction;
  }
  else
  {
    // Create new function calling previous onload function
    // and the input argument function.
    window.onload = function()
                    {
                      old_onload_fctn();
                      iFunction();
                    };
  }

  return;
}

function createGlobalXMLHTTPRequestObject()
{
  if (g_xmlHttpRequestObj == null)
  {
    g_xmlHttpRequestObj = createXMLHTTPRequestObject();
  }

  return g_xmlHttpRequestObj != null ? 
          kErrorSuccess : kErrorXMLHTTPRequestObjCreationFailure;
}

function createXMLHTTPRequestObject()
{
  var requestObj = null;

  if (window.XMLHttpRequest) 
  {
    // Native XMLHttpRequest object.
    // -----------------------------
    // Mozilla, Firefox, Safari, Opera, and Netscape.
    requestObj = new XMLHttpRequest();
  }
  else if (window.ActiveXObject) 
  {
    // MSIE
    // ----
    // This should work for all MSIE >= 5.5 versions.
    requestObj = new ActiveXObject("Microsoft.XMLHTTP");
  }

  return requestObj;
}

// callURL
// =======
// Load the given URL in an XMLHttpRequest object, and have the
// object call a function after load has completed.  In this scenario,
// this function will likely return before the page has fully been
// downloaded.
function callURL_Async(url, callbackFctn) 
{
  if (url == null || url == "" || callbackFctn == null)
  {
    alert("callURL_Async: invalid inputs");
    return false;
  }

  if (createGlobalXMLHTTPRequestObject() != kErrorSuccess)
  {
    alert("callURL_Async: Could not create XMLHTTP object.");
    return false;
  }

  g_xmlHttpRequestObj.onreadystatechange = callbackFctn;
  g_xmlHttpRequestObj.open("GET", url, true);
  g_xmlHttpRequestObj.send(null);

  // Use the XMLHTTPRequest.responseText or XMLHTTPRequest.responseXML 
  // properties to retrieve results.

  return kErrorSuccess;
}

function callURL_Sync(url) 
{
  if (url == null || url == "")
  {
    alert("callURL_Sync: invalid inputs");
    return -1;
  }

  if (createGlobalXMLHTTPRequestObject() != kErrorSuccess)
  {
    alert("callURL_Sync: Could not create XMLHTTP object.");
    return false;
  }

  g_xmlHttpRequestObj.open("GET", url, false);

  // Blocking function that will return after the request has completed.
  g_xmlHttpRequestObj.send(null);

  // Use the XMLHTTPRequest.responseText or XMLHTTPRequest.responseXML 
  // properties to retrieve results.

  return kErrorSuccess;
}

///////////////////////////////////////////////////////////////////////////
// MSIE will not send the request to the server again if the URL is
// unchanged from the last XMLRequestObject url request.  By adding
// a timestamp to the URL, which has an innocuous effect upon the server
// (it is just another key/value pair which is not used), this then
// 'fakes' the browser into performing the submittal.  We could have
// modified the server's CGI response to tell the browser not to cache
// the results, but this is allows the client-side to control whether
// the request is actually sent to the server.
///////////////////////////////////////////////////////////////////////////
function generateXMLHTTPNonCachedURL(iURL)
{
  if (iURL == null || iURL == "")
  {
    alert("generateXMLHTTPNonCachedURL: invalid inputs");
    return "invalid_URL";
  }

  var dateObj = new Date();
  var timestamp = dateObj.getTime();

//  alert("timestamp " + timestamp);

  // Timestamp the URL to force the URL request to be sent out
  // rather than reference a cache'd value.
  var generatedURL = iURL + "&timestamp=" + timestamp;

  return generatedURL;
}

function callPageCounter(iPage, iCallbackFctn)
{
  // Default to 'Sync'.
  return callPageCounterCommon(iPage, iCallbackFctn, false);
}

function callPageCounterCommon(iPage, iCallbackFctn, iAsyncFlag)
{
  var pageCounterURL = "/cgi_common/page_counter.cgi?page=" + iPage;
  var nonCachedURL = generateXMLHTTPNonCachedURL(pageCounterURL);
  var rc = kErrorSuccess;

  if (iAsyncFlag == true)
  {
    rc = callURL_Async(nonCachedURL, iCallbackFctn);
  }
  else
  {
    rc = updatePageCounter_Sync(nonCachedURL, iCallbackFctn);
  }

  return rc;
}

function updatePageCounter_Sync(iURL, iCallbackFctn)
{
  var rc = callURL_Sync(iURL);
  if (rc != kErrorSuccess)
  {
    alert("updatePageCounter_Sync: callURL_Sync() failed.");
    return rc;
  }

  if (iCallbackFctn != null)
  {
    var response = g_xmlHttpRequestObj.responseText;
    iCallbackFctn(response);
  }

  return rc;
}


