var treeMenu = null;

var lvTree = new Class({

	initialize: function(event){
	
		m_selectedDocument = null;
		m_rootUL = null;
		m_rootFolder = null;
		m_loadingAddress = null;
		
		m_subMenuOpen = new Array();
	},
	
	initTree:function(p_cssMenu){
	

		document.getElementById("lvTreeContainer").style.minWidth = '295px';
		
		m_rootUL = document.getElementById("lvTreeContainer").getElementsByTagName("UL")[0];
				
		this.m_rootMenuLI = new Array();
		
		m_rootUL.id = "rootUL";				
		
		// Loop Through All LI Elements On Root UL
		//*******************************************************			
		for(var i = 0; i < m_rootUL.childNodes.length; i++){
			if(m_rootUL.childNodes[i].tagName == 'LI'){
				
				var rootItem = m_rootUL.childNodes[i];
				
				// Check To See If Root Node Has Sub Menu				
				// Had Sub Menu So Add DIV class : Need To Separate Because Sub Menu
				var subMenu = "<ul>" + rootItem.getElementsByTagName('ul')[0].innerHTML + "</ul>";
								
				// Insert HTML
				rootItem.innerHTML = "<div class='" + p_cssMenu.shift() + "'></div>" + subMenu;
				
				// Add Class To Identify root. Class not defined in CSS
				this.addClass(rootItem, "rootLI");

				rootItem.getElementsByTagName('div')[0].onclick = function(p_evt){
					this.openMenu(new Event(p_evt).target.parentNode);
				}.bind(this);
			}
		}

		var menuListLI = m_rootUL.getElementsByTagName('LI');
		var menuListLength = menuListLI.length;
		var menuItem;
		var menuItemLink
		var hasUL;
		var isRootLI;
				
		for(var i = 0; i < menuListLength; i++){

			menuItem = menuListLI[i];
			
			hasUL = (menuItem.getElementsByTagName("UL").length > 0);
			isRootLI = this.hasClass(menuItem, "rootLI");
						
			if(hasUL && !isRootLI){
				// Menu Item Has Sub Menu
				//*******************************************************
				// Add dblClick Event To Open/Close Sub Menu
				var oSelf = this;
				menuItem.childNodes[0].onclick = function(p_evt){
					oSelf.openMenu(new Event(p_evt).target.parentNode);
				}
				
				menuItem.childNodes[0].className = "subMenuClosed";

			}else if(menuItem.className != "rootLI"){			
				var oSelf = this;
				menuItem.childNodes[0].onclick = function(p_evt){
					oSelf.setSelectedDoc(new Event(p_evt).target);				
				}
				
				// Append Document Image Icon Through Class 'documentLink'
				menuItem.childNodes[0].className = "documentLink"
			}
		}

		// Loop Through All UL Elements
		//*******************************************************
		m_subMenu = m_rootUL.getElementsByTagName('ul');
		var m_subMenuLength = m_subMenu.length;
		
		var pOptions = { duration:400, wait:false, onComplete:this.menuToggleDone.bind(this) }
		var subMenu;

		for(var i = 0; i < m_subMenuLength; i++){
		
			subMenu = m_subMenu[i];

			subMenu.id = i;
			
			this.m_rootMenuLI[i] = new Fx.Slide(subMenu, pOptions);
			this.m_rootMenuLI[i].hide();
		
			subMenu.parentNode.style.display = 'none';
			subMenu.removeProperty("$included"); // moo-tools adds property : remove
		}
		
		// Loop Through Links In Menu
		//*******************************************************
		var linkList = m_rootUL.getElementsByTagName('a');
		var linkListLength = linkList.length;
		var linkLI = null; 


		for(var i = 0; i < linkListLength; i++){
			if(linkList[i].href){
				var oSelf = this;
				linkList[i].onclick = function(p_evt){
					oSelf.setLoadingAddress(new Event(p_evt).target);
				}
			}
		}

		
		// Get The Root Folder Name For Help
		//*******************************************************
		m_rootFolder = "help";
	},
	
	setLoadingAddress:function(p_link){
		m_loadingAddress = p_link.href;
		this.setSelectedDoc(p_link);
	},
	
	setSelectedDoc:function(p_link){
	
		if(!this.isNull(m_selectedDocument)){
			this.addClass(m_selectedDocument, "documentLink");
			this.removeClass(m_selectedDocument.parentNode, "docSelected");
		}
		
		m_selectedDocument = p_link;
		
		this.removeClass(m_selectedDocument, "documentLink");
		this.addClass(m_selectedDocument.parentNode, "docSelected");
	},
	
	openMenuItem:function(p_objLocation){
	
		var pagePath = p_objLocation.href;

		// If User Clicked Link From lvTree Ignore		
		if(m_loadingAddress == pagePath) return false;
								
		// Check For Content Sensitive Help : Open Navigation To Current Page
		//*******************************************************
		var urlArray = pagePath.split("/");
		var urlArrayLength = urlArray.length;
		var currentPath = "";
		var startPath = urlArrayLength; // Default To No Path Created To Match
		
		for(var i = 0; i < urlArrayLength; i++){
			if(urlArray[i] == m_rootFolder){
				// Found Root Help Folder Now Start Flagging In Root Project Folder
				// Which is one level deaper than root help folder
				startPath = (i + 1);
			}
			else if(i > startPath){
				currentPath += (i == (urlArrayLength - 1)) ? urlArray[i] : urlArray[i] + "/";
			}
		}
		
		// Loop Through Links In Menu To Find A Match To currentPath
		//*******************************************************
		var linkList = m_rootUL.getElementsByTagName('a');
		var linkListLength = linkList.length;
		var linkLI = null; 
		
		for(var i = 0; i < linkListLength; i++){
			if(linkList[i].href.indexOf(currentPath) != -1){
				// Found Menu Item Which Matches Path
				linkLI = linkList[i].parentNode;
				break;
			}			
		}
				
		if(!this.isNull(linkLI)){

			var rootLI = linkLI.parentNode.parentNode.parentNode;
			var rootLIArray = new Array();

			while(!this.hasClass(rootLI, 'rootLI')){
				// loop through from root for deaper sub menus
				rootLIArray.unshift(rootLI);
				rootLI = rootLI.parentNode.parentNode.parentNode;
			}
			
			this.setSelectedDoc(linkLI.firstChild);
			
			// Must Open rootLI element first
			var isMenuOpen = this.openMenu(rootLI, "open");
			var subMenusClosed = 0;
			
			if(isMenuOpen && rootLIArray.length < 0){
				// Menu Was Already Opened & No Sub Menu Available
				this.centerMenuItem();
			}else{
				// Open all other rootLI element's
				for(var i = 0; i < rootLIArray.length; i++){
					
					//m_lastChainedMenu = rootLIArray[i]; // Flag For Last Sub Menu
					
					// Only Need To Really Flag Last Menu Option Since 
					// Last Menu Is Where Selected Item Is
					isMenuOpen = this.openMenu(rootLIArray[i], "open");
					
					if(!isMenuOpen) subMenusClosed++
				}

				// Make Sure Selected Menu Item Is Viewable In Scroll Pane
				//************************************************************************
				// Time Menu Centering According To Number of Menus Opened
				this.centerMenuItem.delay((Math.max(subMenusClosed, 1) * 500), this);
			}
		}
	},
	
	openMenu:function(p_li, p_forceOpenClose){

		var subMenu = p_li.getElementsByTagName("UL")[0];
		var currentView = "";

		if(subMenu.parentNode.style.display == 'block'){
			// Closing Menu : 
			//*******************************************************			
			if(p_forceOpenClose != "open"){

				// Reset Height Back To Original Fixed : If IE 6
				subMenu.parentNode.style.height = subMenu.parentNode.offsetHeight + "px";
			}			
			currentView = "open";
		}else{
			if(p_forceOpenClose != "close"){
				// Set The DIV tag which is the container of the UL to visible				
				subMenu.parentNode.style.display = "block";
			}
			currentView = "close";
		}
			
		// Make Sure Menu State Is Not Already Set
		if(currentView != p_forceOpenClose){
			this.m_rootMenuLI[subMenu.id.toInt()].toggle();
			return false;
		}else{
			return true;
		}
	},

	menuToggleDone:function(p_event){
	
		// Check The DIV container of the UL to see if open or closed
		var isMenuOpen = (p_event.parentNode.style.height.toInt() > 0)

		// Update The Root LI background accordingly on open/close		
		if(this.hasClass(p_event.parentNode.parentNode, 'rootLI')){
			if(this.hasClass(p_event.parentNode.parentNode, 'opened')){				
				// Remove Class
				this.removeClass(p_event.parentNode.parentNode, 'opened');
				
				// Need To Remove OnState : Get First Class Name To Append 'On'
				var divContainer = p_event.parentNode.parentNode.getElementsByTagName('div')[0];
				var cssBkgClass = divContainer.className.split(' ')[0];
				this.removeClass(divContainer, cssBkgClass + "On");
				
				// Set Display None To Remove Space From IE
				p_event.parentNode.style.display = "none";
			}else{
				// Menu Was Closed : Open Window
				var divContainer = p_event.parentNode.parentNode.getElementsByTagName('div')[0];
				var cssBkgClass = divContainer.className.split(' ');
				this.addClass(p_event.parentNode.parentNode, 'opened');
				this.addClass(divContainer, cssBkgClass + "On");
			}
		}
		else if(isMenuOpen){
			var aElement = p_event.parentNode.parentNode.getElementsByTagName("A")[0];
			this.addClass(aElement, 'subMenuOpened');
		}
		else{
			// Set Parent Container To display:none to indicate submenu closed
			p_event.parentNode.style.display = "none";
			
			var aElement = p_event.parentNode.parentNode.getElementsByTagName("A")[0];
			this.removeClass(aElement, 'subMenuOpened');
		}
		
		if(isMenuOpen){
			p_event.parentNode.id =  p_event.parentNode.style.height.toInt();
			p_event.parentNode.style.height = 'auto'
			this.addClass(p_event.parentNode, 'heightAuto');
			
			//************************************************************************
			// Opened Sub Menu : Get offsetWidth and Set To Container For Horizontal 
			// Scroll Bar in Navigation Frame To Display Appropriately
			
			// Have To Set UL to "inline" to get Propper offsetWidth
			p_event.style.display = "inline"; 
			
			var currentWidth = document.getElementById("lvTreeContainer").style.minWidth.toInt();
			var newWidth = Math.max(currentWidth, (p_event.offsetWidth + p_event.offsetLeft + 25));

			document.getElementById('lvTreeContainer').style.minWidth = newWidth + "px";
			
			p_event.style.display = "block"; // Switch Back To Display Appropriately
			
			m_subMenuOpen[p_event.id] = newWidth; // Save Width
			
		}else{
			m_subMenuOpen[p_event.id] = -1;
				
			var maxWidth = 300;
				
			for (a in m_subMenuOpen){					
				if(m_subMenuOpen[a] > 0) maxWidth = Math.max(maxWidth, m_subMenuOpen[a]);
			}
								
			document.getElementById("lvTreeContainer").style.minWidth = maxWidth + 'px';
		}
	},
	
	centerMenuItem:function(){
		var windowHeight = (window.ie || window.safari ) ? document.documentElement.clientHeight : window.innerHeight;
		var menuHeight = document.getElementById("lvTreeContainer").offsetHeight;
		
		// Menu Was Larger Than Frame Height
		if(menuHeight > windowHeight){
			var yOffSet = (document.all) ? document.body.scrollTop : window.pageYOffset;
			var xOffSet = (document.all) ? document.body.offsetLeft : window.pageXOffset;
			
			var howMuchNotShown = (menuHeight - windowHeight);
			var currentlyShowingInMenuTo = (yOffSet + windowHeight);

			var topOffSet = this.getPosition(m_selectedDocument).y;

			if(topOffSet > windowHeight){
				var frameCenter = Math.round(windowHeight / 2);
				var centered = (topOffSet - frameCenter + 40);
				
				window.scroll(xOffSet, centered);
			}
		}
	},
			
	isNull:function(p_value){
		return(p_value==null || p_value == "null");
	},
	
	isEmptyNull:function(p_value){
		return(p_value==null || p_value == "null" || p_value == "");
	},
	
	removeClass:function(objElement, strClass){

		if ( objElement.className ){ // if there is a class

			// the classes are just a space separated list, so first get the list
			var arrList = objElement.className.split(' ');

			// get uppercase class for comparison purposes
			var strClassUpper = strClass.toUpperCase();

			// find all instances and remove them
			for ( var i = 0; i < arrList.length; i++ ){

				// if class found
				if ( arrList[i].toUpperCase() == strClassUpper ){

					// remove array item
					arrList.splice(i, 1);

					// deincrament loop counter as we have adjusted the array's contents
					i--;
				}
			}

			// assign modified class name attribute
			objElement.className = arrList.join(' ');
		}
	},
	
	hasClass:function(objElement, strClass){

		if ( objElement.className ){
			// the classes are just a space separated list, so first get the list
			var arrList = objElement.className.split(' ');

			// get uppercase class for comparison purposes
			var strClassUpper = strClass.toUpperCase();

			// find all instances and remove them
			for ( var i = 0; i < arrList.length; i++ ){
				if ( arrList[i].toUpperCase() == strClassUpper ){
					return true;
				}
			}
		}
		// No Class Found
		return false;
   },
   
  	getPosition: function(p_element, overflown){
  		overflown = overflown || [];
  		var el = p_element, left = 0, top = 0;
  		
  		do {
  			left += el.offsetLeft || 0;
  			top += el.offsetTop || 0;
  			el = el.offsetParent;
  		} while (el);
  		
  		overflown.each(function(element){
  			left -= element.scrollLeft || 0;
  			top -= element.scrollTop || 0;
  		});
  		
  		return {'x': left, 'y': top};
	},
   
	addClass:function(element, value) {
		
		if(!element.className) {
			element.className = value;
		} else {
			newClassName = element.className;
			newClassName+= " ";
			newClassName+= value;
			element.className = newClassName;
		}
	}
});