
function MenuItem(parentMenuItem, activity, documentObject, isClone) {

	this.ParentMenuItem = parentMenuItem;
	
	//JMH - 1/20/07 - No longer storing the activity data on the menu object since sometimes we'll be rendering
	// lookahead data and sometimes "real-time" sequencing data.  Appropriate methods now take the activity as a parameter.
	// The activity passed into the constructor is used to get the ActivityId, which will never change and is also 
	// used to initialize the display.
	//this.Activity = activity; 
	this.Document = documentObject;

	//MR - 10/27/06 - Changing from just the Item Identifier to a combination of item identifier and database identifier
	//when it was just item identifier, the getElementById function would not distinguish between elements that 
	//differed only by case. Keeping the item identifier to make the ids less cryptic and easier to work with.
	this.ActivityId = activity.GetItemIdentifier() + activity.GetDatabaseIdentifier();
	this.MenuElementId = "MenuItem" + this.ActivityId;
	
	this.DivTag = null;
	
	if (parentMenuItem === null){
		this.Level = 0;
	}
	else{
		this.Level = parentMenuItem.Level + 1;
	}
	
	this.Children = new Array();
	
	this.Visible = true;
	
	// Enabled means "show as a link", Disabled will still show the menu item 
	// but as simple text rather than a link
	this.Enabled = true; 
	
	//create the actual div tag on the DOM
	var node = this.Document.createElement("div");

	node.id = this.MenuElementId;
	
	this.DivTag = node;
	
	this.CurrentDisplayState = null;
	
	this.CurrentDisplayState = IntegrationImplementation.PopulateMenuItemDivTag(node, 
													this.Document, 
													this.ActivityId, 
													activity.GetTitle(), 
													this.Level, 
													activity.IsDeliverable(),
													Control.Package.LearningStandard,
													Control.Package.Properties.StatusDisplay,
													activity.GetItemIdentifier());

	
	

}

MenuItem.prototype.Render = MenuItem_Render;
MenuItem.prototype.UpdateStateDisplay = MenuItem_UpdateStateDisplay;

MenuItem.prototype.Hide = MenuItem_Hide;
MenuItem.prototype.Show = MenuItem_Show;
MenuItem.prototype.Enable = MenuItem_Enable;
MenuItem.prototype.Disable = MenuItem_Disable;
MenuItem.prototype.BumpUpLevel = MenuItem_BumpUpLevel;
MenuItem.prototype.BumpDownLevel = MenuItem_BumpDownLevel;
MenuItem.prototype.ResynchChildren = MenuItem_ResynchChildren;


function MenuItem_Render(activity){
	
	// Figure out the previous node
	var nodeToInsertAfter;
	
	//if this is the root node, insert it at the appropriate spot on the page
	if (this.ParentMenuItem === null){
		nodeToInsertAfter = IntegrationImplementation.GetHtmlElementToInsertMenuWithin();
		nodeToInsertAfter.insertBefore(this.DivTag, null);
		return;
	}
	//otherwise, we need to find the last (grand)child of the previous sibling and insert after it
	else {
		//find the location of this activity within the parent
		var i;
		for (i = 0; i < this.ParentMenuItem.Children.length; i++) {
			if (this.ParentMenuItem.Children[i].ActivityId == this.ActivityId){
				break;
			}
		}	
		
		//if this is the first activity it in the parent, insert right after the parent
		if (i === 0){
			nodeToInsertAfter = this.Document.getElementById(this.ParentMenuItem.MenuElementId);
		}
		else{
			//otherwise, find the immediately previous sibling's last (grand)child
			var prevMenuItem = this.ParentMenuItem.Children[i-1];
			var lastChildOfPrevMenuItem = MenuItem_getLastSubmenuItem(prevMenuItem);		
			nodeToInsertAfter = this.Document.getElementById(lastChildOfPrevMenuItem.MenuElementId);
		}
	}
	
	//there is no "insertAfter" method that is cross browser compatible, so we want to insert between the "after" node
	//and whatever comes next (its nextSibling)
	nodeToInsertAfter.parentNode.insertBefore(this.DivTag, nodeToInsertAfter.nextSibling);
	
	if (activity.DisplayInChoice() === true){
		this.Show();
	}
	else{
		this.Hide();
	}
	
}


