/*
 * Author
 *   Sean Willson <thinker@wideasleep.com>
 * 
 * Additional Information
 *   http://www.wideasleep.com/javascript/
 *
 * Copyright 2002-2007 WideAsleep, LLC. All rights reserved. 
 *
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted provided that the following conditions are met: 
 *
 * Redistributions of source code must retain the above copyright notice, this list 
 * of conditions and the following disclaimer. Redistributions in binary form must 
 * reproduce the above copyright notice, this list of conditions and the following 
 * disclaimer in the documentation and/or other materials provided with the 
 * distribution. THIS SOFTWARE IS PROVIDED BY THE FREEBSD PROJECT ``AS IS'' AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 
 * IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 * POSSIBILITY OF SUCH DAMAGE.
 */ 

/*
 * Browser version snooper; determines your browser (Navigator 4, Navigator 6, or Internet Explorer 4/5)
 */

// convert all characters to lowercase to simplify testing 
var agent = navigator.userAgent.toLowerCase(); 
// extract the major and minor version information
var isMajor = parseInt(navigator.appVersion);
var isMinor = parseFloat(navigator.appVersion); 
// determine the browser type
var isNav = ((agent.indexOf('mozilla') != -1) && (agent.indexOf('spoofer') == -1) && (agent.indexOf('compatible') == -1) && (agent.indexOf('opera') == -1) && (agent.indexOf('webtv') == -1));
var isNav2 = (isNav && (isMajor == 2));
var isNav3 = (isNav && (isMajor == 3));
var isNav4 = (isNav && (isMajor == 4));
var isNav4up = (isNav && (isMajor >= 4));
var isNav5 = (isNav && (isMajor == 5));
var isNav5up = (isNav && (isMajor >= 5));
var isIE = (agent.indexOf("msie") != -1);
var isIE3 = (isIE && (isMajor < 4));
var isIE4 = (isIE && (isMajor == 4) && (agent.indexOf("msie 5.0") == -1));
var isIE4up = (isIE  && (isMajor >= 4));
var isIE5 = (isIE && (isMajor == 4) && (agent.indexOf("msie 5.0") != 1));
var isIE5up = (isIE  && !isIE3 && !isIE4);
// determine the os type
var isWin = (agent.indexOf("win") != -1);
var isMac = (agent.indexOf("mac") != -1);
var isSun = (agent.indexOf("sunos") != -1);
var isIrix = (agent.indexOf("irix") !=-1);
var isHpUX = (agent.indexOf("hp-ux") != -1);
var isAix = (agent.indexOf("aix") != -1);
var isLinux = (agent.indexOf("inux") != -1);
var isFreeBSD = (agent.indexOf("freebsd") != -1);
var isBSD = (agent.indexOf("bsd") != -1);

/*
 * Removes all of my pages from any frameset that they may have been put in
 */
function removeFrameSet() {
  if (self.parent.frames.length != 0) {
    self.parent.location=document.location;
  }
}

/*
 * Jump to a particualar url in a selector. It's assumed that the first and
 * second elements are labels and thus won't kick off the jumpto.
 */
function jumpTo(selector) {
  if ((null != selector) && ("" != selector.options[selector.selectedIndex].value)) {
    self.parent.location=selector.options[selector.selectedIndex].value;
  }
}
 
/*
 * Given a selector string, return a style object by searching through stylesheets. 
 * Return null if none found
 */
function getStyleBySelector( selector ) {
  // if they aren't running at least navigator 5 this stuff will not work
  if (!isNav5up) {
    return null;
  }
  var sheetList = document.styleSheets;
  var ruleList;
  var i, j;

  // look through all of the stylesheets in reverse order looking for the selector
  for (i=sheetList.length-1; i >= 0; i--) {
    ruleList = sheetList[i].cssRules;
    for (j=0; j<ruleList.length; j++)
    {
      // if the rule is a style rule and it is the selector we are looking for return that style object
      if ((ruleList[j].type == CSSRule.STYLE_RULE) && (ruleList[j].selectorText == selector)) {
        return ruleList[j].style;
      }   
    }
  }
  return null;
}

/*
 * Given an id and a property (as strings), return the given property of that id.  Navigator 6 will
 * first look for the property in a tag; if not found, it will look through the stylesheet.
 *
 * Note: do not precede the id with a # -- it will be appended when searching the stylesheets
 */
