// <![CDATA[

/* navigation.js (appropriately hide/show/highlight elements of an unordered list
 * used for navigation)
 * 
 * The "algorithm"
 *
 * 0.5. If we're in /dept/polisci/, set a base href tag, to /dept/polisci/
 * 
 * 1. Figure out which li/anchor corresponds to the page we're on by 
 *    pattern-matching the URL
 * 
 * 2. Expand the ul below that li, if it exists
 *
 * 3. Bounce up the tree, expanding ul's and setting .activelink on *anchors* 
 *    not on li's
 * 
 */

var DOM_ELEMENT_NODE = 1;
var DOM_ATTRIBUTE_NODE = 2;
var DOM_TEXT_NODE = 3;
var DOM_CDATA_SECTION_NODE = 4;
var DOM_ENTITY_REFERENCE_NODE = 5;
var DOM_ENTITY_NODE = 6;
var DOM_PROCESSING_INSTRUCTION_NODE = 7;
var DOM_COMMENT_NODE = 8;
var DOM_DOCUMENT_NODE = 9;
var DOM_DOCUMENT_TYPE_NODE = 10;
var DOM_DOCUMENT_FRAGMENT_NODE = 11;
var DOM_NOTATION_NODE = 12;


/**
 * Get CSS classes applied to a node
 * @param object node node to get classes for
 * @return Array array containing a list of classes
 */
function nodeClasses(node)
{
  var classes = new Array();

  if (typeof(node) == "string") {
    node = document.getElementById(node);
  }

  if (node) {
    classes = String(node.className).split(" ");
  }

  return classes;
}

/**
 * Determines if a node has a specific CSS class applied
 * @param String className name of class
 * @return Boolean true if class is applied, false otherwise
 */
function nodeHasClass(node, className)
{
  var hasClass = false;

  if (typeof(node) == "string") {
    node = document.getElementById(node);
  }

  if (node) {
    var classes = nodeClasses(node);

    if (classes.inArray(className)) {
      hasClass = true;
    }
  }
  return hasClass;
}

/**
 * Applies a CSS class to a node (if it is not
 * already applied)
 * @param Object node node to apply class to
 * @param String className name of class to apply
 * @return Boolean true
 */
function nodeAddClass(node, className)
{
  if (!nodeHasClass(node, className)) {
    var classes = nodeClasses(node);
    classes.push(className);

    var newClass = classes.implode(" ");
    node.className = newClass;
  }

  return true;
}

/**
 * Removes a CSS class from a node
 * @param Object node node to remove class from
 * @param String className name of class to remove
 * @return Boolean true
 */
function nodeRemoveClass(node, className)
{
  if (nodeHasClass(node, className)) {
    var classes = nodeClasses(node);
    classes.remove(className);

    var newClass = classes.implode(" ");
    node.className = newClass;
  }

  return true;
}

/**
 * Get children of node by tag name
 * @param node Object node to get children from
 * @param tagName String tag name of children to obtain
 * @param depth Number how far to descend into node tree, empty or zero for all
 * @return Array array of child nodes meeting criteria
 */
function nodeChildrenByTagName(node, tagName, depth)
{
  var children = Array();

  if (node) {

    if (depth > 0) {
      var childNodes = node.childNodes;

      for (var n=0; n < childNodes.length; n++) {
        if (String(childNodes[n].tagName).toUpperCase() == String(tagName).toUpperCase()) {
          children.push(childNodes[n]);
        }
      }

    } else {
      children = node.getElementsByTagName(tagName);
    }
  }

  return children;
}

/*******************************************************************************/

/**
 * Trims whitespace from the left side of a string
 * @return String string with left side trimmed
 */
function strltrim() 
{
  return this.replace(/^\s+/,'');
}

/**
 * Trims whitespace from the right side of a string
 * @return String string with right side trimmed
 */
function strrtrim() 
{
  return this.replace(/\s+$/,'');
}

/**
 * Trims whitespace from beginning and end of string
 * @return String string with leading and trailing whitespace trimmed
 */
function strtrim() 
{
  return this.replace(/^\s+/,'').replace(/\s+$/,'');
}

/**
 * Checks to see if a value exists in a non-associative array
 * @return boolean true if value exists in array
 */
function arrinArray(value)
{
  var rc = false;
  
  for (var n=0; n < this.length; n++) {
    if (this[n] == value) {
      rc = true;
    }
  }
  
  return rc;
}

/**
 * Removes a single non-associative array item by value
 * @param value value to remove from array
 * @return 1 if an item was removed, false if no items removed
 */
function arrremove(value)
{
  var removed = -1;
  
  for (var n=0; n < this.length; n++) {
    if (this[n] == value) {
      removed = n;
    }    
  }
  
  if (removed > -1) {
    this.splice(removed, 1);
  } else {
    removed = false;
  }
  
  return removed;
}

/**
 * Implodes a non-associative array seperating each value
 * with the specified seperator
 * @param sep seperator to use between values
 * @return String string containing array values
 */
function arrimplode(sep)
{
  var values = new String(this.toString());
  return values.replace(/,/g,sep);
}

String.prototype.ltrim = strltrim;
String.prototype.rtrim = strrtrim;
String.prototype.trim = strtrim;
Array.prototype.inArray = arrinArray;
Array.prototype.remove = arrremove;
Array.prototype.implode = arrimplode;

/*******************************************************************************/


/* whereAmI()
 * 
 * @param Object node of ul with anchors to search
 * @return Object page_anchor of anchor of the page you're on
 */
