function isAlien(a) {
   return isObject(a) && typeof a.constructor != 'function';
}

function isArray(a) {
    return isObject(a) && a.constructor == Array;
}

function isBoolean(a) {
    return typeof a == 'boolean';
}

function isEmpty(o) {
    var i, v;
    if (isObject(o)) {
        for (i in o) {
            v = o[i];
            if (isUndefined(v) && isFunction(v)) {
                return false;
            }
        }
    }
    return true;
}

function isFunction(a) {
    return typeof a == 'function';
}

function isNull(a) {
    return typeof a == 'object' && !a;
}

//function isNumber(a) {
//   return typeof a == 'number' && isFinite(a);
//}

function isObject(a) {
    return (a && typeof a == 'object') || isFunction(a);
}

function isString(a) {
    return typeof a == 'string';
}

function isUndefined(a) {
    return typeof a == 'undefined';
}

/***************************************************************************
*HTML Functions
****************************************************************************/

/////////////////////////////////////////////////////////////////////////
//function htmlEscape
//
//This function escapes characters that can cause problems inside of
//HTML tags (',",/,\) for Javascript
/////////////////////////////////////////////////////////////////////////
function htmlEscape(str){
  var retStr;
  retStr = str.replace(/"/, "&#34;");
  retStr = retStr.replace(/'/, "&#39;");
  retStr = retStr.replace(/\\/, "&#92;");
  retStr = retStr.replace(/\//, "&#47;");

  return retStr;
}

/////////////////////////////////////////////////////////////////////////
//function rgbToHex
//
//This function converts RGB color values to HEX color values.
/////////////////////////////////////////////////////////////////////////
function rgbToHex(rgbString) {

  var num1, num2, num3;

  if(rgbString.indexOf("rgb") == 0){

    var tmpStr = rgbString.replace(/rgb\(/i,"");
    tmpStr = tmpStr.replace(/\)/,"");
    tmpStr = tmpStr.split(",");
    num1 = decToHex(parseInt(tmpStr[0]));
    num2 = decToHex(parseInt(tmpStr[1]));
    num3 = decToHex(parseInt(tmpStr[2]));

    return new String("#" + num1 + num2 + num3).toUpperCase();
  }
  else
    return rgbString.toUpperCase();
}

/////////////////////////////////////////////////////////////////////////
//function decToHex
//
//This function converts decimal numbers to color values to HEX color values.
/////////////////////////////////////////////////////////////////////////
function decToHex(num) {

 var arHex = new Array("0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F");

 var themod=num % 16;
 var thenum=((num-themod) / 16);

 return "" + arHex[thenum] + "" + arHex[themod]
}


/***************************************************************************
*Cookie Functions
****************************************************************************/

/////////////////////////////////////////////////////////////////////////////
//function setCookie
//
//This function sets a cookie with the given parameters.
//
// name - name of the cookie
// value - value of the cookie
// [expires] - expiration date of the cookie
//   (defaults to end of current session)
// [path] - path for which the cookie is valid
//   (defaults to path of calling document)
// [domain] - domain for which the cookie is valid
//   (defaults to domain of calling document)
// [secure] - Boolean value indicating if the cookie transmission requires
//   a secure transmission
// * an argument defaults when it is assigned null as a placeholder
// * a null placeholder is not required for trailing omitted arguments
/////////////////////////////////////////////////////////////////////////////

function setCookie(name, value, expires, path, domain, secure) {
  if(name){
    var curCookie = name + "=" + escape(value) +
        ((expires) ? "; expires=" + expires.toGMTString() : "") +
        ((path) ? "; path=" + path : "") +
        ((domain) ? "; domain=" + domain : "") +
        ((secure) ? "; secure" : "");
    document.cookie = curCookie;
  }
}


/////////////////////////////////////////////////////////////////////////////
//function getCookie
//
//This function sets a cookie with the given name
//
//name - name of the desired cookie
//return string containing value of specified cookie or null
//if cookie does not exist
/////////////////////////////////////////////////////////////////////////////

function getCookie(name) {
  var dc = document.cookie;
  var prefix = name + "=";
  var begin = dc.indexOf("; " + prefix);
  if (begin == -1) {
    begin = dc.indexOf(prefix);
    if (begin != 0) return null;
  } else
    begin += 2;
  var end = document.cookie.indexOf(";", begin);
  if (end == -1)
    end = dc.length;
  return unescape(dc.substring(begin + prefix.length, end));
}


/////////////////////////////////////////////////////////////////////////////
//function deleteCookie
//
//This function deletes a cookie.
//
// name - name of the cookie
// [path] - path of the cookie (must be same as path used to create cookie)
// [domain] - domain of the cookie (must be same as domain used to
//   create cookie)
// path and domain default if assigned null or omitted if no explicit
//   argument proceeds
/////////////////////////////////////////////////////////////////////////////

function deleteCookie(name, path, domain) {
  if (getCookie(name)) {
    setCookie(name, false, new Date("Thu, 01-Jan-70 00:00:01 GMT"), path, domain);
  }
}

/************************************************************************
*Propagation delay notifications
************************************************************************/

var propagationCookieName = "cp-propNotif";

function alertPropagationNotification(){
  var sCookieTxt = getCookie(propagationCookieName);

  if(isNull(sCookieTxt) || sCookieTxt != 't'){
    alert("Please note that most all control panel functions take 5-10 minutes to take affect.  We appreciate your patience as we work to speed up these functions and ultimately make them instantaneous.");
    setCookie(propagationCookieName, 't', '', '/');
  }
}

function trim(str) {
    str = str.replace(/^\s*/, '').replace(/\s*$/, '');
    return str;
}

function urldecode(encoded){

    if(!encoded) return "";

    // Replace + with ' '
    //Replace %xx with equivalent character
    var HEXCHARS = "0123456789ABCDEFabcdef";
    var plaintext = "";
    var i = 0;
    while (i < encoded.length) {
        var ch = encoded.charAt(i);
        if (ch == "+") {
            plaintext += " ";
            i++;
        } else if (ch == "%") {
            if (i < (encoded.length-2)
                    && HEXCHARS.indexOf(encoded.charAt(i+1)) != -1
                    && HEXCHARS.indexOf(encoded.charAt(i+2)) != -1 ) {
                plaintext += unescape(encoded.substr(i,3));
                i += 3;
            } else {
                plaintext += "";
                i++;
            }
        } else {
            plaintext += ch;
            i++;
        }
    }

    return plaintext;
}