/* ######################################################## */
/*                                                          */
/*  TITLE:        UTILS.JS                                  */
/*  SITE:         workingstiff.biz                          */
/*  VERSION:      0.14                                      */
/*  AUTHOR:       Brian Maniere                             */
/*  LAST UPDATED: 2009/03/02                                */
/*                                                          */
/*  NAMESPACE: U                                            */
/*                                                          */
/*  PUBLIC CONSTRUCTORS:                                    */
/*    preloadImgs                                           */
/*    postloadImgs                                          */
/*    toggleImgs                                            */
/*    loadImg()                                             */
/*    toggleImg()                                           */
/*                                                          */
/*  PUBLIC FUNCTIONS:                                       */
/*    doLoadImages()                                        */
/*    doDoLoadImages()                                      */
/*    isDomBrowser()                                        */
/*    $()                                                   */
/*    addEvent()                                            */
/*    removeEvent()                                         */
/*    getElementsByClassName()                              */
/*    getElementsIncludeClassName()                         */
/*    toggleDisplay()                                       */
/*    setClass()                                            */
/*    toggleClass()                                         */
/*    swapClass()                                           */
/*    outputHTML()                                          */
/*    insertAfter()                                         */
/*    removeChildren()                                      */
/*    prependChild()                                        */
/*    randomizeArray()                                      */
/*    getMaxValueInArray()                                  */
/*    getQueryParam()                                       */
/*    parseAndExecuteScripts()                              */
/*    enterKeyPressed()                                     */
/*    charEncodeSpaces()                                    */
/*    truncateString()                                      */
/*    trim()                                                */
/*    ltrim()                                               */
/*    rtrim()                                               */
/*    createCookie()                                        */
/*    readCookie()                                          */
/*    manageCookie()                                        */
/*    eraseCookie()                                         */
/*    isNull()                                              */
/*    isNotNull()                                           */
/*    getPosition()                                         */
/*    isOpera()                                             */
/*    isSafari()                                            */
/*    isKDE()                                               */
/*    isGecko()                                             */
/*    isNN4()                                               */
/*    isWinIE()                                             */
/*    isMac()                                               */
/*                                                          */
/*  PRIVATE OBJECTS:                                        */
/*    Navigator                                             */
/*                                                          */
/* ######################################################## */

/* Some of these functions were derived and adapted from the books:
 * Advanced DOM Scripting, Jeffrey Sambells, 2007 Friends of Ed
 * JavaScript: The Definitive Guide, 5th Edition, David Flanagan, 2006 O'Reilly Media, Inc.
 * Most are home-baked
 */
 