function MenuItem_UpdateStateDisplay(activity, currentActivity, navigationRequestInfo, useLookAheadActivityStatus){
	
	var newVisible = true;
	var newEnabled = true;
	
	if (activity.DisplayInChoice() === true){
		newVisible = true;
	}
	else{
		newVisible = false;
	}
	
	// If the nav request won't succeed, hide it if this package is configured to do so
	if ( ! navigationRequestInfo.WillSucceed) 
	{ 
	
		if (Control.Package.Properties.InvalidMenuItemAction == INVALID_MENU_ITEM_ACTION_DISABLE) 
		{
			newEnabled = false;
		}
		else if (Control.Package.Properties.InvalidMenuItemAction == INVALID_MENU_ITEM_ACTION_HIDE) 
		{
			newVisible = false;
		}
		else if (Control.Package.Properties.InvalidMenuItemAction == INVALID_MENU_ITEM_ACTION_SHOW_ENABLE) 
		{
			newVisible = true;
		}
	} 
	else{
		if (Control.Package.Properties.InvalidMenuItemAction == INVALID_MENU_ITEM_ACTION_DISABLE) 
		{
			//this.Enable(this.Activity.GetItemIdentifier(), this.Activity.GetTitle());
			newEnabled = true;
		}
		else if (Control.Package.Properties.InvalidMenuItemAction == INVALID_MENU_ITEM_ACTION_HIDE) 
		{
			newVisible = true;
		}
		else if (Control.Package.Properties.InvalidMenuItemAction == INVALID_MENU_ITEM_ACTION_SHOW_ENABLE) 
		{
			newVisible = true;
		}		
	}
	
	if (newVisible != this.Visible){
		if (newVisible == true){
			this.Show();
		}
		else{
			this.Hide();
		}
	}
	if (newEnabled != this.Enabled){
		if (newEnabled == true){
			this.Enable(activity.GetItemIdentifier(), activity.GetTitle());
		}
		else{
			this.Disable();
		}
	}
	
	this.CurrentDisplayState = IntegrationImplementation.UpdateMenuStateDisplay(this.DivTag, 
													 this.Document, 
													 activity, 
													 this.ActivityId, 
													 activity.IsDeliverable(), 
													 currentActivity, 
													 navigationRequestInfo,
													 Control.Package.LearningStandard,
													 Control.Package.Properties.StatusDisplay,
													 this.CurrentDisplayState,
													 useLookAheadActivityStatus);
}


function MenuItem_Hide(){

	//only affect the div tag if there will be a state change
	if (this.Visible === true){
		this.DivTag.style.display = "none";
		this.BumpDownLevel(this);
	}
	
	this.Visible = false;
}

function MenuItem_Show(){

	//only affect the div tag if there will be a state change
	if (this.Visible === false){
		this.DivTag.style.display = "inline";
		this.BumpUpLevel(this);
	}

	this.Visible = true;
}

function MenuItem_Enable(activityIdentifier, activityTitle){

	//only affect the div tag if there will be a state change
	if (this.Enabled === false){

		// cursor: pointer works for IE 6 and Mozilla browsers.  cursor: hand only works for older IE
		var browserName = navigator.appName; 
		var browserVer = parseInt(navigator.appVersion); 
		if (browserName == "Microsoft Internet Explorer" && browserVer < 6) {
			this.DivTag.onmouseover = function () {this.style.cursor='hand';window.status=activityTitle;return true;};
		} else {
			this.DivTag.onmouseover = function () {this.style.cursor='pointer';window.status=activityTitle;return true;};
		}
		this.DivTag.onclick = function () {window.parent.Control.ChoiceRequest(activityIdentifier);return true;};
	}
	this.Enabled = true;
}

function MenuItem_Disable(){

	//only affect the div tag if there will be a state change
	if (this.Enabled === true){
		this.DivTag.onmouseover = function () {this.style.cursor='default';window.status='';return true;};
		this.DivTag.onclick = "";
	}

	this.Enabled = false;
}

function MenuItem_BumpUpLevel(menuItemToBump){
	
	menuItemToBump.Level++;
	IntegrationImplementation.UpdateIndentLevel(menuItemToBump.DivTag, menuItemToBump.ActivityId, menuItemToBump.Level);
	
	for (var childIndex in menuItemToBump.Children){
		menuItemToBump.BumpUpLevel(menuItemToBump.Children[childIndex]);
	}
}

function MenuItem_BumpDownLevel(menuItemToBump){
	menuItemToBump.Level--;
	IntegrationImplementation.UpdateIndentLevel(menuItemToBump.DivTag, menuItemToBump.ActivityId, menuItemToBump.Level);
	
	for (var childIndex in menuItemToBump.Children){
		menuItemToBump.BumpDownLevel(menuItemToBump.Children[childIndex]);
	}
}

function MenuItem_ResynchChildren(activity){
	
	//remove all the children from the DOM
	var childDivTag;
	for (var childIndex in this.Children){
		childDivTag = this.Children[childIndex].DivTag;
		childDivTag.parentNode.removeChild(childDivTag);
	}
	
	//reset the children to the new children
	this.Children = new Array();
	
	var availableChildren = activity.GetAvailableChildren();
	
	for (var childActivity in availableChildren){
		this.Children[childActivity] = availableChildren[childActivity].MenuItem;
	}

}

//private
function MenuItem_getLastSubmenuItem(menuItem){
	//if there are no children, then this is the last item so return it
	if (menuItem.Children.length === 0){
		return menuItem;
	}
	//otherwise, find the last (grand)child of the last child in this menu item
	else{
		return MenuItem_getLastSubmenuItem(menuItem.Children[menuItem.Children.length -1]);
	}
}
