function toggle_print_friendly()
{
	var css = $('print_css');
	if (css.media == 'print') {
		css.media = 'all';

		print();

	}
	else {
		css.media = 'print';
	}
	
	return false;
}

var Nav = Class.create();
Nav.prototype = {
	initialize: function(container) {
		this.container = $(container);
		
		if (this.container == null)
			return;
		
		this.togglers  = this.container.childElements('li');
		this.tabs      = this.container.childElements('div.callout');
		this.setup();
	},
	setup: function() {
		this.togglers.each(function(el, i) {
			if (el.down('a.tab')) {
				Event.observe(el, 'mouseover', this.show.bindAsEventListener(this, i));
				Event.observe(el, 'mouseout', this.hide.bindAsEventListener(this, i));
			}
		}.bind(this));
	},
	open: function(event, i) {
		//this.timeout = setTimeout(this.show.bind(this,i), 100);
		//Event.stop(event);
	},
	show: function(event, i) {
		//for(var j=0, l=this.togglers.length; j<l; j++){
		//	this.togglers[j].style.zIndex = 1;
		//}
		//this.togglers[i].style.zIndex = 5;
		this.togglers[i].className = 'active';
		//clearTimeout(this.timeout);
		
	},
	hide: function(event, i) {
		//if (this.timeout) {
		//	clearTimeout(this.timeout);
		//}
		this.togglers[i].className = '';
		//Event.stop(event);
	}
}

var Banner = Class.create();
Banner.prototype = {
	initialize: function(container,content_div) {
		this.container = $(container);
		if (content_div != null)
			this.contentDiv = $(content_div);
		else
			this.contentDiv = null;
			
		if (this.container == null)
			return;
			
		this.togglers  = this.container.down('ul').childElements();
		
		if (this.togglers == null)
			return;
		
		this.banners = [];
		this.anchors = [];
		this.setup();
	},
	setup: function() {
		this.togglers.each(function(el, i) {
			var id = el.identify();
			var b = $(id+ "_banner");
			var a = el.down('a');
			
			if (a != null && (b != null || this.contentDiv != null))
			{
				if(this.contentDiv == null)
					this.banners[i] = b;
				this.anchors[i] = a;
				a.onclick = this.onclck;
				
				//if (this.banners[i].className == '')
				//	this.banners[i].className = 'hidden';
				
				Event.observe(a, 'click', this.show.bindAsEventListener(this, i));
			}
		}.bind(this));
	},
	show: function(event, i) {
		for(var j=0; j < this.anchors.length; j++)
		{
			if (i == j)
			{
				this.anchors[j].className = 'active';
				
				if (typeof(trackThisPage) == 'function')
					trackThisPage(this.anchors[j].href);
				
				if (this.contentDiv == null)
				{					
					this.banners[j].className = 'active';
				}
				else
				{
					var id = this.contentDiv.identify();
					ajax_spin_div(id);
					
					// load the Banner
					new Ajax.Updater(id,this.anchors[j].href, {
						evalScripts : false,
						method: 'GET',
						parameters: {asAjax : 'Y'},
						onComplete : function () {
							new Carousel('page_indicator');
						}
					});
				}
			}
			else
			{
				this.anchors[j].className = 'hidden';
				
				if (this.contentDiv == null)
					this.banners[j].className = 'hidden';
			}
		}
	},
	onclck: function() {
		return false;
	}
}

var Narrow = Class.create();
Narrow.prototype = {
	initialize: function() {
		this.togglers  = $$('div.narrow_wrapper');
		this.setup();
	},
	setup: function() {
		this.togglers.each(function(el, i) {
			if (el.down('a.tab')) {
				Event.observe(el, 'mouseover', this.show.bindAsEventListener(this, i));
				Event.observe(el, 'mouseout', this.hide.bindAsEventListener(this, i));
			}
		}.bind(this));
	},
	show: function(event, i) {

		this.togglers[i].className = 'narrow_wrapper_active';
		
	},
	hide: function(event, i) {
		this.togglers[i].className = 'narrow_wrapper';
	}
}

