/* *******************************************************************
 * Class declarations for the TD Ameritrade side menu navigation
 * Version 0.9.5
**********************************************************************/
var count = 0;
/* ***********************************************************
* Class
* Name: menuClass
* Type: public
* Description: Top-level menu object
* Arguments:
*           divID: string: required: name of container div to which menu will be written.
************************************************************ */

function menuClass(divID){
	this.id = divID;
	this.level = 0;
	this.items = new Array();
	this.activeItem = null;
	this.div = document.getElementById(this.id);
	
	//Defaults object: stores default settings
	this.defaults = new defaultsClass();
	this.defaults.setActiveItemStyles("#000000","#ffffff","none");
	this.defaults.setInactiveItemStyles("","","");
	this.defaults.setSubmenuIndent(9);
};

/* ***********************************************************
* Method
* Name: menuClass.addItem
* Type: public
* Description: Adds navigation items to menuClass object.
* Arguments:
*           text: string: required: text for nav item.
*           uri: string: optional: uri to be moved to onclick (will toggle item's submenu if null).
*           parent: object: optional: the parent nav object (assumes top-level menuClass object if null).
************************************************************ */
menuClass.prototype.addItem = function(text,uri,parent){
	parent = (parent)?parent:this;
	var item = new menuItemClass(text,uri,parent,this);
	parent.items[parent.items.length] = item;
	if(!this.activeItem && !uri) this.activeItem = parent.items[parent.items.length-1];
	return parent.items[parent.items.length-1];
};

/* ***********************************************************
* Method
* Name: menuClass.activateItem
* Type: private
* Description: activates a menuItemClass object
* Arguments:
*           item: object: required: reference to the menuItemClass object.
************************************************************ */
menuClass.prototype.activateItem = function(item){
	if(this.activeItem && this.activeItem!=item)this.deActivateItem(this.activeItem, item);
	this.activeItem = item;
	item.isActive = true;
	item.reset();
	
	if(item.parent.submenu && item.parent.items.length>0) item.parent.submenu.style.display = "block";
	
	item.submenu.style.display = "block";
	//item.div.getElementsByTagName("td").style.textDecoration = "none";
	item.div.style.color = this.defaults.itemStyles["active"].color;
	item.div.style.backgroundColor = this.defaults.itemStyles["active"].backgroundColor;
	item.div.getElementsByTagName("td")[0].style.textDecoration = "none";//this.defaults.itemStyles["active"].textDecoration;
};

/* ***********************************************************
* Method
* Name: menuClass.deActivateItem
* Type: private
* Description: deactivates a menuItemClass object
* Arguments:
*           item: object: required: reference to the menuItemClass object being deactivated.
*           newItem: object: optional: reference to the menuItemClass object that will be activated immediately following.
* Note: Not used in current implementation
************************************************************ */
menuClass.prototype.deActivateItem = function(item, newItem){
	item.submenu.style.display = "none";
	item.isActive = false;
	item.reset();
	item.div.style.color = this.defaults.itemStyles["inactive"].color;
	item.div.style.backgroundColor = this.defaults.itemStyles["inactive"].backgroundColor;
	item.div.getElementsByTagName("td")[0].style.textDecoration = this.defaults.itemStyles["inactive"].textDecoration;
	
	if(item.count == count) item.div.style.borderBottom = "0px none #808080";
	
	if(newItem!=null && (item.parent!=newItem.parent)){
		if(item.parent.submenu && item.parent.items.length>0){
			item.parent.submenu.style.display = "none";
			item.parent.reset();
		}
		item.parent.div.style.color = this.defaults.itemStyles["inactive"].color;
		item.parent.div.style.backgroundColor = this.defaults.itemStyles["inactive"].backgroundColor;
		item.parent.div.style.textDecoration = this.defaults.itemStyles["inactive"].textDecoration;
	}
};
/* ***********************************************************
* Method
* Name: menuClass.toggleItem
* Type: private
* Description: toggles whether a menuItemClass object is active
* Arguments:
*           item: object: required: reference to the menuItemClass object.
************************************************************ */
menuClass.prototype.toggleItem = function(item){
	if(item.submenu.style.display == "block"){
		this.deActivateItem(item);
	}
	else {
		this.activateItem(item);
	}
	if(navigator.appName.indexOf("Microsoft Internet Explorer")>-1)window.event.cancelBubble=true;
};