(function() {

if(!window.U) {
  window['U'] = {};
}

  // preloadImgs constructor
var _preloadImgs = new Array();
window['U']['preloadImgs'] = _preloadImgs;

  // postloadImgs constructor
var _postloadImgs = new Array();
window['U']['postloadImgs'] = _postloadImgs;

  // toggleImgs constructor
var _toggleImgs = new Array();
window['U']['toggleImgs'] = _toggleImgs;

  // loadImg constructor
function loadImg( pFile ) {
  this.file = pFile;
  return this;
}
window['U']['loadImg'] = loadImg;

  // toggleImg constructor
function toggleImg( pDefaultImg, pHoverImg ) {
  this.defaultImg = pDefaultImg;
  this.hoverImg = pHoverImg;
  return this;
}
window['U']['toggleImg'] = toggleImg;

  // requires array parameter in expected format
function doLoadImages( pArrImgs, pImagePath ) {
  for( var i=0; i < pArrImgs.length; i++ ) {
    var img = new Image();
    img.src = pImagePath + pArrImgs[i]["file"];
  }
}
window['U']['doLoadImages'] = doLoadImages;

  // let addLoadEvent to do its thing
function doDoLoadImages() {
  doLoadImages( U.postloadImgs );
}
window['U']['doDoLoadImages'] = doDoLoadImages;

function isDomBrowser( pOther ) {
  if( pOther === false
    || !Array.prototype.push
    || !Object.hasOwnProperty
    || !document.createElement
    || !document.getElementsByTagName
    ) {
    return false;
  }
  return true;
}
window['U']['isDomBrowser'] = isDomBrowser;

function $() {
  var elements = new Array();
  for( var i=0; i< arguments.length; i++ ) {
    var element = arguments[i];
    if( typeof element == 'string' ) {
      element = document.getElementById(element);
    }
    if( arguments.length == 1 ) {
      return element;
    }
    elements.push(element);
  }
  return elements;
};
window['U']['$'] = $;

function addEvent( pNode, pType, pListener ) {
  if( !isDomBrowser() ) { return false; }
  if( !(pNode == $(pNode)) ) { return false; }
    // try it via the W3C standard
  if( pNode.addEventListener ) {
    pNode.addEventListener( pType, pListener, false );
    return true;
  }
    // otherwise try the IE method
  else if( pNode.attachEvent ) {
    pNode['e' + pType + pListener] = pListener;
    pNode[pType + pListener] = function() {
      pNode['e' + pType + pListener](window.event);
    }
    pNode.attachEvent('on' + type, pNode[pType + pListener]);
    return true;
  }
    // if both fail
  return false;
};
window['U']['addEvent'] = addEvent;

function removeEvent( pNode, pType, pListener ) {
  if( !(pNode == $(pNode)) ) { return false; }
    // try it via the W3C standard
  if( pNode.removeEventListener ) {
    pNode.removeEventListener( pType, pListener, false );
    return true;
  }
    // otherwise try the IE method
  else if( pNode.detachEvent) {
    pNode.detachEvent('on' + pType, pNode[pType + pListener]);
    pNode[pType + pListener] = null;
    return true;
  }
    // if both fail
  return false;
};
window['U']['removeEvent'] = removeEvent;

function getElementsByClassName( pCssClass, pTag, pParent ) { // parent must be a DOM node and is optional
     //G.outB("enter U.getElementsByClassName; pCssClass: " + pCssClass + "; pTag: " + pTag + "; pParent: " + pParent);
    // locate all matching tags
  var parent = (isNull(pParent)) ? document : pParent;
  var allTags = (pTag == '*' && parent.all) ? parent.all : parent.getElementsByTagName(pTag);
  var matchingElements = new Array();
  var cssClass = pCssClass.replace(/\-/g, "\\-");
  var regex = new RegExp("(^|\\s)" + cssClass + "(\\s|$)");
  var element;
  for( var i=0; i<allTags.length; i++ ) {
    element = allTags[i];
    if( regex.test(element.className) ) {
      matchingElements.push(element);
    }
  }
     //G.outB("exit U.getElementsByClassName; matchingElements.length: " + matchingElements.length);
  return matchingElements;
};
window['U']['getElementsByClassName'] = getElementsByClassName;

function getElementsIncludeClassName(pCssClass, pTag, pParent) { // parent must be a DOM node and is optional
    // G.outB("enter U.getElementsIncludeClassName; pCssClass: " + pCssClass + "; pTag: " + pTag + "; pParent: " + pParent);
    // locate all matching tags
  var parent = (isNull(pParent)) ? document : pParent;
  var allTags = (pTag == '*' && parent.all) ? parent.all : parent.getElementsByTagName(pTag);
  var matchingElements = new Array();
  var element;
  for( var i=0; i<allTags.length; i++ ) {
    element = allTags[i];
      // G.outB("U.getElementsIncludeClassName; element.className: " + element.className);
    if( element.className.indexOf(pCssClass) != -1 ) {
        // G.outB("U.getElementsIncludeClassName; match!");
      matchingElements.push(element);
    }
  }
    // G.outB("getElementsIncludeClassName; matchingElements.length: " + matchingElements.length);
  return matchingElements;
};
window['U']['getElementsIncludeClassName'] = getElementsIncludeClassName;

function toggleDisplay(pNode, pValue) {
  if( !(pNode == $(pNode)) ) {
    alert("false");
    return false;
  }
  if( pNode.style.display != 'none' ) {
    pNode.style.display = 'none';
  }
  else {
    pNode.style.display = pValue || "";
  }
  return true;
};
window['U']['toggleDisplay'] = toggleDisplay;

  // sets the css class for a node.  Overwrites any preexisting classes.
function setClass(pNode, pCssClass) {
  if( !(pNode == $(pNode)) ) {
    return false;
  }
  else {
    $(pNode).className = pCssClass;
  }
}
window['U']['setClass'] = setClass;

   // adds nodeClass as a css class to node of id nodeID, or removes the class if it already exists
   // this works whether the css className is empty, singular, or contains multiple classes
function toggleClass( pNode, pNodeClass ) {
  if( !(pNode == $(pNode)) ) {
    return false;
  }
  else {
    var node = pNode;
    var nodeClass = pNodeClass;
    var currClass = node.className;
    if( currClass.length == 0 ) {
      node.className = nodeClass;
    }
    else {
      if( currClass.match(nodeClass) ) {
        if( currClass.match(" ") ) {
          currClass.charAt(currClass.indexOf(nodeClass)-1) == " " ? nodeClass = " " + nodeClass : nodeClass += " ";
        }
        var substrings = currClass.split(nodeClass);
        var newClass = "";
        for( var i=0; i<substrings.length; i++ ) {
          newClass += substrings[i];
        }
        node.className = newClass;
      }
      else {
        node.className = node.className + " " + nodeClass;
      }
    }
    return true;
  }
};
window['U']['toggleClass'] = toggleClass;

  // finds node of id pNodeId and replaces pOldClass with pNewClass.  Works on nodes with multiple classes.
  // be sure to pass pNodeId, pOldClass, pNewClass as strings
function swapClass( pNode, pOldClass, pNewClass ) {
  var node = $(pNode);
  if( !(pNode == $(pNode)) ) { return false; }
    // assumes pOldclass exists, and newclass doesn't, otherwise it toggles both
  toggleClass( pNode, pOldClass );
  toggleClass( pNode, pNewClass );
}
window['U']['swapClass'] = swapClass;

function doTest() {
  swapClass($("accomplishments"),"section","section2");
}
window['U']['doTest'] = doTest;

  // writes markup to screen within specified divID.
function outputHTML( pDivId, pHTML ) {
  if( $(pDivId) ) {
    var targetNode = $(pDivId);
    targetNode.innerHTML = pHTML;
  }
}
window['U']['outputHTML'] = outputHTML;

function insertAfter( pNode, pReferenceNode ) {
  if( !(pNode == $(pNode)) ) { return false; }
  if( !(pReferenceNode = $(pReferenceNode)) ) { return false; }
  return pReferenceNode.parentNode.insertBefore( pNode, pReferenceNode.nextSibling );
};
window['U']['insertAfter'] = insertAfter;

function removeChildren( pParent ) {
  if( !(pParent == $(pParent)) ) { return false; }
  while( pParent.firstChild ) {
    pParent.firstChild.parentNode.removeChild( pParent.firstChild );
  }
  return pParent;
};
window['U']['removeChildren'] = removeChildren;

function prependChild( pParent, pNewChild ) {
  if( !(pParent == $(pParent)) ) { return false; }
  if( !(pNewChild == $(pNewChild)) ) { return false; }
  if( pParent.firstChild ) {
    pParent.insertBefore( pNewChild, pParent.firstChild );
  }
  else {
    pParent.appendChild( pNewChild );
  }
    // return the parent again so you can chain the methods
  return pParent;
};
window['U']['prependChild'] = prependChild;

function randomizeArray( pArray ) {
  var i = pArray.length;
  if( i == 0 ) {
    return false;
  }
  while( --i ) {
    var j = Math.floor( Math.random()*(i+1) );
    var temp_i = pArray[i];
    var temp_j = pArray[j];
    pArray[i]  = temp_j;
    pArray[j]  = temp_i;
  }
};
window['U']['randomizeArray'] = randomizeArray;

function getMaxValueInArray( pArray ) {
  if( pArray.length == 0 ) {
    return false;
  }
  var biggestYet = pArray[0];
  if( pArray.length > 1 ) {
    for( i=1; i<pArray.length; i++ ) {
      if( pArray[i] > biggestYet ) {
        biggestYet = pArray[i];
      }
    }
  }
  return biggestYet;
}
window['U']['getMaxValueInArray'] = getMaxValueInArray;

function getQueryParam( pParam ) {
  var q = document.location.search || document.location.hash;
  if( q ) {
    var pairs = q.substring(1).split("&");
    for( var i=0; i < pairs.length; i++ ) {
      if( pairs[i].substring(0, pairs[i].indexOf("=")) == pParam ) {
        return pairs[i].substring( (pairs[i].indexOf("=")+1) );
      }
    }
  }
}
window['U']['getQueryParam'] = getQueryParam;

  // finds any script blocks within text and executes them
  // outputs everything outside of script blocks
function parseAndExecuteScripts( pSrc ) {
  var source     = pSrc;
  var arrScripts = new Array();
    // find script tags and parse out that which is between them
  while( source.indexOf("<script") > -1 || source.indexOf("</script") > -1 ) {
    var openScriptTagBegin  = source.indexOf("<script");
    var openScriptTagEnd    = source.indexOf(">", openScriptTagBegin);
    var closeScriptTagBegin = source.indexOf("</script", openScriptTagBegin);
    var closeScriptTagEnd   = source.indexOf(">", closeScriptTagBegin);
    arrScripts.push(source.substring(openScriptTagEnd + 1, closeScriptTagBegin));
    source = source.substring(0, openScriptTagBegin) + source.substring(closeScriptTagEnd + 1);
  }
    // Loop through each script and eval it
  for( var i=0; i<arrScripts.length; i++ ) {
    try {
      eval(arrScripts[i]);
    }
    catch(err) {
      alert("error in U.parseAndExecuteScripts(): " + err);
    }
  }
    // Return the non-script source
  return source;
}
window['U']['parseAndExecuteScripts'] = parseAndExecuteScripts;

function enterKeyPressed( e ) {
  var characterCode;
  if( e && e.which ) { // for NN4
    characterCode = e.which; // character code is contained in NN4's which property
  }
  else { // for IE
    e = event;
    characterCode = e.keyCode;
  }
  if( characterCode == 13 ) { // ascii 13 == enter key
    return true;
  }   
  else {
    return false;
  }
}
window['U']['enterKeyPressed'] = enterKeyPressed;

function charEncodeSpaces( pText) {
  var encodedText = "";
  if( pText == "" ) {
    return false;
  }
  encodedText = pText.replace(/\s+/g,'%20');
  return encodedText;
};
window['U']['charEncodeSpaces'] = charEncodeSpaces;

  // truncates a string after a specified length and appends "..."
function truncateString( pStr, pMaxLen) {
  var str       = pStr;
  var maxLen    = pMaxLen;
  var strLen    = str.length;
  var idxSpace  = 0;
  var curSubstr = "";
  var strTemp   = "";
  var output    = "";
  if( str.length <= maxLen ) {
    return str;
  }
  else {
    do {
      idxSpace  = str.indexOf(" ");
      curSubstr = str.substring( 0, idxSpace );
      strTemp   = strTemp + curSubstr + " ";
      str       = str.substring( idxSpace + 1, strLen );
    }
    while( strTemp.length < maxLen );
    strTemp = strTemp.substring( 0, strTemp.lastIndexOf(" ") );
    if( strTemp.length > maxLen ) {
      strTemp = strTemp.substring( 0, strTemp.lastIndexOf(" ") );
    }
    output = strTemp + "...";
    return output;
  }
}
window['U']['truncateString'] = truncateString;

function trim(pString) {
  return pString.replace(/^\s+|\s+$/g,"");
}
window['U']['trim'] = trim;

function ltrim(pString) {
  return pString.replace(/^\s+/,"");
}
window['U']['ltrim'] = ltrim;

function rtrim(pString) {
  return pString.replace(/\s+$/,"");
}
window['U']['rtrim'] = rtrim;

function createCookie( pName, pValue, pDays ) {
  if( pDays ) {
    var date = new Date();
    date.setTime( date.getTime() + (pDays * 24 * 60 * 60 * 1000) );
    var expires = "; expires=" + date.toGMTString();
  }
  else {
    var expires = "";
  }
  document.cookie = pName + "=" + pValue + expires + "; path=/";
}
window['U']['createCookie'] = createCookie;

function readCookie( pName ) {
  var nameEQ = pName + "=";
  var ca = document.cookie.split(';');
  for( var i=0; i < ca.length; i++ ) {
    var c = ca[i];
    while( c.charAt(0)==' ' ) {
      c = c.substring( 1, c.length );
    }
    if (c.indexOf(nameEQ) == 0 ) {
      return c.substring( nameEQ.length, c.length );
    }
  }
  return null;
}
window['U']['readCookie'] = readCookie;

function manageCookie( pName, pValue, pDays ) {
  var currentValue = readCookie( pName );
  if( currentValue == pValue ) {
    return;
  }
  else {
    createCookie( pName, pValue, pDays);
  }
}
window['U']['manageCookie'] = createCookie;

function eraseCookie( pName ) {
  createCookie( pName, "", -1 );
}
window['U']['eraseCookie'] = eraseCookie;

function isNotNull( pString ) {
  return( pString != undefined && pString != "" && pString.length > 0 );
}
window['U']['isNotNull'] = isNotNull;

function isNull( pString ) {
  return( pString == undefined || pString == null || pString == "" || pString.length == 0 );
}
window['U']['isNull'] = isNull;

function getPosition( pElement ) {
  var element = pElement;
  var left = 0;
  var top  = 0;
    // while the current element has a parent.
  while( element.offsetParent ) {
      // sum the current element's offsets with the running total
    left += element.offsetLeft;
    top  += element.offsetTop; 
      // switch focus to the current element's parent
    element = element.offsetParent;
  }
    // do a final increment in case there was no parent or the top parent has an offset
  left += element.offsetLeft;
  top  += element.offsetTop;
    // return values named x and y.
  return { x:left, y:top };
}
window['U']['getPosition'] = getPosition;

var Navigator = {
  _getVersion: function (a, b) {
    var t = navigator.userAgent.split(a)[1];
    return (t) ? t.split(b)[0] : false;
  },
  isOpera: function () {
    return (
      (window.opera) ?
        (document.createElementNS) ?
          (document.createCDATASection) ?
            (document.styleSheets) ? 9 : 8
          : 7
        : 6
      : false
    );
  },
  isSafari: function () {
    return (document.createCDATASection && document.createElementNS) ? Navigator._getVersion('AppleWebKit/', '(') : false;
  },
  isKDE: function () {
    return (document.createCDATASection && document.createElementNS) ? Navigator._getVersion('Konqueror/', ';') : false;
  },
  isGecko: function () {
    return (document.createCDATASection && document.createElementNS) ? Navigator._getVersion('Gecko/', ' ') : false;
  },
  isNN4: function () {
    return (document.layers && typeof document.layers == 'object') ? true : false;
  },
  isWinIE: function () {
    return (
      /*@cc_on @if (@_win64 || @_win32 || @_win16)
      (document.getElementsByTagName) ?
        (@_jscript_version > 5.6) ? 7 :
        (@_jscript_version == 5.6) ? 6 :
        (@_jscript_version == 5.5) ? 5.5 :
        5
      : 4
      @else@*/false/*@end @*/
    );
  },
  isMac: function () {
    var av = navigator.appVersion.toLowerCase();
    return ( av.indexOf( 'mac' ) != -1 );
  }
};
window['U']['isOpera']  = Navigator.isOpera();
window['U']['isSafari'] = Navigator.isSafari();
window['U']['isKDE']    = Navigator.isKDE();
window['U']['isGecko']  = Navigator.isGecko();
window['U']['isNN4']    = Navigator.isNN4();
window['U']['isWinIE']  = Navigator.isWinIE();
window['U']['isMac']    = Navigator.isMac();

})();
