/**
 * This file oversees the vertical expansion and collapse of divs.  The menu  must
 * be inside of its controller element in the DOM.
 * 
 *	 Expansion:	Slide up
 *	 Collapse:	Slide down
 *
 *  To switch the expansion and collapse, change style.bottom to style.top in the
 *  addMenu function.
 *
 *	Menu objects have the following properties:
 *		direction			1 is up, -1 is down
 *		endHeight			style.height at which div should stop sliding (in px)
 *		expanded			whether the menu is fully expanded
 *		moving				whether or not the div is sliding
 *		parentDivId			id of the control that activates sliding
 *		slideAmount			number of pixels to slide each time
 *		startTime			when the div last started moving in 'direction'
 *		timer				the timer that calls the slide function
 *
 *		menuObject			the menu
 *		controllerObject	the controller for sliding the menu
 */

var menus = new Array();		// holds menus and their states
var timerLength = 5;			// how often to update
var slideNormalize = 200;		// how quickly to slide, lower = faster

// Adds a new menu to the array
function addMenu(navMenuId, fullHeight, controlId)
{
	menus[navMenuId] = new Object();
	menus[navMenuId].direction = -1;	// set up menu for expanding
	menus[navMenuId].endHeight = fullHeight;
	menus[navMenuId].expand = false;
	menus[navMenuId].moving = false;
	menus[navMenuId].parentDivId = controlId;
	
	// Uncomment for expanding/collapsing in a certain amount of time
	// menus[navMenuId].slideAmount = Math.round(timerLength / slideNormalize * fullHeight)
	menus[navMenuId].slideAmount = 10;
	
	// set up mouse events for control and menu
	var controller = document.getElementById(controlId);
	controller.onmouseover = new Function('expand("' + navMenuId + '")');
	controller.onmouseout = new Function('collapse("' + navMenuId + '")');
	
	// style menu
	var navMenu = document.getElementById(navMenuId);
	navMenu.onmouseover = new Function('expand("' + navMenuId + '")');
	navMenu.onmouseout = new Function('collapse("' + navMenuId + '")');
	navMenu.onclick = new Function('hideMenu("' + navMenuId + '")');
	navMenu.style.visibility = 'hidden';
	
	// set menu to be positioned
	menus[navMenuId].positioned = false;
	
	// save objects
	menus[navMenuId].menuObject = navMenu;
	menus[navMenuId].controllerObject = controller;
}

// Hides menu so back button will not show menus
function hideMenu(navMenuId)
{
	var navMenu = menus[navMenuId].menuObject;
	navMenu.style.visibility = 'hidden';
	collapse(navMenuId);
}

// Slides a div navigation menu up
function expand(navMenuId)
{
	/* always position in case user has resized windows	*/
	var controller = menus[navMenuId].controllerObject;
	var navMenu = menus[navMenuId].menuObject;
	
	// center menu over controller
	var offsetLeft;
	if (navigator.appName == 'Microsoft Internet Explorer')
	{
		offsetLeft = getLeftPosition(controller);
	}
	else
	{
		offsetLeft = controller.offsetLeft;
	}
	
	/* Uncomment to offset in the middle */
	//offsetLeft += Math.round(controller.clientWidth/2) - Math.round(navMenu.clientWidth/2);
	navMenu.style.left = offsetLeft;
	
	navMenu.style.top = menus[navMenuId].endHeight + 4;
	menus[navMenuId].positioned = true;

	if (menus[navMenuId].moving == true)
	{
		// only set a direction if the menu is sliding down
		if (menus[navMenuId].direction == -1)
		{
			menus[navMenuId].direction = 1;
		}
		// do nothing since the slide function will take care of what to do
	}
	// only start expanding if menu is not expanded already
	else if (!menus[navMenuId].expanded)
	{		
		menus[navMenuId].moving = true;
		menus[navMenuId].direction = 1;
		menus[navMenuId].timer = setInterval('slide("' + navMenuId + '")', timerLength);
		menus[navMenuId].menuObject.style.visibility = 'visible';
		menus[navMenuId].menuObject.style.height = '1px';
	}
}

// Slides a div navigation menu down
function collapse(navMenuId)
{
	if (menus[navMenuId].moving == true)
	{
		// only set a direction if the menu is sliding up
		if (menus[navMenuId].direction == 1)
		{
			menus[navMenuId].direction = -1;
		}
		// do nothing since the slide function will take care of what to do
	}
	// only start collapsing if menu is expanded
	else if (menus[navMenuId].expanded)
	{
		menus[navMenuId].moving = true;
		menus[navMenuId].direction = -1;
		menus[navMenuId].expanded = false;
		menus[navMenuId].timer = setInterval('slide("' + navMenuId + '")', timerLength);
	}
}

// Slides a div navigation menu a calculated amount of pixels
function slide(navMenuId)
{
	// get the current height
	var pxIndex = menus[navMenuId].menuObject.style.height.indexOf('px');
	var currentHeight = menus[navMenuId].menuObject.style.height.substring(0, pxIndex) * 1;

	// if sliding up
	if (menus[navMenuId].direction == 1)
	{
		// if this would be the last slide, make the height the full height of the menu
		if ((currentHeight+menus[navMenuId].slideAmount) >= menus[navMenuId].endHeight)
		{
			clearInterval(menus[navMenuId].timer);
			menus[navMenuId].menuObject.style.height = menus[navMenuId].endHeight + 'px';
			menus[navMenuId].moving = false;
			menus[navMenuId].expanded = true
		}
		else
		{
			menus[navMenuId].menuObject.style.height = (currentHeight+menus[navMenuId].slideAmount) + 'px';
		}
	}
	// if sliding down
	else
	{
		// if this would be the last slide, make the height 0px and hide the menu
		if ((currentHeight-menus[navMenuId].slideAmount) <= 0)
		{
			clearInterval(menus[navMenuId].timer);
			menus[navMenuId].menuObject.style.visibility = 'hidden';
			menus[navMenuId].moving = false;
		}
		else
		{
			menus[navMenuId].menuObject.style.height = (currentHeight-menus[navMenuId].slideAmount) + 'px';
		}
	}
}

// for positioning in IE
function getLeftPosition(element)
{
	var curLeft = 0;
	
	if (element.offsetParent)
	{
		do
		{
			curLeft += element.offsetLeft;
		} while (element = element.offsetParent);
	}
	
	return curLeft;
}