/* ***********************************************************
* Method
* Name: menuClass.writeMenu
* Type: public
* Description: builds menu hierarchy and writes to menuClass.div. 
************************************************************ */

menuClass.prototype.writeMenu = function(){
	var rNavCorners = document.createElement("div");
	rNavCorners.id = "navCorners";
	rNavCorners.style.padding = "0";
	rNavCorners.style.borderStyle = "none";
	var rtop = document.createElement("div");
	rtop.className = "rtop";
	rtop.style.padding = "0";
	var r1 = document.createElement("div");
	r1.className = "r1";
	var r2 = document.createElement("div");
	r2.className = "r2";
	var r3 = document.createElement("div");
	r3.className = "r3";
	var r4 = document.createElement("div");
	r4.className = "r4";
	var r1Bottom = document.createElement("div");
	r1Bottom.className = "r1";
	var r2Bottom = document.createElement("div");
	r2Bottom.className = "r2";
	var r3Bottom = document.createElement("div");
	r3Bottom.className = "r3";
	var r4Bottom = document.createElement("div");
	r4Bottom.className = "r4";
	rtop.appendChild(r1);
	rtop.appendChild(r2);
	rtop.appendChild(r3);
	rtop.appendChild(r4);
	rNavCorners.appendChild(rtop);
	for(var m=0; m<this.items.length; m++){
		if(m == this.items.length-1) this.items[m].bottom = true;
		this.items[m].reset();
		rNavCorners.appendChild(this.items[m].div);
		this.items[m].writeMenu(rNavCorners);
	}
	var rbottom = document.createElement("div");
	rbottom.className = "rbottom";
	rbottom.style.padding = "0";
	rbottom.style.borderStyle = "none";
	rbottom.appendChild(r4Bottom);
	rbottom.appendChild(r3Bottom);
	rbottom.appendChild(r2Bottom);
	rbottom.appendChild(r1Bottom);
	rNavCorners.appendChild(rbottom);
	this.div.appendChild(rNavCorners);
	//document.write(this.div.outerHTML)
};
/* ***********************************************************
* Class
* Name: defaultClass
* Type: public
* Description: default properties and objects.
************************************************************ */
function defaultsClass(){
	this.indent = 10;
	this.activeItem = null;
	this.itemStyles = new Array();
	this.itemStyles["active"] = new stylesClass();
	this.itemStyles["inactive"] = new stylesClass();
};
/* ***********************************************************
* Method
* Name: menuClass.defaults.setItemStyles
* Type: private
* Description: Sets member values for items within the menuClass.defaults.itemStyles array.
* Arguments:
*           event: string: required: named index within the menuClass.defaults.itemStyles array.
*           color: string: optional: color style.
*           backgroundColor: string: optional: background color style.
*           textDecoration: string: optional: text decoration style.

************************************************************ */

defaultsClass.prototype.setItemStyles = function(event, color, backgroundColor, textDecoration){
	this.itemStyles[event].color = color;
	this.itemStyles[event].backgroundColor = backgroundColor;
	this.itemStyles[event].textDecoration = textDecoration;
	return this.itemStyles[event];
};

/* ***********************************************************
* Method
* Name: menuClass.setActiveItemStyles
* Type: public
* Description: Sets member values for the named index "active" item within the menuClass.defaults.itemStyles array.
* Arguments:
*           color: string: optional: color style.
*           backgroundColor: string: optional: background color style.
*           textDecoration: string: optional: text decoration style.
************************************************************ */

defaultsClass.prototype.setActiveItemStyles = function(color, backgroundColor, textDecoration){
	return this.setItemStyles("active", color, backgroundColor, textDecoration);
};
/* ***********************************************************
* Method
* Name: menuClass.defaults.setInactiveItemStyles
* Type: public
* Description: Sets member values for the named index "inactive" item within the menuClass.defaults.itemStyles array.
* Arguments:
*           color: string: optional: color style.
*           backgroundColor: string: optional: background color style.
*           textDecoration: string: optional: text decoration style.\
************************************************************ */

defaultsClass.prototype.setInactiveItemStyles = function(color, backgroundColor, textDecoration){
	return this.setItemStyles("inactive", color, backgroundColor, textDecoration);
};

/* ***********************************************************
* Method
* Name: menuClass.setSubmenuIndent
* Type: public
* Description: Sets indent member of menuClass.defaults Object.
* Arguments:
*           indent: int: required: pixel value determining how much each successive nav level is indented.
************************************************************ */
defaultsClass.prototype.setSubmenuIndent = function(indent){
	this.indent = indent;
	return this.indent;
};