var Map = Class.create();
Map.prototype = {
	initialize: function(container) {
		this.container = $(container);
		if (this.container == null)
			return;
		this.togglers  = this.container.childElements();
		this.setup();
	},
	setup: function() {
		this.togglers.each(function(el, i) {
			var t = el.down('a');
			if (t)
			{
				Event.observe(t, 'mouseover', this.hover.bindAsEventListener(this, i));
				Event.observe(t, 'mouseout', this.hide.bindAsEventListener(this, i));
				Event.observe(t, 'click', this.open.bindAsEventListener(this, i));
			}
		}.bind(this));
	},
	open: function(event, i) {
		for(var j=0, l=this.togglers.length; j<l; j++){
			if (j != i)
			{
				this.togglers[j].style.zIndex = 1;
				this.togglers[j].className = '';
			}
		}
		this.togglers[i].style.zIndex = 5;
		this.togglers[i].className = 'active';
		//clearTimeout(this.timeout);
		
	},
	hover: function(event, i) {
		for(var j=0, l=this.togglers.length; j<l; j++){
			this.togglers[j].style.zIndex = 1;
		}
		this.togglers[i].style.zIndex = 5;
		if (this.togglers[i].className != 'active')
			this.togglers[i].className = 'hover';
		//clearTimeout(this.timeout);
		
	},
	hide: function(event, i) {
		//if (this.timeout) {
		//	clearTimeout(this.timeout);
		//}
		
		if (this.togglers[i].className == 'hover')
		{
			this.togglers[i].style.zIndex = 1;
			this.togglers[i].className = '';
		}
		//Event.stop(event);
	}
}
var Carousel = Class.create();
Carousel.prototype = {
	initialize: function(container) {
		if (container == null)
			container = "page_indicator";
		
		this.container = $(container);
		if (this.container == null)
			return;
			
		this.buttons  = this.container.childElements('a');
		this.services = [{'id':'service.splash','className':''}];
		this.pages = [];
		this.setup();
	},
	setup: function() {
		var cnt = 0;
		this.buttons.each(function(el, i) {
			cnt = cnt + 1;
			this.pages[i] = $(el.id+ ".detail");
			if (this.pages[i] != null) {
				this.setupPage(i);
				el.onclick = function(evt) { return false; };
				Event.observe(el, 'click', this.showPage.bindAsEventListener(this, i));
			}
		}.bind(this));
		
		// implement scollbars ------
		var left = this.container.previous().down('a');
		var right = this.container.next().down('a');
		
		// attach events
		if (cnt <= 1)
		{
			left.style.display = 'none';
			right.style.display = 'none';
		}
		else
		{
			left.onclick = function(evt) { return false; };
			right.onclick = function(evt) { return false; };
			Event.observe(left, 'click', this.scrollPage.bindAsEventListener(this, left, 'left'));
			Event.observe(right, 'click', this.scrollPage.bindAsEventListener(this, right, 'right'));
		}
	},
	setupPage: function(i) {
		var arr = this.pages[i].childElements('a');
		var len = this.services.length;
		for (var i = 0; i < arr.length; ++i)
		{
			if (arr[i] == null || arr[i].id == '')
				continue;
			
			this.services[len+i] = arr[i];
			arr[i].onclick = function(evt) { return false; };
			Event.observe(arr[i], 'click', this.showService.bindAsEventListener(this, len+i));
		}
	},
	showPage: function(event, i) {
		for (var j = 0; j < this.pages.length; ++j)
		{
			if (i == j)
			{
				this.pages[j].className = 'page_services_active';
				this.buttons[j].className = 'active';
			}
			else
			{
				this.pages[j].className = 'page_services';
				this.buttons[j].className = '';
			}
		}
	},
	showService: function(event, i) {
		for (var j = 0; j < this.services.length; ++j)
		{
			
			var obj = $(this.services[j].id+ ".detail");
			if(obj == null)
				continue;
				
			if (i == j)
			{
				obj.className = 'service_active';
				this.services[j].className = 'active';
			}
			else
			{
				
				obj.className = 'service';
				this.services[j].className = '';
			}
		}
	},
	scrollPage: function(event, obj, direction) {
		var len = this.pages.length;
		for (var j = 0; j < len; ++j)
		{
			var cur = 0;
			if (this.buttons[j].className == 'active')
			{
				// found current page
				if (direction == 'right')
					cur = j + 1;
				else
					cur = j - 1;
					
				if (cur < 0)
					cur = len - 1;
				else if (cur >= len)
					cur = 0;
					
				this.showPage(event,cur);
				break;
			}
		}
		
		return false;
	}
}

