// Object constructor for the menu element
function menuElement(initDivName, initOnHeight, initOffHeight, initOnClassName, initOffClassName)
{
	// Private members
	var divName = null;
	var onHeight = null;
	var offHeight = null;
	var onClassName = null;
	var offClassName = null;
	var active = false;
	setDivName(initDivName);
	setOnHeight(initOnHeight);
	setOffHeight(initOffHeight);
	setOnClassName(initOnClassName);
	setOffClassName(initOffClassName);

	//Public Method Pointers
	this.getDivName = getDivName;
	this.setDivName = setDivName;
	this.getOnHeight = getOnHeight;
	this.setOnHeight = setOnHeight;
	this.getOffHeight = getOffHeight;
	this.setOffHeight = setOffHeight;
	this.getOnClassName = getOnClassName;
	this.setOnClassName = setOnClassName;
	this.getOffClassName = getOffClassName;
	this.setOffClassName = setOffClassName;
	this.setActive = setActive;
	this.getActive = getActive;
	this.isActive = isActive;

	//Getters and Setters (public, as they have pointers)
	function getDivName() { return divName; }
	function setDivName(valDivName) { divName = valDivName; }
	function getOnHeight() { return onHeight; }
	function setOnHeight(valOnHeight) { onHeight = valOnHeight; }
	function getOffHeight() { return offHeight; }
	function setOffHeight(valOffHeight) { offHeight = valOffHeight; }
	function getOnClassName() { return onClassName; }
	function setOnClassName(valOnClassName) { onClassName = valOnClassName; }
	function getOffClassName() { return offClassName; }
	function setOffClassName(valOffClassName) { offClassName = valOffClassName; }
	function setActive(valActive) { active = valActive; }
	function getActive() { return active; }
	
	// Other public functions
	function isActive()
	{
		var returnBool;
		var divNameStr = getDivName();
		var curDiv = document.getElementById(divNameStr);
		if (curDiv.className == getOnClassName()) returnBool = true;
		else returnBool = false;
		setActive(returnBool);
		return getActive();
	}
}



// Object constructor for the dynamicMenu
function dynamicMenu(initProgramVersionId, initText, initHyperlink, initState)
{
	// Private members
	var programVersionId = null;
	var text = null;
	var hyperlink = null;
	var state = null;
	var active = false;
	setProgramVersionId(initProgramVersionId);
	setText(initText);
	setHyperlink(initHyperlink);
	setState(initState);
	
	// Public members
	this.elements = new Array();
	
	//Public Method Pointers for general methods
	this.expand = expand;
	this.collapse = collapse;
	this.toggleState = toggleState;
	this.addElement = addElement;
	this.isActive = isActive;
	this.setActive = setActive;

	//Public Methods (they all have pointers)
	//Getters and Setters
	function getProgramVersionId() { return programVersionId; }
	function setProgramVersionId(valProgramVersionId) { programVersionId = valProgramVersionId; }
	function getText() { return text; }
	function setText(valText) { text = valText; }
	function getHyperlink() { return hyperlink; }
	function setHyperlink(valHyperlink) { hyperlink = valHyperlink; }
	function getState() { return state; }
	function setState(valState) { if (valState == "on" || valState == "off") state = valState; }
	function getActive() { return active; }
	function setActive(valActive) { active = valActive; }
	
	// *** General Methods ***

	// Collapses the menu item, turning it off
	function collapse(valElements)
	{
		for (i=0; i<valElements.length; i++)
		{
			var curDiv = document.getElementById(valElements[i].getDivName());
			var newHeight = null;
			var newClassName = valElements[i].getOffClassName();
			
			if (typeof(valElements[i].getOffHeight()) == "number") newHeight = valElements[i].getOffHeight() + "px";
			else newHeight = valElements[i].getOffHeight();

			if (newClassName != "") curDiv.className = newClassName;
			curDiv.style.height = newHeight;
		}
		setState("off");
	}
	
	function expand(valElements)
	{
		for (i=0; i<valElements.length; i++)
		{
			var curDiv = document.getElementById(valElements[i].getDivName());
			var newHeight = null;
			var newClassName = valElements[i].getOnClassName();

			if (typeof(valElements[i].getOnHeight()) == "number") newHeight = valElements[i].getOnHeight() + "px";
			else newHeight = valElements[i].getOnHeight();

			if (newClassName != "") curDiv.className = newClassName;
			curDiv.style.height = newHeight;
		}
		setState("on");
	}


	// Adds an element to the menu item.  Returns success boolean.
	function addElement(valElement)
	{
		if (typeof(valElement) == "object")
		{
			var oldLen = this.elements.length;
			var newLen = this.elements.push(valElement);
			if (newLen > oldLen) return true;
			else return false;
		}
		else return false;
	}
	

	// Toggles the on/off state of the menu
	function toggleState()
	{
		var oldState = state;
		if (state == "on")
		{
			collapse(this.elements);
			setActive(false);
		}
		else if (state == "off")
		{
			expand(this.elements);
			setActive(true);
		}
		return getActive();
	}


	// Return boolean indicator showing whether or not this menu (rather, any of it's elements) are active
	function isActive()
	{
		// Loop through all the child elements and check each one to see if it's active
		for (var i = 0; i < this.elements.length; i++)
		{
			// alert("Running isActive in the dynamic menu.\nThere are " + this.elements.length + " elements in the dynamic menu.");
			var curElement = this.elements[i];
			isElementActive = curElement.isActive();
			// When / if we find one that is active, set this menu's active property to true and break the loop
			// alert("Element: " + curElement.getDivName());
			if (isElementActive)
			{
				setActive(true);
				setState("on");
				break;
			}
		}
		return getActive();
	}
}