/* ***********************************************************
* Class
* Name: menuItemClass
* Type: private
* Description: Navigational item within the menuClass.items array. 
* Arguments:
*          text: string: required: text for nav item.
*          uri: string: optional: uri to be moved to onclick (will assume item contains a submenu if null).
*          level: int: required: level of this menuItemClass object in the nav hierarchy.
*          menuObj: object: required: reference to the menuClass object.
************************************************************ */

function menuItemClass(text,uri,parent,menuObj){
	this.isActive = false;
	this.bottom = false;
	this.count = ++count;
	this.level = parent.level+1;
	this.indent = this.level * menuObj.defaults.indent;
	this.parent = parent;
	this.text = text;
	this.div = document.createElement("div");
	this.items = new Array();
	this.submenu = document.createElement("div");
	this.submenu.className = "submenu";
	this.submenu.style.display = "none";
	if(uri){this.div.onclick = function(){location = (uri)?uri:"#";};}
	else{this.div.onclick = bindActivation(this, menuObj);}
};

menuItemClass.prototype.reset = function(){
	var table = document.createElement("table");
	table.border = "0";
	table.cellPadding = "0";
	table.cellSpacing = "0";
	var row = document.createElement("tr");           
	var textCell = document.createElement("td");
	var markerCell = document.createElement("td");
	textCell.innerHTML = this.text;
	textCell.className = "text";
	textCell.style.paddingLeft = this.indent+"px";
	markerCell.innerHTML = "&#9658;";
	markerCell.className = "marker";
	if(this.isActive) markerCell.style.display = "";
	else markerCell.style.display = "none";

	if(!this.isActive){
		this.div.className = "thirdNav_hover_off";
		this.div.onmouseover = function(){this.className = 'thirdNav_hover_on' };
		this.div.onmouseout = function(){this.className = 'thirdNav_hover_off' };
		if(this.count==1){
								this.div.style.borderStyle="none";
								textCell.style.paddingTop="0";
		}
		else if(this.count==count){
								textCell.style.paddingBottom="0";
		}
		else if(this.bottom && this.submenu.style.display!="block"){
								textCell.style.paddingBottom="0";
		}
	}
	else{
		this.div.className = "thirdNav_hover_selected";
		this.div.onmouseover = function(){return false;};
		this.div.onmouseout = function(){return false;};
		if(this.count==1){
			this.div.style.borderStyle="none";
		}
		if(this.bottom){
			this.div.getElementsByTagName("td")[0].style.paddingBottom="0";
		}
		else if(this.count==count){
			this.div.style.borderStyle="none";
		}
	}
	this.textCell = row.appendChild(textCell);
	this.markerCell = row.appendChild(markerCell);
	table.appendChild(row);
	
	var tempContainer = document.createElement("div");
	tempContainer.appendChild(table);
	this.div.innerHTML=tempContainer.innerHTML;
};
/* ***********************************************************
* Method
* Name: menuItemClass.writeMenu
* Type: protected (called only from menuClass.writeMenu())
* Description: writes nav item and submenu hierarchy (iteratively) of menuItemClass object. 
* Arguments:
*           menuDiv: object: required: container div for top-level menuClass object.
************************************************************ */
menuItemClass.prototype.writeMenu = function(menuDiv){
	for(var m=0; m<this.items.length; m++){
		this.submenu.appendChild(this.items[m].div);
		this.items[m].reset();
		this.items[m].parent.reset();
		this.items[m].writeMenu(this.submenu);
	}
	if(this.items.length>0) menuDiv.appendChild(this.submenu);
};
/* ***********************************************************
* Function
* Name: bindActivation
* Type: private
* Description: binds an event handler to menuItemClass.div while keeping the menuItemClass object in scope
* Arguments:
* 	item: object: required: reference to the menuItemClass object.
* 	menuObj: object: required: reference to the menuClass object.
************************************************************ */
function bindActivation(item, menuObj){
	return function(){
		this.activeItem = item;
		menuObj.toggleItem(item);
	}
};
/* ***********************************************************
* Class
* Name: stylesClass
* Type: private
* Description: members map to css style rule definitions
************************************************************ */
function stylesClass(){
	this.color = "";
	this.backgroundColor = "";
	this.textDecoration = "";
};
/* *******************************************************************
 * End class declarations for the TD Ameritrade side menu navigation
**********************************************************************/