/** Tree Explorer Framework */
var AllTreeExplorer = Class.create();
AllTreeExplorer.prototype = {
	/*
		This can be initialized from just an empty div
		or initialized from a fully populated HTML page
	*/
	initialize: function() {
		try
		{
			if (TreeBrowser == null || TreeBrowser.length <= 0)
				return;
		}
		catch(e)
		{
			return;
		}
		
		this.defaultResultsText = "Please use the navigation above to browse these materials.";
		this.detail = null;
		this.dynamicLoad = null;
		this.tree  = $('tree_explorer');
		this.treeBody = $('tree_explorer_body');
		this.firstShown = 1;
		this.maxCols = this.getTreeDepth(TreeBrowser);
		this.selectedDepth = 0;
		this.colWidth = 177;
		this.scrollDelay = 1;
		this.scrollSteps = 10;	//15;
		this.max_len = 23;
		
		// Firefox on Windows doesn't like the scrolling ... so don't do it!
		if (Prototype.Browser.Gecko && navigator.userAgent.indexOf("Windows") > -1)
			this.scrollSteps = 1;
		
		// incorrectly setup calling page
		if (this.tree == null)
			return;
		
		// the <div> where the results are posted
		this.desc = $("tree_description_wrapper");
		this.results = $('tree_explorer_results');
		
		// add the left and right arrows ----

		// NOTE: creating w/prototype Element('div')
		// does not allow adding onclicks via Event.observe/attachEvent
		// for some strange reason

		this.leftArrow = document.createElement('div');
		this.leftArrow.id='tree_explorer_left_arrow';
		this.leftArrow.style.visibility='hidden';
		this.leftArrow.appendChild(new Element("a",{'href':'','title':'previous','onclick':'return false;'}));

		this.leftArrow.onclick = function(evt) { return false; };
		Event.observe(this.leftArrow, 'click',this.scrollLeft.bindAsEventListener(this));


		this.rightArrow = document.createElement('div');
		this.rightArrow.id="tree_explorer_right_arrow";
		this.rightArrow.style.visibility="hidden";
		this.rightArrow.appendChild(new Element("a",{'href':'','title':'next','onclick':'return false;'}));

		this.rightArrow.onclick = function(evt) { return false; };
		Event.observe(this.rightArrow, 'click',this.scrollRight.bindAsEventListener(this));
		
		$('tree_explorer_footer').insert(this.leftArrow);
		$('tree_explorer_footer').insert(this.rightArrow);
		
		var changed = this.getSelected();
		
		if ($("tree_column_0") != null)
		{
			// the basic widget has already been rendered by the HTML, so just initialize
			this.setup(TreeBrowser,0, !changed);
		}
		else
		{
			// we need to build the widget from the javascript def
			var temp = $("tree_explorer_header");
			for (var i = 0; i < this.maxCols; ++i)
			{
				var ul = new Element("ul", {'id': "tree_column_"+i});
				temp.insert({after:ul});
				temp = ul;
			}
			
			this.setup(TreeBrowser,0, false);
		}

		this.paths = this.getPaths(TreeBrowser);
		
	},
	getTreeDepth: function(obj) {
		var max = 0;
		for (node_id in obj)
		{
			if (obj[node_id]['children'] != null)
			{
				max = Math.max(max,this.getTreeDepth(obj[node_id]['children']));
			}
		}
		
		return max + 1;
	},
	/*
		Set up the tree columns starting at the current location
		obj - the Object where the keys, values pairs represent the nodes in the tree
		start - the level from which we are starting
		init_only - true = HTML already generated, just need to attach events
	*/
	setup: function(obj,start,init_only) {
		

		// loop for each column, except the last one
		for (var i = start; i < this.maxCols; ++i)
		{
			// setup the one individual tree column
			this.setColumn(obj,i,init_only);
			
			try
			{
				// implement tree traversal
				obj = obj[TreeBrowser_selected[i]];
				if (obj != null)
					obj = obj['children'];
			}
			catch(e)
			{
				obj = null;
			}
		}
		
		this.setSelected();
		
		if (this.detail == null)
			return;
		
		// set the description column
		if ( (!init_only || this.desc.innerHTML == '') && this.detail['description'] != '')
		{
			if (this.detail['description'] == '[NULL]')
			{
				this.desc.style.visibility = 'hidden';
			}
			else
			{
				this.desc.style.visibility = 'visible';
				this.desc.innerHTML = '<div class="tree_description">'+
					this.detail['description']+ '</div>';
			}
		}
		else if (!init_only)
		{
			// clean out
			this.desc.innerHTML = '';
		}
		
		if ( (!init_only || this.results.innerHTML == '') && this.detail['href'] != '' && !this.detail['js_only'])
		{
			if (this.detail['new_window'])
			{
				window.open(this.detail['href'],'_new');
			}
			else
			{
				this.startResultsSpinner();
				
				// execute the href action
				new Ajax.Updater(this.results.identify(),this.detail['href'],{
					evalScripts:true,
					parameters: "asAjax=Y",
					method:'get',
					onComplete: new Function("transport","eval('" +this.detail['complete']+ "');")
				});
			}
		}
		else if (!init_only)
		{
			this.resetResults(this.defaultResultsText);
		}
		
		// fix the "arrows" ------
		this.lastShown = 0;
		for (var i = 0; i < TreeBrowser_selected.length; ++i)
		{
			if (TreeBrowser_selected[i] != null && TreeBrowser_selected[i] != '')
				this.lastShown = this.lastShown + 1;
		}
		
		var maxc = 3;
		if (this.desc.style.visibility == 'hidden')
			maxc = 4;
		
		if (this.lastShown >= maxc)
		{
			var nextUL = $("tree_column_" +this.lastShown);
			if (nextUL == null || nextUL.empty())
			{
				// there is no sub-selection
				this.lastShown = this.lastShown - 1;
			}	
			
			to_firstShown = this.lastShown - 1;
		}
		else
			to_firstShown = 1;
			
		this.scrollHorizontal(to_firstShown);

	},
	resetResults: function(txt) {
		this.results.innerHTML = "<div>" +txt+ "</div>";
	},
	startResultsSpinner: function() {
		var container = this.results;

		var spin_div = document.createElement("div");
		spin_div.style.position = 'absolute';
		spin_div.style.top = '0px';
		spin_div.style.left = '0px';
		spin_div.style.width = container.offsetWidth+'px';
		spin_div.style.height = container.offsetHeight+'px';
		spin_div.style.zIndex = 100;
		spin_div.className = 'spin_div';
	
		relative_div = document.createElement("div");
		relative_div.style.position = 'relative';
	
		relative_div.appendChild(spin_div);
	
	
		var first_child = container.firstDescendant();
		if (first_child == null)
		{
			container.insert(spin_div);
		}
		else
			first_child.parentNode.insertBefore(relative_div, first_child);

	},
	startDescSpinner: function() {
		var first = this.desc.firstDescendant();
		if (first == null)
			return;
		
		var height = first.getStyle('height');
		var paddingtop = first.getStyle('padding-top');
		var paddingbottom = first.getStyle('padding-bottom');
		var paddingleft = first.getStyle('padding-left');
		var paddingright = first.getStyle('padding-right');
		var overflow = first.getStyle('overflow');
		
		first.innerHTML = "Loading New Content";
		first.className = 'spin_div';
		
		try
		{
			first.setStyle({
				'height': height,
				'paddingTop': paddingtop,
				'paddingBottom': paddingbottom,
				'paddingLeft': paddingleft,
				'paddingRight': paddingright,
				'overflow': overflow
			});
		}
		catch(e){}
	},
	/*
		Set up the tree columns starting at the current location
		obj - the Object where the keys, values pairs represent the nodes in the tree
		start - the level from which we are starting
		init_only - true = HTML already generated, just need to attach events
	*/
	setColumn: function(obj,i,init_only) {
		var ul = $("tree_column_" +i);
		
		if (!init_only)
		{
			// clear all the existing li from object ul
			while (!ul.empty())
				ul.down().remove();
		}
		
		// quit, don't replace with anything
		if (obj == null)
			return;
		
		// the currently selected node
		var selected = TreeBrowser_selected[i];
		
		// add the current items to the <ul>
		for (node_id in obj)
		{
			var thenode = obj[node_id];
			if (typeof(thenode) != 'object')
				continue;
				
			var html_node_id = "subtree_" +node_id;	
			var a = null;
			var li = null;
			
			if (node_id == selected)
				this.detail = thenode;
			
			if (!init_only)
			{
				if (node_id == selected)
				{
					var className = "active";
					if (thenode['autoSelect'] != null && (TreeBrowser_selected[i+1] == null || TreeBrowser_selected[i+1] == ''))
						TreeBrowser_selected[i+1] = thenode['autoSelect'];
					
					// make sure we don't have to dynamically load
					if (this.beginDynamicLoad(thenode,i))
					{ }
				}
				else
					var className = '';
				
				// create the HTML elements
				var params = {'href' : thenode['href'], 'id' : html_node_id, 'class' : className,'title' : thenode['text']};
				
				// allow new window ---
				if (thenode['new_window'])
					params['target'] = '_new';
				else if (! thenode['follow_url'])
					params['onclick'] = 'return false;';
					
				li = new Element("li");
				a = new Element("a",params);
				a.update(this.truncateTitle(thenode));				
				li.insert(a);
				ul.insert(li);
			}
			else
			{
				// already exists, just need to get reference
				
				// make sure we don't have to dynamically load
				if (node_id == selected)
				{
					if (this.beginDynamicLoad(thenode,i))
					{ }
				}
				
				a = $(html_node_id);
				if (a == null)
					continue;

				li = a.up();
			}
			
			// fix onclick
			if (!thenode['new_window'] && !thenode['follow_url'])
				a.onclick = function(evt) { return false; };
			
			if (node_id == selected)
			{
				// fix possible scrolling issues with previously selected nodes
				var scrollLoc = ul.scrollTop + ul.offsetHeight - li.scrollHeight;
				if (scrollLoc < li.offsetTop)
				{
					// out of frame, need to scroll here
					ul.scrollTop = li.offsetTop - scrollLoc + li.scrollHeight ;
				}
			}
			
			// attach event on click
			if (!thenode['follow_url'])
				a.observe('click',this.select.bindAsEventListener(this,thenode,html_node_id,ul,i), null, 'Three'); // TODO: remove
		}
	},
	/**
		This method actually gets called when a user clicks on an item in the tree column
		event - reference for the event
		obj - the object defining this entity
		html_node_id - the 'id' of the anchor tag clicked
		ul - the containing ul of the anchor tag
		i - the column number
	*/
	select: function(event, obj, html_node_id, ul, i) {
		var node_id = obj['id'];
		this.detail = obj;
		TreeBrowser_selected[i] = node_id;
		
		// make sure the scroller is correct -----
		var top_offset = this.tree.cumulativeOffset();
		var offset = document.viewport.getScrollOffsets();
		if (offset['top'] < top_offset[1])
			this.tree.scrollTo();
		
		// set the class to active, correctly
		ul.childElements().each(function(li) {
			var a = li.down();
			if(a.identify() == html_node_id)
			{
				a.className = 'active';
			}
			else
				a.className = '';
		});
		
		var extra = 0;
		if (obj['autoSelect'] != null)
		{
			// implement auto select
			TreeBrowser_selected[i+1] = obj['autoSelect'];
			extra = 1;
		}
		
		// update the columns to the right of the current one
		for (var j = i+extra+1; j < this.maxCols; ++j)
		{
			TreeBrowser_selected[j] = null;
		}
		
		try
		{
			this.trackClick(i+extra);
			if (!this.beginDynamicLoad(obj,i))
			{
				// re-setup the columns from the current selection
				this.setup(obj['children'],i+1, false);
			}			
		}
		catch(e)
		{ }
		
	},
	trackClick: function(curr_pos) {
		
		var uri = this.getURLToken();
		
		if (uri.charAt(uri.length-1) == '/')
			uri = uri+ "index.htm";
		
		for (var i = 0; i <= curr_pos; ++i)
		{
			uri = uri + '/' +TreeBrowser_selected[i];
		}
		
		if (typeof(trackThisPage) == 'function')
			trackThisPage(uri);
	},
	getURLToken: function() {
		var s = location.href;
		s = s.split("?");
		return s[0];
	},
	scrollLeft: function(event) {
		var to_showFirst = Math.max(1,this.firstShown-1);
		this.scrollHorizontal(to_showFirst);
	},
	scrollRight: function(event) {
		
		var to_showFirst = Math.min(this.lastShown-1,this.firstShown+1);
		this.scrollHorizontal(to_showFirst);
		
	},
	scrollHorizontal: function(to_showFirst) {
		
		var startLeft = -1*parseInt(this.colWidth*(this.firstShown-1));
		var endLeft = -1*parseInt(this.colWidth*(to_showFirst-1));
		
		var i = 2;
		if (this.desc.style.visibility == 'hidden')
			i = 3;
		
		if (to_showFirst > 1)
			this.leftArrow.style.visibility = 'visible';
		else
			this.leftArrow.style.visibility = 'hidden';
		if (to_showFirst+i <= this.lastShown)
			this.rightArrow.style.visibility = 'visible';
		else
			this.rightArrow.style.visibility = 'hidden';
		
		// scroll over (animate)!
		var nbr_steps = this.scrollSteps;
		var increment = Math.floor((endLeft - startLeft)/nbr_steps);
		this.scrollSleep(endLeft,startLeft,increment);
		//--------
		
		this.firstShown = to_showFirst;
	},
	scrollSleep: function(final_stop,cur_at,increment) {
		var diff = final_stop - cur_at;
		if (Math.abs(diff) < Math.abs(increment))
			increment = diff;
		
		var to = cur_at+increment;
		var to_desc = parseInt(this.desc.getStyle('left'))+ -1*increment;
		this.treeBody.style.left = to+ "px";
		this.desc.style.left = to_desc+ "px";
		
		if (to != final_stop)
			window.setTimeout("treeExplorerHandle.scrollSleep(" +final_stop+ "," +to+ "," +increment+ ");",this.scrollDelay);
	},
	updateSelected: function(node_id) {
		TreeBrowser_selected = this.paths[node_id].clone();
		this.setup(TreeBrowser,0,false);
	},
	setSelected: function() {
		var str = '';
		for (var i = 0; i < TreeBrowser_selected.length; ++i)
		{
			if (TreeBrowser_selected[i] == null)
				break;
				
			if (i > 0)
				str = str + "`";
			str = str + TreeBrowser_selected[i];
		}
		
		var name = "tree_" +this.getURLToken();
		document.cookie = name+ "=" +str;
	},
	getSelected: function() {
		
		var any = false;
		for (var i =0; i < TreeBrowser_selected.length; ++i)
		{
			if (TreeBrowser_selected[i] == null || TreeBrowser_selected[i] == '')
				continue;
			
			any = true;
			break;
		}
		
		if (!any)
		{
			// use the cookie value to get the selected ----
			var name = "tree_" +this.getURLToken();
			var cookies = document.cookie.split(";");
			
			for (var i = 0; i < cookies.length; ++i)
			{
				if (cookies[i].indexOf(name) >= 0)
				{
					var temp = cookies[i].split("=");
					TreeBrowser_selected = temp[1].split("`");
					return true;
				}
			}
			
			if (TreeBrowser_selectFirst)
			{
				// nothing selected, but initial config says to auto select the first
				for (node_id in TreeBrowser)
				{
					TreeBrowser_selected[0] = node_id;
					break;
					// only get the first one
				}
			}
			
			return true;
		}
		
		return false;
	},
	truncateTitle: function(thenode) {
		
		var title = thenode['text'];
		if (title == null)
			return title;
		
		if (thenode['no_truncate'])
			return title;
		
		title = title.stripTags();
		var len = title.length;
		if (len > this.max_len)
			return title.substr(0,this.max_len-4)+ "&nbsp;...";
		else
			return title;
	},
	beginDynamicLoad: function(obj,i) {
		// try to dynamically load, if needed ---
		if (obj['dynamic_load'] && obj['dynamic_href'] != '')
		{
			this.dynamicLoad = {"obj":obj,"i":i};
			this.startDescSpinner();
			
			// go get the new stuff
			new Ajax.Request(obj['dynamic_href'],{
				evalScripts:true,
				parameters: "asAjax=Y",
				method:'get',
				onSuccess: this.finishDynamicLoad
			});
			
			return true;
		}
		
		return false;
	},
	finishDynamicLoad: function(transport) {
	//alert(transport.responseText);
		try{
		// add response to the tree definition ----
		treeExplorerHandle.dynamicLoad["obj"]["children"] = transport.responseText.evalJSON(true);

		
		// recalculate some things from this adjustment
		treeExplorerHandle.maxCols = treeExplorerHandle.getTreeDepth(TreeBrowser);
		var temp = $("tree_column_"+ treeExplorerHandle.dynamicLoad['i']);
		for (var i = treeExplorerHandle.dynamicLoad['i']; i < treeExplorerHandle.maxCols; ++i)
		{
			// make sure the <ul> exists
			var junk = $("tree_column_"+i);
			if (!junk)
			{
				var ul = new Element("ul", {'id': "tree_column_"+i});
				temp.insert({after:ul});
				temp = ul;
			}
			else
				temp = junk;
		}
		
		treeExplorerHandle.setup(treeExplorerHandle.dynamicLoad["obj"]["children"],treeExplorerHandle.dynamicLoad["i"]+1,false);
		treeExplorerHandle.dynamicLoad["obj"]['dynamic_load'] = false;
		treeExplorerHandle.paths = treeExplorerHandle.getPaths(TreeBrowser);

		//treeExplorerHandle.dynamicLoad = null;
		}catch(e){alert(e);}
	},

	// return obj where keys are node_ids
	// and values are arrays of node ids that 
	// represent path to node
	
	getPaths: function(tree_root)
	{
		paths_obj = new Object;
		this.calculatePaths(paths_obj, tree_root);
		return paths_obj;
 	},

	// calculate the paths to each node
	// so that can find path from root.
	// paths_obj - object keys are node_ids, values are 
	//  	arrays that represent path to node
	// tree_branch - branch currently being calculated
	// current_path path to this node

	calculatePaths: function(paths_obj, tree_branch, current_path)
	{
		if (current_path == null)
			current_path = new Array();

		for (key in tree_branch) {
			new_path = current_path.clone();
			id = tree_branch[key]['id']
			new_path[new_path.length] = key;

			if (!paths_obj[id]) {
				paths_obj[id] = new_path;
			}

			if (tree_branch[key]['children'] ) {
				this.calculatePaths(paths_obj, tree_branch[key]['children'], new_path);
			}
		}
	}

}