function getIdProperty( id, property ) {
  // we have a bit more power in nav5up to find what we are looking for, thats why this is
  // a bit longer then the other accessors
  if (isNav5up) {
    var styleObject = document.getElementById( id );
    if (styleObject != null) {
      styleObject = styleObject.style;
      if (styleObject[ property ]) {
        return styleObject[ property ];
      }
    }
    styleObject = getStyleBySelector( "#" + id );
    return (styleObject != null) ? styleObject[ property ] : null;
  }
  else if (isNav4up) {
    return document[ id ][ property ];
  }
  else {
    return document.all[ id ].style[ property ];
  }
}

/*
 * Given an id and a property (as strings), set the given property of that id to the value provided.
 *
 * The property is set directly on the tag, not in the stylesheet.
 */
function setIdProperty( id, property, value ) {
  if (isNav5up) {
    var styleObject = document.getElementById( id );
    if (styleObject != null) {
      styleObject = styleObject.style;
      styleObject[ property ] = value;
    }
  }
  else if (isNav4up) {
    document[ id ][ property ] = value;
  }
  else if (isIE4up) {
    document.all[ id ].style[ property ] = value;
  }
}

/*
 * Given an element (as a string), toggle the display attribute for that element from being 
 * visable to invisable.
 */
function toggleDisplay( element ) {
  var display = getIdProperty(element, "display");
  if (display == "none") {
    setIdProperty(element, "display", "block"); 
  } 
  else {
    setIdProperty(element, "display", "none"); 
  }
}

/*
 * Given an element (as a string), toggle the className attribute from className to
 * className+Active.  This will allow the element to change color if that Active style
 * has been defined.
 */
function toggleActive( element ) {
  var index = element.className.lastIndexOf("Active");
  if (index >= 0) {
    element.className = element.className.slice(0, index);
  }
  else {
    element.className = element.className+"Active";
  }
}

/*
 * Automatically puts into focus the first form element contained within a page.
 */
function selectFirstFormElement() {
  if (document.forms[0] != null) {
    for (var i = 0; i < document.forms.length; i++) {
      for (var j = 0; j < document.forms[i].elements.length; j++) {
        if (document.forms[i].elements[j].type != 'hidden') {
          document.forms[i].elements[j].focus();
          return true;
        }
      }
    }
  }
}

/*
 * Gets a cookie with a given name if present
 */
function readCookie( cookieName ) {
  var cookies = "" + document.cookie;
  var cookieStart = cookies.indexOf(cookieName);
  // if they sent an invalid name or the cookie wasn't found
  if ((cookieStart == -1) || (cookieName == '')) { return ''; }
  var cookieEnd = cookies.indexOf(';', cookieStart);
  if (cookieEnd == -1) { cookieEnd = cookies.length; }
  // return the cookie in it's origional form
  return unescape(cookies.substring(cookieStart + cookieName.length + 1, cookieEnd));
}

/*
 * Sets a cookie.
 */
function setCookie( cookieName, cookieValue, days ) {
  if (! days) { days = 30; } // default to 30 days if empty
  var expdate = new Date(); 
  expdate.setTime(expdate.getTime() + days*24*60*60*1000); 
  document.cookie = cookieName + "=" + escape(cookieValue) + ";domain=" + domain + 
                    ";expires=" + expdate.toGMTString();
}

/*
 * Delete a cookie.
 */
function deleteCookie( cookieName ) {
  if ( readCookie(cookieName) ) {
    document.cookie = cookieName + "=; domain=" + domain + "; expires=Thu, 01-Jan-70 00:00:01 GMT";
  }
}

/*
 * Opens a new window.
 */
function newWindow( url, name, width, height, misc ) {
  var newWindow = window.open(url, name, 'width=' + width + ',height=' + height + ',resizable=yes,statusbar=no,toolbar=no,menubar=no,personalbar=no' + misc);
  if (null != newWindow.focus) { newWindow.focus(); }
}

/*
 * Force all external links to open in a new browser.
 */
function externalLinks() { 
	if (!document.getElementsByTagName) {
		return;
	}
	var anchors = document.getElementsByTagName("a"); 
	for (var i=0; i<anchors.length; i++) { 
		var anchor = anchors[i]; 
		if (anchor.getAttribute("href") && anchor.getAttribute("rel") == "external") {
			anchor.target = "_blank"; 
		}
	} 
} 
window.onload = externalLinks;

/*
 * The main function for this library.
 */
function main() {
  externalLinks(); 
}

/*
 * Perform the following for all pages that load this javascript library.
 */
main();