// these functions allow a local web page to track internal movements 
// this happens when there is a <a href='' onclick=' code stuff '> structure
// the servermenus detects this during menu build and extends your on click to invoke menufocuslocal
// app never needs to call these functions

// the container is the outer container for the menu as named in the menubuild
// selectedItem is the presently clicked item
// classRoot identifies the styles being used for this menu

// all these methods do is to switch the html CLASS attribute to invoke a different screen experience
// sets everything to be not selected then sets the one named item back to selected (ie the equivalent thereof

var ydrClientMenus = new function () {
	// returns the the common div container of the anchor one level up from the given anchor
	// mouseout enables a mouse hover that shows more menu to stay visible as the mouse makes the transition between one zone and the other
	// this is because even if the sub menu is within the parent, if it is marked absolute it counts as crossing boundaries to get to it
	var mouseOutOuter;  // these will be the same element, but we track them because the event is called from different containers
	var mouseOutInner;
	var mouseOutSeq=1;
	
	this.mouseOutSet = function(element, inner)
	{
		mouseOutSeq++;
		
		if (element)
		{
			if (inner)
				mouseOutInner = element;
			else
				mouseOutOuter = element;	

			element.style.display='block';	
		}
		else
		{
			if (mouseOutOuter && mouseOutInner)
			{
				if (inner)
					mouseOutInner = null
				else
					mouseOutOuter = null
			}
			else 				
				window.setTimeout("ydrClientMenus.mouseOutDo(" + mouseOutSeq + ")",500);
		};		
	};
	this.mouseOutDo = function(seq)
	{		
		if (seq == mouseOutSeq)
		{
			if (mouseOutOuter)
			{
				mouseOutOuter.style.display='none';
				mouseOutOuter=null;
			}
			else if (mouseOutInner)
			{
				mouseOutInner.style.display='none';
				mouseOutInner=null;
			};
		};
	}

	var delim = "|"

	function anchorGroupDiv(imgElement) 
	{ 
		var result = document.getElementById(imgElement.name).parentNode.parentNode;
		//if (result.id.indexOf("ChildDiv") <0)
		//	window.alert("menu error - I did not locate the ChildDiv anchor for "+ imgElement.name);
		return result;		
	};
		
	this.lastMenuSelectedItem = null;  // set my this to the last menu item clicked locallyto client 
		// only impacted by menus that are activated for local menu handling

	this.menuFocusLocalEvent = null;  // can contain an anonymous function to be called at the start of menuFocusLocal
	this.menuFocusLocal = function (container,selectedItem, classRoot, optionalShow)
	{
		// optionalShow can be "show" or "hide" to force the selectedItem (if expandable to be shown or hidden)
		//classRoot if the labelling style of the menu in the build (parameter 2 - style)
		// selectedItem is the id (inclusive of classroot or the actual document element that is the a tag of the currently focussed menu item
			// if string is containerID.id + a.name (where name is the name as in the menu extender declaration
		// container is the id (inclusive of classroot or tha actual document element of the element that contains the selected item)
			// if string then is the same name as the containerID - parameter 4 of the menu build
			
		// as a documentary help it is useful to put a call in or near the onload of the page - the call itself is necessary to make sure the correct
		// local focus is shown
					// eg ydrClientMenus.menuFocusLocal("coordXX", "coordXXcoord", "leftPlain", "show"); 
			// eg ydrClientMenus.menuFocusLocal("adminXX", "adminXXdoc", "leftPlain", "show") 
		
		if (this.menuFocusLocalEvent)
			this.menuFocusLocalEvent(container, selectedItem);
		
		if (typeof container == "string")
			container = document.getElementById(container);
			
		if (typeof selectedItem == "string")
			selectedItem = document.getElementById(selectedItem);
			
		this.lastMenuSelectedItem = selectedItem;	
		ydrClientPane.lastSelectedItem = selectedItem;	
		
		var doneSelectNames = new Object();
		//stop();
		menuFocusLocalRecurse(container, classRoot+"MenuTextActive", doneSelectNames)
		try
		{
			selectedItem.className=classRoot+"MenuTextFocus" ;
		} catch (e) {};
		
		// see if it is an expand/contract node
		try 
		{
			var displayable = selectedItem.getAttribute("ydr:display");
			
			if (displayable != null )
			{
				var display;
				// get the src attribute of the img for the +/- button for expanding the meun
				with (document.getElementById(selectedItem.id+"Display").firstChild)
				{
					if (getAttribute("src").indexOf("plus")>0 || optionalShow == "show")
					{
						setAttribute("src",  getAttribute("src").replace(/plus/, "minus"));
						//innerText = "-";
						display = "inline";
					}	
					else
					{
						setAttribute("src", getAttribute("src").replace(/minus/, "plus"));
						//innerText = "+";
						display = 'none';
					};					
				};
				
				document.getElementById(displayable).style.display = display;
			};
		} catch (e) {};
		
		// if there are selectors on the items then handle the visibility of the selector
		try 
		{	
			select =selectedItem.firstChild.getAttribute("ydr:select");  // should only be optionally present in the img tag
			
			if 	(select != null && doneSelectNames[select] == null)
			{
				doneSelectNames[select]=select;

				name = selectedItem.firstChild.getAttribute("name");
				switch (select)
				{
					case "one" :
						// navigate to approx the parent div that spans all of these like named images
						// then check that these are really our images (no xpath available here sadly)
						
						var items;						
						with (items = document.getElementById(selectedItem.firstChild.name+"ChildDiv").getElementsByTagName("img"))
						{
							for (j=0; j<length; j++)
							{
								if (items[j].getAttribute("name") == name)
									items[j].style.visibility = (item[j].parentNode == selectedItem) ? "inherit" : "hidden";
							};
						};
					
						break;
					
					case "zeroormany" :
						element.style.visibility = (element.style.visibility == "hidden") ? "inherit" : "hidden";
						
					default :
						window.alert("menu XHTML error - invalid ydrselect attribute " + select);
				};
			};
		}
		catch (e) {};
	};

	function menuFocusLocalRecurse(container, classRootActive, doneSelectNames)
	{
		var element;
		var select;
		var name;
		var i, j;
		var items;

		try
		{
			if (container.length != null)
			{
				window.alert("Menu definition error - there is more than one element with the id "+container[0].id);
				return
			}
		} catch (e) {};

		with (items = container.getElementsByTagName("a"))
		{
			for (i=0; i<length; i++)
			{
				element =items[i];
				
				try   // not all childNodes have nodeNames
				{
					if (element.tagName.toLowerCase() == "a")   // note is capital to deal with MS conversions from standard lowercase
					{
						if (element.className != classRootActive)
							element.className= classRootActive;
					};
											
					//menuFocusLocalRecurse(element, classRootActive, doneSelectNames);
				}catch (e) {};;				
			};
		};
	};
	
	this.isDisplayed = function(elementOrId)
	{
		//returns null if the element does not have dynamic display - otherwise returns whether on not the contents are presently visible
		try
		{
			var src;
			if (typeof elementOrId == "string")
				src = document.getElementById(elementOrId).firstChild.firstChild.getAttribute("src")
			else
				src = elementOrId.firstChild.firstChild.getAttribute("src");
			
			if (src == null)
				return null
			else
				return (src.indexOf("minus.gif")>0)
		}
		catch (e) {};
	};
	
	this.isSelected = function(elementOrId)
	{
		// returns null if the element does not have a selector and true or false depending on if it is selected	
		try
		{
			var element;
			if (typeof elementOrId == "string")
				element = document.getElementById(elementOrId)
			else
				element = elementOrId;
				
			return isSelectedRecurse(element);
		}
		catch (e) {return null};
	}
		
	// we cannot predict where the element is because different menu layouts have different nesting of components
	function isSelectedRecurse(element)
	{
		var result;
		var i;
		
		if (element.nodeName.toLowerCase() == "img")
			return element.style.visibility == "visible"
		else
		{
			for (i=0; i<element.childNodes.length; i++)
			{
				result = isSelectedRecurse (element[i]);
				
				if (result != null)
					return result;
			};
		};
		return null;
	}
	
    // toggles the requested switchname and returns true or false dependent on if the setting is set
   // if value is null then toggles otherwise should be true for set and false for not set 
   // this is design to let you leave multiple focus set -
   // if you want just the one set use menuFocusLocal
   
	this.toggle = function(elementOrId, switchName, optionalValue)
	{
		var element;
		if (typeof elementOrId == "string")
			element = document.getElementById(elementOrId)
		else
			element = elementOrId;
						
		switch (switchName)
		{
			case "focus" :  // affects the highlighter style - typically the background colour
				var className = element.className;
				
				if ( (className.indexOf("MenuTextActive")<0 ) || optionalValue == false)
					element.className = className.replace(/MenuTextFocus/, "MenuTextActive")
				else 
					element.className = className.replace(/MenuTextActive/, "MenuTextFocus");
				return null;
				
			case "selected" :
				element.style.visibility = ((element.style.visibility == "hidden") || optionalValue == true)  ? "inherit" : "hidden";
				return element.style.visibility == "inherit";
				
			default :
				window.alert("ydrClientMenus.toggle(): Unknown switchName " + switchName);
				return false;
		}
	}
	
	// if is null returns the value numeric interger newValue sets the value
	//ONLY relevant if this is a bit MASK items selected and the img has a ydrvalue attribute
	// throws error otherwise
	// note only good for lists up to about 45 entries
	this.value = function(element, newValue)
	{
		var i; 
		var reg = new RegExp(element.id);
		var imgs = childNodes(element);
		
		if (newValue == null)
		{
			var result=0;
			
			for (i=0; i<imgs.length;  i++)
				if (imgs[i].style.visibility != "hidden") 
					result = result | parseInt(imgs[i].ydrvalue);
			
			return result;
		}
		else
		{
			for (i=0; i<imgs.length;  i++)
				imgs[i].style.visibility = ((parseInit(ydrBrowser.html.elementValue(imgs[i])) & newValue)>0) ? "inherit" : "hidden";
		};
	}
	
	// null returns the current text being an ID name list of the selected elements within element
	// or if is a string is a ID list of elements to marked as selected (delim delimited)
	// result/format is compatible with ydrGenericScripts.gString.value()
	// element is the container anchorGroupDiv
	this.text = function(topDivElement, element, newValue, invoke)
	{
		var i;
		// the node name for each action is prefixed by the id of the parent group div's a's id - we will need to remove that  prefix
		var reg = new RegExp(topDivElement.id);
		var imgs = childNodes(element);
		
		if (newValue == null)
		{
			var result="";
				
			for (i=0; i<imgs.length;  i++)
				if (imgs[i].style.visibility != "hidden") 
					result += imgs[i].parentNode.id.replace(reg, delim)
			
			result += delim;
			return result;
		}
		else
		{	
			for (i=0; i<imgs.length;  i++)
			{
				imgs[i].style.visibility = (newValue.indexOf(delim+imgs[i].parentNode.id.replace(reg,"")+delim)==0) ? "inherit" : "hidden";
				if ((invoke == "invoke") && imgs[i].style.visibility == "inherit")
				{
					var anchor = imgs[i].parentNode;
					while (anchor != null && anchor.nodeName.toLowerCase() != "a")
					{
						anchor = anchor.parentNode;
					};
					imgs[i].style.visibility = "hidden"; // so the click will make it visibile by its usual process
					anchor.click();
				};	
			};
		};
	}
	
	// produces like a childNode list of those nodes that are the IMG nodes for selectors 
	// that are the first direct menu child of the given node
	function childNodes(element)
	{
		var result = new Array();
		var i;
		var items;
		var index=0;
		// the node name for each action is prefixed by the id of the parent group div's a's id 
		var name= element.getElementsByTagName("a")[0].id;
		
		with (items = element.getElementsByTagName("img"))
		{
			for (i=0; i<length; i++)
				if (items[i].name == name)
					result[index++] = items[i];
		};		
		
		return result;
	}
	
	// if newvalue is null returns an XML element + structure which documents the selected elements of the hierarchy under element
	// if newValue is present is either xml string or xml element node with a previous properties value
	// if invoke == "invoke" then menu options are "clicked" as they are set
	this.properties = function(topDivElement, element, newValue, invoke)
	{
		var namesEncountered = new Object();	
		var menuItemId;
		var i;
		
		if (newValue == null)
		{
			var imgs = element.getElementsByTagName("img");
			var reg = new RegExp(topDivElement.id);
			
			with (ydrClientScripts.XMLdocument())
			{
				with (appendChild(createElement("ydrMenuProperties")))
				{
					setAttribute("id", element.id);
					
					for (i=0; i<imgs.length; i++)
					{
						if (imgs[i].getAttribute("ydr:select") != null)
						{
							menuItemId = imgs[i].getAttribute("name").replace(reg,"");
							
							if (namesEncountered[menuItemId] == null)
							{
								namesEncountered[menuItemId] = menuItemId;
								with (appendChild(ownerDocument.createElement("ydrMenuSelected")))
								{
									setAttribute("name", menuItemId);
									///////////////////  STOP remove anchro group div and do directly
									setAttribute("value", this.text(topDivElement, anchorGroupDiv(imgs[i])));
								};
							};
						};
					};
				};
			
				return documentElement;
			}
		}
		else
		{		
			if (element != null)
				throw new Error("ydrClientMenus.properties[let]: element is expected to be null - is defined in the xml")
			else
			{
				if (typeof newValue == "string")
					newValue = ydrClientScripts.XMLdocument(newValue).documentElement;
				
				var thisElementsDiv;
				for (i=0; i<newValue.childNodes.length; i++)
				{
					with (newValue.childNodes[i])
					{
						
						try 
						{
							thisElementsDiv =document.getElementById(topDivElement.id+getAttribute("name"));
							while (thisElementsDiv && thisElementsDiv.nodeName.toLowerCase() != "div")
							{
								thisElementsDiv = thisElementsDiv.parentNode;
							};
							
							this.text(topDivElement, thisElementsDiv, ydrBrowser.html.elementValue(newValue.childNodes[i]), invoke);
						} 
						catch (e) {};
					};
				};
			};
		};				
	};
	
	this.helpFetchUrl = function (url) 
	// given a URL containing ONLY innerHTML (ie free of body and outer tags)
	// puts the result in the help area - done this way to avoid security restrictions
	{
		//stop(); // if used shift to clientscripts and dont use activex
		try 
		{
			var http=new ActiveXObject("YDRhtmlCleanserDLL.webExtender");
			return http.httpGet(url, document.URL);
		}
		catch (e) 
		{
			// well why ???? - the above code does not get trapped with MS Security notices
			// but doesnt ov=bsiously work until the code is downloaded
			var http=new ActiveXObject("MSXML2.XMLHTTP");
			{
				http.open("GET", url, false);
				http.send();
			
				return http.responseText;  
			};
		};
	};	
	
	this.navigate = function(script, href)
	{
		// used when a client menu is possibly being called from a page that is not loaded with the anticipated script (this can happen when a remote
		// page is loaded as part of a menu that wants to presevre the current menu rather than the target's page's natural menu).  However if the
		// menu also calls a script object that is only available from the main page of this menu then we have to reload the base page first

		try 
		{
			var result;
			eval("result="+script);
			return result;
		} catch (e) 
		{
			window.location.href = href;
			return false;
		};		
	}
}

	