var treeExplorerHandle = null;

function loadBanner()
{
	// load the Banner -----
	var t = $('banner_navigation');
	if (t != null)
	{
		if (t.className == 'asAjax')
		{
			// load the Banner
			ajax_spin_div('banner_content');
			new Ajax.Updater('banner_content',t.down('ul').down('li').down('a').href, {
				evalScripts : false,
				method: 'GET',
				parameters: {asAjax : 'Y'},
				onComplete : function () {
					new Banner('banner_navigation','banner_content');
					new Carousel('page_indicator');
				}
			});
		}
		else
		{
			// load the Banner
			new Ajax.Updater('banner_content',t.down('ul').down('li').down('a').href, {
				evalScripts : false,
				method: 'GET',
				insertion: Insertion.Bottom,
				onComplete : function () {
					new Banner('banner_navigation',null);
					new Map('map');
					new Carousel('page_indicator');
				}
			});
		}
	}
}

function newMap()
{
	new Map('map');
}

/*
	parseUri 1.2.1
	(c) 2007 Steven Levithan <stevenlevithan.com>
	MIT License
*/

function parseUri (str) {
	var	o   = parseUri.options,
		m   = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
		uri = {},
		i   = 14;

	while (i--) uri[o.key[i]] = m[i] || "";

	uri[o.q.name] = {};
	uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
		if ($1) uri[o.q.name][$1] = $2;
	});

	return uri;
};

