/*global YAHOO,window */

/*jslint white: true, onevar: true, browser: true, on: true, undef: true,
         eqeqeq: true, plusplus: true, bitwise: true, regexp: true,
         newcap: true, immed: true, indent: 2, nomen: false */

var always_safe = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.-';

if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function (elt /*, from*/)
  {
    var len = this.length,
        from = Number(arguments[1]) || 0;

    from = (from < 0) ?
           Math.ceil(from) :
           Math.floor(from);
    if (from < 0) {
      from += len;
    }
    for (; from < len; from += 1)
    {
      if (from in this &&
          this[from] === elt) {
        return from;
      }
    }
    return -1;
  };
}

function recursiveGetOffsetTop(FIELD) {
  var theOffsetTop = FIELD.offsetTop;
  if (FIELD.offsetParent !== null) {
    theOffsetTop = theOffsetTop + recursiveGetOffsetTop(FIELD.offsetParent);
  }
  return theOffsetTop;
}
function recursiveGetOffsetLeft(FIELD) {
  var theOffsetLeft = FIELD.offsetLeft;
  if (FIELD.offsetParent !== null) {
    theOffsetLeft = theOffsetLeft + recursiveGetOffsetLeft(FIELD.offsetParent);
  }
  return theOffsetLeft;
}
function createCookie(name, value, days, path) {
/*
 days defaults to Session Expiring ("").
 path defaults to /.
*/
  var expires, pathname, date;
  if (days) {
    date = new Date();
    date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
    expires = "; expires=" + date.toGMTString();
  } else {
    expires = "";
  }
  if (path) {
    pathname = path;
  } else {
    pathname = "/";
  }
  document.cookie = name + "=" + value + expires + "; path=" + pathname;
}

function readCookie(name, defaultValue) {
  var nameEQ = name + "=",
      ca = document.cookie.split(";"), i, c;
  for (i = 0; i < ca.length; i += 1) {
    c = ca[i];
    while (c.charAt(0) === " ") {
      c = c.substring(1, c.length);
    }

    if (c.indexOf(nameEQ) === 0) {
      c = c.substring(nameEQ.length, c.length);
      if (c.indexOf('"') === 0 && c.lastIndexOf('"') === c.length - 1) {
        return c.substring(1, c.length - 1);
      } else {
        return c;
      }
    }
  }
  if (defaultValue) {
    return defaultValue;
  } else {
    return undefined;
  }
}

/*
   -************-
   |addAttribute|
   -************-
   This function creates an attribute and adds it to the element specified.
   In areas that are slow it would be good to not call this function and
   just do what it does.
*/
function addAttribute(element, attributeName, attributeValue) {
  var attribute = document.createAttribute(attributeName);
  attribute.value = attributeValue;
  element.setAttributeNode(attribute);
}

/*
   -++++++++++++-
   |urllib_quote|
   -++++++++++++-
   + This function operates like the python urllib.quote function.

*/

function padding(str, padchar, padding_size) {
  padding_size = padding_size - 1;
  if (str.length <= padding_size) {
    str = [str];
    while (padding_size >= str.unshift(padchar)) {
    }
    str = str.join('');
  }
  return str;
}

function urllib_quote(s, safe) {
  var res, i, c;
  if (safe === null) {
    safe = '/';
  }
  safe = always_safe + safe;
  res = [];
  for (i = 0; i <= s.length; i += 1) {
    res[i] = s.charAt(i);
  }
  for (i = 0; i <= s.length; i += 1) {
    c = s.charAt(i);
    if (safe.indexOf(c) === -1) {
      res[i] = '%' + padding(c.charCodeAt(0).toString(16).toUpperCase(), 2);
    }
  }
  return res.join('');
}