// Object constructor for the menu block
function menuBlock(initProgramVersionId)
{
	// Private members
	var programVersionId = null;
	var lastActiveMenu = null;
	setProgramVersionId(initProgramVersionId);
	
	// Public members
	this.menus = new Array();
	
	//Public Method Pointers for Getters/Setters
	this.getProgramVersionId = getProgramVersionId;
	this.setProgramVersionId = setProgramVersionId;
	this.setLastActiveMenu = setLastActiveMenu;
	this.getLastActiveMenu = getLastActiveMenu;
	
	//Public Method Pointers for general methods
	this.collapseAllMenus = collapseAllMenus;
	this.expandLastActive = expandLastActive;
	this.addMenu = addMenu;

	//Public Methods (they all have pointers)
	//Getters and Setters
	function getProgramVersionId() { return programVersionId; }
	function setProgramVersionId(setProgramVersionId) { programVersionId = setProgramVersionId; }
	function getLastActiveMenu() { return lastActiveMenu; }
	function setLastActiveMenu(valLastActiveMenu) { lastActiveMenu = valLastActiveMenu; }
	
	// General Methods
	
	// Collapses all menus in this menu block
	function collapseAllMenus()
	{
		//  Loop over all the menus contained within
		for (var i=0; i<this.menus.length; i++)
		{
			var curMenu = this.menus[i];
			// Check to see if the menu in this iteration was active, save it's index if so
			if (curMenu.isActive()) setLastActiveMenu(i);
			// Collapse and set active to false
			curMenu.collapse(curMenu.elements);
			curMenu.setActive(false);
		}
	}
	
	// Expands the previously active menu in the block
	function expandLastActive()
	{
		//  Loop over all the menus contained within
		for (var i=0; i<this.menus.length; i++)
		{
			var curMenu = this.menus[i];
			// Check to see if the menu in this iteration was last active, expand it if so
			if ((getLastActiveMenu() == i) && !curMenu.isActive()) curMenu.toggleState();
		}
	}

	// Adds menu to the menu block.  Returns success boolean.
	function addMenu(dynamicMenu)
	{
		if (typeof(dynamicMenu) == "object")
		{
			oldLen = this.menus.length;
			newLen = this.menus.push(dynamicMenu);
			if (newLen > oldLen) return true;
			else return false;
		}
		else return false;
	}
}