parseUri.options = {
	strictMode: false,
	key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
	q:   {
		name:   "queryKey",
		parser: /(?:^|&)([^&=]*)=?([^&]*)/g
	},
	parser: {
		strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
		loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
	}
};


function trackThisPage(uri)
{
	if (pageTracker != null)
	{
		var uriO = parseUri(uri);
		var uri = uriO['path'];
		if (uri == '/')
			uri = uri+ "index.htm";
		
		if (uriO['anchor'] != '')
			uri = uri+ "/" +uriO['anchor'];
		
		pageTracker._trackPageview(uri);
	}
}

Event.onDOMReady(function(){
	new Nav('nav');
	new Narrow();
	treeExplorerHandle = new AllTreeExplorer();
	loadBanner();
	
	//if ($('internal_banner') != null)
	//	$('main_nav_wrapper').scrollTo();
	
	//new Map('map');
	//new Carousel('page_indicator');
	//setupZoom();
});


// manipulate the z-index of header so that on IE
// livesearch appears on top of main menu when it pops up
// but below when it closes

function live_search_on_open() { $('header_wrapper').style.zIndex = 11; }

function live_search_on_close() { $('header_wrapper').style.zIndex = 10; }


//-------------------------
// functions to select/copy
//-------------------------

function nav_select(object_id)
{
	nav_deselect();
	if (window.getSelection) 
	{
		var range = document.createRange();
		range.selectNode(document.getElementById(object_id));
		window.getSelection().addRange(range);
   	}
	else if (document.selection) 
	{
		var range = document.body.createTextRange();
		range.moveToElementText(document.getElementById(object_id));
		range.select();
	}
}

