// Global vars
var ajax_timeoutID;	// Timeout timer.
var ajax_progressID;	// Progresss timer.
var ajax_method;	// Holds GET or POST
var ajax_busy = false;	// Flag to indicate if ajax is busy or not.
var ajax_divEl;		// Holds the div element to be loaded with the data returned.
var ajax_url;		// Records the url to be posted to.
var ajax_caller;	// The element that called the post function.
var ajax_timeout;	// The timout value in milliseconds
var ajax_progress;	// The progress interval value in milliseconds
var ajax_progMsgCode;	// The progress message code integer value.
var ajax_startTime;	// The time when the action started.
var ajax_result;	// The result text (for use by other javascript code)
var ajax_callback;	// A callback function for external progs to use.


function showDivWithMsg(divname,msg) {
  var el = document.getElementById(divname);
  if( el) {
    el.innerHTML = msg;
    el.style.visibility = "visible";
  }
}

function toggleDivVisibility(divname) {
  var el = document.getElementById(divname);
  if( el) {
    if( el.style.visibility == "visible") {
      el.style.visibility = "hidden";
    } else el.style.visibility = "visible";
  }
}

/* --------------------------------------------------------------------------------
  This function is called to get or post some data using Ajax.
  caller is a reference to the element that called this (a button for example)
    If the caller type is 'button' then it will be disabled during the get.
    Caller can be '' in which case nothing happens with the caller.
  method must be either GET or POST and in uppercase.
  url is the url to GET or POST to.
  divname may be '' or the id of the div element to paste the response into.
  timeout is the timeout value (in seconds) and may be zero for no timeout.
  startMsg can be an html message to show in the divname upon starting the
    request.
  progMsgCode can be a number to indicate what kind of progress message should
    be displayed in the divname.
      0 = no progress message.
      1 = seconds left until timout.

  POST only parameters, ignored when method is GET.
    postElements is a string of DOM element IDs whose data is to be posted.
-------------------------------------------------------------------------------- */
function ajax_request(caller, method, url, divname, postElements, timeout, startMsg, progMsgCode) {
  if( ajax_busy ) {
    alert('Please wait for previous action to complete.');
    return false;
  }
  if( method != 'GET' && method != 'POST') {
    alert('Invalid method '+method);
    return false;
  }
  ajax_result = '';
  ajax_progress = 0;
  ajax_progMsgCode = parseInt(progMsgCode);
  if( ajax_progMsgCode == 1) ajax_progress = 1000;
  ajax_timeout = parseInt(timeout) * 1000;
  ajax_method = method;
  if( caller) {
    ajax_caller = caller;
    if( caller.type == 'button') caller.disabled = true;
  } else ajax_caller = null;
  if( divname != '') {
    ajax_divEl = document.getElementById(divname);
  } else {
    ajax_divEl = null;
  }
  var nvs = '';
  if( method == 'POST' && postElements != '') {
    var arr = postElements.split(',');
    for( var j=0; j < arr.length; j++) {
      var el = document.getElementById(arr[j]);
      if( el && el.value ) {
        if( nvs == '') {
          nvs = el.id+'='+el.value;
        } else nvs = nvs + '&' + el.id+'='+el.value;
      }
    }
  }

  var d = new Date();
  ajax_startTime = d.getTime();

  var httpRequest = GetXmlHttpObject();
  if (httpRequest == null) {
    alert("Browser does not support AJAX");
    if( ajax_caller) {
      if( ajax_caller.type == 'button') ajax_caller.disabled = false;
    }
    return false;
  } 
  ajax_url = url;
  ajax_busy = true;
  if( startMsg != '' && ajax_divEl) {
    ajax_divEl.innerHTML = startMsg;
    ajax_divEl.style.visibility = "visible";
  }
  if( ajax_timeout > 0) {
    ajax_timeoutID = setTimeout('ajax_timeoutEvent()', ajax_timeout);
  }
  if( ajax_progress > 0) {
    ajax_progressID = setTimeout('ajax_progressEvent()', ajax_progress);
  }

  httpRequest.onreadystatechange = function() { ajax_handleResponse(httpRequest); };
  try {
    httpRequest.open(method, url, true);
    if( method == 'POST') {
      httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
      httpRequest.send(nvs); // name=value pairs
    } else {
      httpRequest.send('');
    }
    ajax_busy = true;
  } catch(err) {
    if( ajax_timeoutID) clearTimeout(ajax_timeoutID);
    if( ajax_progressID) clearTimeout(ajax_progressID);
    alert(err);
    if( ajax_caller) {
      if( ajax_caller.type == 'button') ajax_caller.disabled = false;
    }
  }
}

/* --------------------------------------------------------------------------------
This is the function called by Ajax when the posting has completed.
-------------------------------------------------------------------------------- */
function ajax_handleResponse(httpRequest) {
  if (httpRequest.readyState == 4) {
    if( ajax_timeoutID) clearTimeout(ajax_timeoutID);
    if( ajax_progressID) clearTimeout(ajax_progressID);
    ajax_busy = false;
    if( ajax_caller) {
      if( ajax_caller.type == 'button') ajax_caller.disabled = false;
    }

    if (httpRequest.status == 200) {
      if( httpRequest.responseText.indexOf("ERR!! You are not logged in.") != -1) {
        alert("That function requires you to be logged in to the server.");
        document.location = "/login.php";
        return;
      }

      if( httpRequest.responseText) {
        ajax_result = httpRequest.responseText; // Store in global var as well.
        if( ajax_callback) eval(ajax_callback);
        if( ajax_divEl) {
          ajax_divEl.innerHTML = httpRequest.responseText; 
        }
      } else {
        alert('Unsupported document returned!');
      }

    } else {
      alert('There was a problem with the post request.\n'+
        httpRequest.status+' '+httpRequest.statusText);
      if( ajax_callback) eval(ajax_callback);
    }
  }
}

// This is called if the request times out.
function ajax_timeoutEvent() {
  if( ajax_timeoutID) clearTimeout(ajax_timeoutID);
  if( ajax_progressID) clearTimeout(ajax_progressID);
  if( ajax_progMsgCode == 1 && ajax_timeout > 0) {
    if(ajax_divEl) ajax_divEl.innerHTML = '';
  }
  alert('A timeout occured waiting for a response from\n'+ajax_url);
  ajax_busy = false;
  if( ajax_caller) {
    if( ajax_caller.type == 'button') ajax_caller.disabled = false;
  }
}

// This is called frequently to allow some progress information to be updated.
function ajax_progressEvent() {
  if( ajax_divEl) {
    if( ajax_progMsgCode == 1 && ajax_timeout > 0) {
      var d = new Date();
      var t = d.getTime();
      var elapsed = t - ajax_startTime;
      var tmLeft = parseInt((ajax_timeout - elapsed)/1000);
      if( ajax_method == 'POST') {
        ajax_divEl.innerHTML = 'Posting data... '+tmLeft+' seconds remaining';
      } else {
        ajax_divEl.innerHTML = 'Getting data... '+tmLeft+' seconds remaining';
      }
    }
  }
  ajax_progressID = setTimeout('ajax_progressEvent()', ajax_progress);
}

function GetXmlHttpObject() {
  var xmlHttp=null;

  try {
    xmlHttp=new XMLHttpRequest(); // Firefox, Opera 8.0+, Safari
    //if (xmlHttp.overrideMimeType) xmlHttp.overrideMimeType('text/xml');
  } catch (e) {
    try {
      xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); // Internet Explorer
    } catch (e) {
      xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
  }
  return xmlHttp;
}