function whereAmI(ul){
	//Grab all of the anchor tags from the unordered list
	var all_the_anchors = nodeChildrenByTagName(ul, "a");
	var where_you_are = document.location.href;
	var return_anchor;
	for (var i=0; i<all_the_anchors.length; i++)
	{
		if (normalizeURL(where_you_are) == normalizeURL(all_the_anchors[i].href))
		{
			return_anchor = all_the_anchors[i];
		}

	}

	// if nothing has matched yet, let's try the path alone
	if (null == return_anchor) {
		for (var i=0; i<all_the_anchors.length; i++) {
			if (normalizeURL(where_you_are).indexOf(normalizeURL(all_the_anchors[i].href))>-1) {
				return_anchor = all_the_anchors[i];
			}
		}
	}

	/* If we haven't matched anything, try matching on the title 
	 * before returning false*/
/*	if (null == return_anchor) {
		//Try to match the page title against the text of the anchors
		var page_title = document.title;
		var link_text;
		for (var i=0; i<all_the_anchors.length; i++)
		{
			link_text = all_the_anchors[i].childNodes[0].nodeValue;
			if (page_title.indexOf(link_text)>-1) {
				return_anchor = all_the_anchors[i];
				return return_anchor;
			}				
		}
		//If we still haven't found an anchor
		if (null == return_anchor) {
			return false;
		}
	}
	*/
	return return_anchor;
}



/* Don't choke if we don't have getElementById*/
if (!document.getElementById)
    document.getElementById = function() { return null; }

/* Initializes (appropriately hides) all of the ul's below the
 * second level ul.
 * @param id string the id of  
 * @return void
 */
function initializeNavTree(tree_id) {
	var nav_tree = document.getElementById(tree_id);
	//hide the nav_tree to prevent flash of unstyled content
	if (nav_tree) { //in case the page doesn't have a nav_tree
	nav_tree.style.display = 'none';
	if (nav_tree) {
		var anchor = whereAmI(nav_tree);
		if (anchor) {
			hideChildUls(nav_tree); 
			//show the menu one below this anchor (if it exists)
			expandChildNavTree(anchor);
			//show the entire menu above this anchor
			expandParentsNavTree(anchor, tree_id);
		} else {
			hideChildUls(nav_tree); 
			//alert('This page is not linked to in the sidenav.');
		}
	}
	//show the nav_tree
	nav_tree.style.display = 'block';
	}
	return;
}

//End menuExpandable

/**
 * Hides all child ul's from a starting ul, descending into
 * child nodes
 * @param Object el node to initialize
 * @return void
 */
function hideChildUls(el)
{
  try {
	var children = el.childNodes;
  }
  catch (er) {
	  return;
  }
  for (var n=0; n < children.length; n++) {
    var item = children[n];
    
    if (String(item.tagName).toUpperCase() == "LI") {

      var nodes = item.childNodes;
	  for (var t=0; t < nodes.length; t++) {
	    if (String(nodes[t].tagName).toUpperCase() == "UL") {
		  nodes[t].style.display = 'none';
		  hideChildUls(nodes[t]);
        }
      }// end for loop
    } 
  }
}

/* Starting from an anchor nested within a UL, displays the UL it's nested in,
 * then all of its parents', grandparents', great-grandparents' ULs
 * stopping only when it gets to a specific id
 * @param Object node ul
 * @param string id ID of node to stop at
 * @return void
 */
function expandParentsNavTree(a, id) {
	//show this ul and all of its parents
	var node = a;
	if (node != null)
	{
		while (node.id != id)
		{
			if (String(node.tagName).toUpperCase() == "LI")
			{
				var children = nodeChildrenByTagName(node, "A", 1);
				if (children[0]) {
					nodeAddClass(children[0], 'activelink');
				}
			}
			if (String(node.tagName).toUpperCase() == "UL")
			{
				node.style.display = 'block';
			}
			node = node.parentNode;
		}
	}
}

/* Starting from an anchor nested within a ul, displays its li,
 * then all of its parents, grandparents, great-grandparents, etc.
 * stopping only when it gets to a specific id
 * @param Object node ul
 * @param string id ID of node to stop at
 * @return void
 */
function expandChildNavTree(a) {
	var node = a;
	//get the LI that the anchor is nested in
	while (String(node.tagName).toUpperCase() != "LI")
	{
		node = node.parentNode;
	}
	
	//loop through the children of that li, display the ul if it's in there
	var node_children = node.childNodes;
	for (var n=0; n < node_children.length; n++)
	{
		var this_node = node_children.item(n);
		if (String(this_node.tagName).toUpperCase() == "UL" )
		{
			this_node.style.display = 'block';
		}
	}
}

/* chop index.html, index.php, page anchors,
 *  from the end of URLs*/
function normalizeURL(url_string) {
	var file_names = Array('index.html', 'index.htm', 'index.php');
	for (var i=0; i<file_names.length; i++ ){
		if (url_string.toLowerCase().indexOf(file_names[i]) != -1) {
			url_string = url_string.toLowerCase().replace(file_names[i], '');
		}
	}

	//Split on # and disregard everything after the #
	//Gets rid of page anchors
	var url_arr = url_string.split('#');
	url_string = url_arr[0];
	
	//Remove trailing question mark
	if (url_string.charAt(url_string.length-1)=='?') {
		url_string = url_string.substring(0,url_string.length-1);
	}
	
	return url_string;
}




// ]]>