function nav_deselect() 
{
	if (document.selection)
		document.selection.empty();
	else if (window.getSelection)
		window.getSelection().removeAllRanges();
} 


function nav_copy(object_id)
{
	var enabled = false;

	nav_select(object_id);

	if ( Prototype.Browser.IE )
	{

		var onEvent = function()
		{
			enabled = true ;
		};

		// IE will not throw exception if it doesn't work,
		// but, will raise event if it does work.
		var eventName = 'oncopy';

		window.document.body.attachEvent( eventName, onEvent ) ;

		if ((typeof nav_beforeCopyFromIE) == 'function') 
		{
			// since IE will copy background, can create
			// nav_beforeCopyFromIE function to 
			// chg background color to white before copy
			nav_beforeCopyFromIE();
		}

		window.document.execCommand('Copy') ;

		if ((typeof nav_afterCopyFromIE) == 'function') 
		{
			nav_afterCopyFromIE();
		}

		window.document.body.detachEvent( eventName, onEvent ) ;
	}
	else
	{
		try
		{
			// Other browsers throw an error if the command is disabled.
			window.document.execCommand('Copy') ;
			enabled = true ;
		}
		catch(e){}
	}

	if ( !enabled )
		alert( "Your browser's security settings do not permit the site to automatically execute copy operations.\nPlease use the keyboard for that (CTRL-C). ");
	else
		alert("The text has now been copied to your clipboard.\n");

}
