var AJAJObj = new Object();

// Save some typing with getElementById
// ---------------------------------------------------------------------------------------
function getEl(id) {
  return document.getElementById(id);
}

// Do some action as soon as an ID exists. Note: just b/c a DIV's ID exists, doesn't mean
// its contents do. To be safe, check to see if something after that DIV (in HTML order)
// exists before acting on the contents of that DIV.
// --------------------------------------------------------------------------------------- 
function actASAP(id, action, varAry) {
  var n = 0;  // "loop" counter
  var checkIfReady = function() {  // start the timer
    var cont = true;  // do we keep checking? Assume so for now
    n++;
    if (typeof document.getElementsByTagName != 'undefined' &&  // gEBTN exists
        document.getElementsByTagName('body')[0] != null &&  // body exists
        getEl(id) != null) {  // specific element with that id exists
      cont = false;  // so stop "looping"
      if(!cont) { action(varAry); clearInterval(checkInt); }
    }
    if (n >= 100) { clearInterval(checkInt); }  // clear the timer if it's gone on too long
  };
  var checkInt = setInterval(checkIfReady, 200);
}

// Abstract out the new XMLHttpRequest process
// ---------------------------------------------------------------------------------------
function newXMLHttpRequest() {
  var XHR;
  if (window.XMLHttpRequest) {  // Firefox, Safari, ...
    XHR = new XMLHttpRequest();
  } else if (window.ActiveXObject) {  // Internet Explorer/ActiveX version
    XHR = new ActiveXObject("Microsoft.XMLHTTP");
  }
  return XHR;
}

// If the XHR returns JSON, use this to do store the results in a global variable,
// then call function f
// ---------------------------------------------------------------------------------------
function handleJson(f) { 
  if (AJAJObj.httpReq.readyState == 4) {
    if (AJAJObj.httpReq.status == 200) {
      var jsonData = AJAJObj.httpReq.responseText; 
      AJAJObj.results = eval("(" + jsonData + ")");
      f();
    } else {
      alert("Could not get data from server.");
    }
  }
}

// Universal asynchronous (AJAJ) handler
// ---------------------------------------------------------------------------------------
function GoAJAJ(globalObj, urlStr, baseUrl, method, handler) {
  globalObj.httpReq = newXMLHttpRequest();
  globalObj.httpReq.onreadystatechange = function() { handleJson(handler); };
  if (method == "GET") {
    globalObj.httpReq.open("GET", baseUrl+"?"+urlStr, true);
    globalObj.httpReq.send(null);  
  } else if (method == "POST") {
    globalObj.httpReq.open("POST", baseUrl, true);
    globalObj.httpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    globalObj.httpReq.send(urlStr);  
  }
}

// ***************************************************************************************
// ***************************** className handling **************************************
// *************************************************************************************** 

// Check to see if an element's className contains a particular class
// ---------------------------------------------------------------------------------------
function classCheck(el, checkClass) {
  var classAry = el.className.split(" ");
  var found = 0;
  for (i=0; i<classAry.length; i++) { // loop through all classes
    if (classAry[i] == checkClass) { found = 1; }
  }
  return found;
}
  
// Add a particular class to an element's className
// ---------------------------------------------------------------------------------------
function classAdd(el, addClass) {
  var oldClassName = el.className;
  var newClassName = el.className;
  newClassName += (el.className) ? " "+addClass : addClass;
  el.className = newClassName;
}

// Remove a particular class to an element's className
// ---------------------------------------------------------------------------------------
function classRemove(el, removeClass) {
  var oldClassName = el.className;
  var classAry = el.className.split(" ");
  var newClassName = "";
  for (i=0; i<classAry.length; i++) { // loop through all classes
    if (classAry[i] != removeClass) { // concat all but that one class into new string
      newClassName += (newClassName) ? " "+classAry[i] : classAry[i];
    }
  }
  el.className = newClassName;
}

// ***************************************************************************************
// ******************************* cookie handling ***************************************
// *************************************************************************************** 

// Get a cookie's value
// ---------------------------------------------------------------------------------------
function getCookie(name) {
  var nameStart = document.cookie.indexOf(name+"=");
  var valueStart = nameStart + name.length + 1;
  if (nameStart == -1) return null;
  var valueEnd = document.cookie.indexOf(";", valueStart);
  if (valueEnd == -1) { valueEnd = document.cookie.length; }
  return unescape(document.cookie.substring(valueStart, valueEnd));
}

// Set a cookie's value
// ---------------------------------------------------------------------------------------
function setCookie(name, value, expDays, domain) {
  var today = new Date();
  today.setTime(today.getTime());
  if (expDays) { var expires = expDays * 1000 * 60 * 60 * 24; }
  var expiresDate = new Date(today.getTime()+expires);
  document.cookie = name + "=" + escape(value) + ";expires="+expiresDate.toGMTString() +
                   ";domain="+domain;
}

// ***************************************************************************************
// ************************* string prototype extensions *********************************
// ***************************************************************************************
// (From: http://www.ivanuzunov.net/top-10-javascript-stringprototype-extensions/ )

String.prototype.trim = function(){ return this.replace(/^\s+|\s+$/g,''); }

String.prototype.isValidEmail = function () {
  var emailAddress = /\w+([-+.]\w+)*@([\w-]+\.)+\w{2,}/;
  // close enough to RFC 282{1,2}, excludes some odd corner cases, just from laziness
  var matches = emailAddress.exec(this);
  return (matches!=null && this==matches[0]);
}