/*
   -++++++++++-
   |cgi_escape|
   -++++++++++-
   + This function operates like the python cgi.escape function.

*/
function cgi_escape(s, quote) {
  s = s.replace(/&/g, "&amp;");
  s = s.replace(/</g, "&lt;");
  s = s.replace(/>/g, "&gt;");
  if (quote !== null) {
    s = s.replace(/"/g, "&quot;");
  }
  return s;
}

/*
   -++++++++++++-
   |cgi_unescape|
   -++++++++++++-
   + This function works in reverse of cgi_escape.

*/
function cgi_unescape(s, quote) {
  if (quote !== null) {
    s = s.replace(/&quot;/g, /"/);
  }
  s = s.replace(/&gt;/g, ">");
  s = s.replace(/&lt;/g, "<");
  s = s.replace(/&amp;/g, "&");
  return s;
}

var setNodeValue;
if (YAHOO.env.ua.webkit && YAHOO.env.ua.webkit < 522) {
  setNodeValue = function (node, value) {
    if (!YAHOO.lang.isNull(node.nodeValue)) {
      node.nodeValue = value;
    } else {
      node.value = value;
    }
  };
} else {
  setNodeValue = function (node, value) {
    node.value = value;
  };
}

var unicodeEscapeDecRegex = new RegExp("&#([0-9]{2,6});", "g");
var unicodeEscapeNameRegex = new RegExp("&([A-Za-z]{2,4});", "g");
var namedEscapeToNumberLookup = {"quot":    34,
                                 "amp":     38,
                                 "lt":      60,
                                 "gt":      62,
                                 "nbsp":   160,
                                 "laquo":  171,
                                 "raquo":  187,
                                 "copy":   169,
                                 "reg":    174,
                                 "iexcl":  161,
                                 "cent":   162,
                                 "pound":  163,
                                 "curren": 164,
                                 "yen":    165,
                                 "brvbar": 166,
                                 "sect":   167,
                                 "uml":    168,
                                 "ordf":   170,
                                 "not":    172,
                                 "shy":    173,
                                 "macr":   175,
                                 "deg":    176,
                                 "plusmn": 177,
                                 "sup2":   178,
                                 "sup3":   179,
                                 "acute":  180,
                                 "micro":  181,
                                 "para":   182,
                                 "middot": 183,
                                 "cedil":  184,
                                 "sup1":   185,
                                 "ordm":   186,
                                 "frac14": 188,
                                 "frac12": 189,
                                 "frac34": 190,
                                 "iquest": 191,
                                 "Agrave": 192,
                                 "Aacute": 193,
                                 "Acirc":  194,
                                 "Atilde": 195,
                                 "Auml":   196,
                                 "Aring":  197,
                                 "AElig":  198,
                                 "Ccedil": 199,
                                 "Egrave": 200,
                                 "Eacute": 201,
                                 "Ecirc":  202,
                                 "Euml":   203,
                                 "Igrave": 204,
                                 "Iacute": 205,
                                 "Icirc":  206,
                                 "Iuml":   207,
                                 "ETH":    208,
                                 "Ntilde": 209,
                                 "Ograve": 210,
                                 "Oacute": 211,
                                 "Ocirc":  212,
                                 "Otilde": 213,
                                 "Ouml":   214,
                                 "times":  215,
                                 "Oslash": 216,
                                 "Ugrave": 217,
                                 "Uacute": 218,
                                 "Ucirc":  219,
                                 "Uuml":   220,
                                 "Yacute": 221,
                                 "THORN":  222,
                                 "szlig":  223,
                                 "agrave": 224,
                                 "aacute": 225,
                                 "acirc":  226,
                                 "atilde": 227,
                                 "auml":   228,
                                 "aring":  229,
                                 "aelig":  230,
                                 "ccedil": 231,
                                 "egrave": 232,
                                 "eacute": 233,
                                 "ecirc":  234,
                                 "euml":   235,
                                 "igrave": 236,
                                 "iacute": 237,
                                 "icirc":  238,
                                 "iuml":   239,
                                 "eth":    240,
                                 "ntilde": 241,
                                 "ograve": 242,
                                 "oacute": 243,
                                 "ocirc":  244,
                                 "otilde": 245,
                                 "ouml":   246,
                                 "divide": 247,
                                 "oslash": 248,
                                 "ugrave": 249,
                                 "uacute": 250,
                                 "ucirc":  251,
                                 "uuml":   252,
                                 "yacute": 253,
                                 "thorn":  254,
                                 "yuml":   255,
                                 "euro":  8364
                                 };

function dec2Unicode(text, value) {
  var tempValue = parseInt(value, 10).toString(16);
  while (tempValue.length < 4) {
    tempValue = "0" + tempValue;
  }
  return eval('"\\u' + tempValue + '"');
}

function name2Unicode(text, value) {
  value = namedEscapeToNumberLookup[value];
  if (!value) {
    return text;
  }
  var tempValue = parseInt(value, 10).toString(16);
  while (tempValue.length < 4) {
    tempValue = "0" + tempValue;
  }
  return eval('"\\u' + tempValue + '"');
}

function unicodeEscape(text) {
  text = text.replace(unicodeEscapeDecRegex, dec2Unicode);
  return text.replace(unicodeEscapeNameRegex, name2Unicode);
}

function isCapsLock(e, blur) {
  var kc = e.keyCode ? e.keyCode : e.which,
      sk = e.shiftKey ? e.shiftKey : ((kc === 16) ? true : false);
  if (!blur && (((kc >= 65 && kc <= 90) && !sk) || ((kc >= 97 && kc <= 122) && sk))) {
    document.getElementById('isCapsLock').style.display = 'block';
  } else {
    document.getElementById('isCapsLock').style.display = 'none';
  }
}

var recursivePurgeAndRemove = function (el) {
  var children = YAHOO.util.Dom.getChildren(el);
  if (children.length) {
    YAHOO.util.Dom.batch(children, recursivePurgeAndRemove);
  }
  YAHOO.util.Event.purgeElement(el);
  if (el.parentNode) {
    el.parentNode.removeChild(el);
  }
};

/* Can't handle decimals in arguments yet */
function jval(jString, oScope) {
  var jPath, jPathLength, jChunks, jScope, jArgs = [], x, y;
  if (!oScope) {
    oScope = window;
  }
  jPath = jString.replace(/javascript:/, '').split(".");
  jPathLength = jPath.length;
  for (x = 0; x < jPathLength; x += 1) {
    if (jPath[x].indexOf("(") !== -1) {
      jChunks = jPath[x].match(/(['|"]?[\w\d\.]+['|"]?)/g);
      jScope = jChunks.shift();
      if (jChunks.length > 0) {
        jArgs = [];
        for (y = 0; y < jChunks.length; y += 1) {
          if (jChunks[y].search(/['|"]{1}/g) !== -1) {
            jArgs = jArgs.concat(jChunks[y].match(/[\w\d]+/g));
          } else if (jChunks[y].search(/[\.\d]+/g) !== -1) {
            jArgs.push(parseInt(jChunks[y], 10));
          } else if (jChunks[y] === "true") {
            jArgs.push(true);
          } else if (jChunks[y] === "false") {
            jArgs.push(false);
          } else {
            jArgs.push(jChunks[y]);
          }
        }
      }
      oScope = oScope[jScope].apply(oScope, jArgs);
    } else {
      oScope = oScope[jPath[x]];
    }
  }
  return oScope;
}

function getQueryStringVariable(varName) {
  var queryString, x, xLen, queryStringVar;
  queryString = window.location.search.substring(1);
  queryString = queryString.split("&");
  for (x = 0, xLen = queryString.length; x < xLen; x += 1) {
    queryStringVar = queryString[x].split("=");
    if (queryStringVar[0] === varName) {
      return queryStringVar[1];
    }
  }
}

function typeOf(value) {
  var s = typeof value;
  if (s === 'object') {
    if (value) {
      if (typeof value.length === 'number' &&
          !(value.propertyIsEnumerable('length')) &&
          typeof value.splice === 'function') {
        s = 'array';
      }
    } else {
      s = 'null';
    }
  }
  return s;
}

function isEmpty(o) {
  var i, v;
  if (typeOf(o) === 'object') {
    for (i in o) {
      if (o.hasOwnProperty(i)) {
        v = o[i];
        if (v !== undefined && typeOf(v) !== 'function') {
          return false;
        }
      }
    }
  }
  return true;
}
