/*
The Dynamic Navigation Model Interface Component.
Javascript object to access and maintain the Dynamic Navigation XML


The Dynamic Navigation is stored (modeled) in XML in the following format:
---------------------
DynamicNavigation.xml
---------------------
<html>
	<a href="/about/about-admin/admin-gov.cfm">Administration/Governance
			<a href="/about/about-admin/admin-constitution.cfm">Constitution and Canons</a>
			<a href="/about/admin-gov/policy/index.cfm">Policy Manual</a>
	</a>
	<a href="/about/about-admin/center.cfm">Diocesan Center
			<a href="/about/about-admin/center-map.cfm">Area Map</a>
			<a href="/about/about-admin/center-redevelopment.cfm">Redevelopment</a>
	</a>
	<a href="/about/about-admin/map-profile.cfm">Map and Profile</a>
</html>
---------------------

This component will maintain a local XML document object (menuXML) for modification.
The save method will post it back to the server.
(uses ajaxCFC for server transactions)

A menuPath may represent a MenuItem or a Menu/Sub Menu
For example: (zero based counting)
NULL 	- MenuItem: No representation
NULL 	- Menu: Represents the root menu
3 		- MenuItem: The 4th menuItem of the root menu
3 		- Menu: The pop-up of the 4th menuItem of the root menu (may be null)
5,2,3	- MenuItem: 6th of root, 3rd of pop-up, 4th menuItem of the pop-up's pop-up
5,2,3	- Menu: the pop-up of the 6th of root, 3rd of pop-up, 4th menuItem of the pop-up's pop-up

Properties:
XmlDoc menuXML
	- The XML Document representing the Dynamic Menu

Methods:
boolean removeMenuItem(menuPath)
boolean insertMenuItem(menuPath)
boolean moveMenuItemUp(menuPath)
boolean moveMenuItemDown(menuPath)
boolean updateMenuItemName(menuPath, name)
boolean updateMenuItemUrl(menuPath, url)
boolean getMenu(menuPath)
boolean save()
*/

//alert("included dnm");
//dynamicMenu Class
function dynamicMenu(){
	//Constructor
	//alert("constructor");
	DWREngine.setAsync(false);
	try{
		DWREngine._execute(	'/components/DynamicNavigation/DynamicNavigation.cfc',	null,
												'getMenuXml', synchHelp);
	}catch(err){
		alert("Error Creating Dynamic Menu")											
		throw(err);
	}

	//Properties
	var menuXML = syncHelper
	//menuXML.setProperty "SelectionLanguage","XPath";

	//var that = this; //not needed
	//alert(menuXML.xml)

	//Private Methods
	function menuPathToXpath(mp){
		//construct Xpath expression to select a node
		if(mp==null) mp = ""
		mp = mp.toString();
		var arrPath = mp.split(",");
		var xp = "/html";
		if(mp != ""){
			for (i=0;i<arrPath.length;i++){
				pathIndex = 1+ eval(arrPath[i])
				xp=xp+"/a["+pathIndex+"]";
			}
		}
		return xp;
	}

	function buildTree(list,str){
		//alert("# A Tags: "+list.getElementsByTagName('a').length)
		//alert("Menu Item "+list.firstChild.text);
		if (list.getElementsByTagName('a').length > 0){
			var y = list.childNodes;
			for (var i=0;i<y.length;i++){
				if(y[i].nodeType ==1){
					//str = str + y[i].firstChild.text + "\n";
					//str = str + "->"
					str = buildTree(y[i],str)
					//alert(str);
				}
			}
		}else{
			str = list.firstChild.nodeValue + "\n";
			//var fcList = get_firstChild(list);
			//str = fcList.nodeValue + "\n";
		}
		return str;
	};


	//Priverlaged Methods
	this.returnSubTree			= function(menuPath){
			
	}
	
	this.removeMenuItem			=	function (menuPath){
															var success = true
															menuPath = menuPathToXpath(menuPath);
															oNode = menuXML.selectSingleNode(menuPath)
															if (oNode) {
																oNode.parentNode.removeChild(oNode);
															}else{
																success = false;
															}
															return success;
														};

	this.insertMenuItem			=	function (menuPath){
															menuPath = menuPath.toString();
															var success = true;
															//create a new 'a' node to insert
															nNode = menuXML.parentNode.createElement('a');
															//add the href attribute to the new node
															nAttr = menuXML.parentNode.createAttribute("href");
															nAttr.value="NEW URL";
															nNode.setAttributeNode(nAttr);
															//add a text node
															nText = menuXML.parentNode.createTextNode('NEW Menu Item');
															nNode.appendChild(nText);
															//Where do I add the new node? if the menuPath
															//represents where to put the new node then
															//the last number in the MenuPath does not exist.
															//If it is a 0 then it is a submenu (child) insert
															//Otherwise it is regular sibling insert
															//Either way if I always grab the parent node and
															//appendChild it will always work.
															//remove last from the menuPath to reach the parent node
															menuPath = menuPath.match(/.*(?=,\d+$)/);
															//get the Xpath to the node to add a child or sibling
															menuPath = menuPathToXpath(menuPath);
															oNode = menuXML.selectSingleNode(menuPath);
															if(oNode != null){
																//now append a the new node
																oNode.appendChild(nNode);
															}else{success = false;}
															return success;
														};

	this.moveMenuItemUp			=	function (menuPath){
															var success = true;
															menuPath = menuPathToXpath(menuPath);
															oNode = menuXML.selectSingleNode(menuPath);
															if(oNode != null){
																if(oNode.previousSibling.nodeType==1){
																		oNode.parentNode.insertBefore(oNode,oNode.previousSibling);
																}else{success = false;}//already on top
															}else{success = false}//does not exist
															return success;
														};

	this.moveMenuItemDown		=	function (menuPath){
															var success = true;
															menuPath = menuPathToXpath(menuPath);
															oNode = menuXML.selectSingleNode(menuPath);
															if(oNode != null){
																if(oNode.nextSibling!=null){
																		oNode.parentNode.insertBefore(oNode.nextSibling,oNode);
																}else{success = false;}
															}else{success = false}//does not exist
															return success;
														};

	this.updateMenuItemName	=	function (menuPath, name){
															var success = true;
															menuPath = menuPathToXpath(menuPath);
															oNode = menuXML.selectSingleNode(menuPath)
															if(oNode != null){
																//alert(oNode.firstChild.nodeType)
																oNode.firstChild.nodeValue = name;
																//var fcNode = get_firstChild(oNode);
																//fcNode.nodeValue = name;
															}else{success = false;}
															return success;
														};

	this.updateMenuItemUrl	=	function (menuPath, url){
															var success = true;
															menuPath = menuPathToXpath(menuPath);
															oNode = menuXML.selectSingleNode(menuPath)
															if(oNode != null){
																oNode.setAttribute("href",url);
															}else{success = false;}
															return success;
														};

	this.getMenu						=	function (menuPath){
															var retArray = new Array();
															menuPath = menuPathToXpath(menuPath);
															//alert(menuPath);
															oNode = menuXML.selectSingleNode(menuPath);
															if(oNode != null){
																nChildren = oNode.childNodes;
																//0th node (firstChild) is textNode
																var myCount = 0
																for(i=1;i<nChildren.length;i++){
																	if(nChildren[i].nodeType ==1){
																		//alert(nChildren[i].nodeType);
																		//alert('Item Name '+nChildren[i].childNodes[0].nodeValue)
																		//alert('Item URL '+nChildren[i].getAttribute("href"))
																		//alert('Has Submenu '+ (nChildren[i].getElementsByTagName('a').length > 0).toString())
																		retArray[myCount] = new Object();
																		retArray[myCount].ItemName = nChildren[i].childNodes[0].nodeValue;
																		retArray[myCount].ItemUrl = nChildren[i].getAttribute("href");
																		retArray[myCount].hasSubMenu = (nChildren[i].getElementsByTagName('a').length > 0);
																		myCount += 1;
																	}
																}
															}
															return retArray;
														};

	this.save								=	function (){
															DWREngine._execute(	'/components/DynamicNavigation/DynamicNavigation.cfc',	null,
																									'saveMenuXml', menuXML.xml,doNothing);
														};

	this.reset							=	function (){
															DWREngine.setAsync(false);
															DWREngine._execute(	'/components/DynamicNavigation/DynamicNavigation.cfc',	null,
																									'getMenuXml', synchHelp);
															//Properties
															menuXML = syncHelper;
														};

	this.ToString						= function () {
															//Output all titles
															var txt = "";
															//return buildTree(menuXML,txt); //recursive function
															LevelZero = menuXML.selectNodes("/html/a")
															for (LevelZeroIndex=0; LevelZeroIndex<LevelZero.length; LevelZeroIndex++){
																txt=txt+LevelZero[LevelZeroIndex].firstChild.text+" ("+LevelZero[LevelZeroIndex].getAttribute("href")+")<br>"
																LevelOne=menuXML.selectNodes("/html/a["+LevelZeroIndex+"]/a")
																for (LevelOneIndex=0; LevelOneIndex<LevelOne.length; LevelOneIndex++){
																	txt=txt+LevelZero[LevelZeroIndex].firstChild.text+"->"+LevelOne[LevelOneIndex].firstChild.text+" ("+LevelOne[LevelOneIndex].getAttribute("href")+")<br>"
																	LevelTwo=menuXML.selectNodes("/html/a["+LevelZeroIndex+"]/a["+LevelOneIndex+"]/a")
																	for (LevelTwoIndex=0; LevelTwoIndex<LevelTwo.length; LevelTwoIndex++){
																		txt=txt+LevelZero[LevelZeroIndex].firstChild.text+"->"+LevelOne[LevelOneIndex].firstChild.text+"->"+LevelTwo[LevelTwoIndex].firstChild.text+" ("+LevelTwo[LevelTwoIndex].getAttribute("href")+")<br>"
																		LevelThree=menuXML.selectNodes("/html/a["+LevelZeroIndex+"]/a["+LevelOneIndex+"]/a["+LevelTwoIndex+"]/a")
																		for (LevelThreeIndex=0; LevelThreeIndex<LevelThree.length; LevelThreeIndex++){
																			txt=txt+LevelZero[LevelZeroIndex].firstChild.text+"->"+LevelOne[LevelOneIndex].firstChild.text+"->"+LevelTwo[LevelTwoIndex].firstChild.text+"->"+LevelThree[LevelThreeIndex].firstChild.text+" ("+LevelThree[LevelThreeIndex].getAttribute("href")+")<br>"
																			LevelFour=menuXML.selectNodes("/html/a["+LevelZeroIndex+"]/a["+LevelOneIndex+"]/a["+LevelTwoIndex+"]/a["+LevelThreeIndex+"]/a")
																			for (LevelFourIndex=0; LevelFourIndex<LevelFour.length; LevelFourIndex++){
																				txt=txt+LevelZero[LevelZeroIndex].firstChild.text+"->"+LevelOne[LevelOneIndex].firstChild.text+"->"+LevelTwo[LevelTwoIndex].firstChild.text+"->"+LevelThree[LevelThreeIndex].firstChild.text+"->"+LevelFour[LevelFourIndex].firstChild.text+" ("+LevelFour[LevelFourIndex].getAttribute("href")+")<br>"
																			}
																		}
																	}
																}
															}
															return txt;
														}



	//Public Methods
	//none
}

/****************************
	ajaxCFC Synchronus Helpers
*****************************/
var syncHelper = "";
function synchHelp(text){
	// code for IE
	//alert("Return from Server")

	//alert("in synch help");
	if (window.ActiveXObject){
		try{
			var doc=new ActiveXObject("Msxml2.DOMDocument.4.0");
			doc.async="false";
			doc.loadXML(text);
		}catch(err){
			//rethrow error. allow to propogate up
			//alert("here")
			throw(err);
		}
	}else{// code for Mozilla, Firefox, Opera, etc.
		var parser=new DOMParser();
		var doc=parser.parseFromString(text,"text/xml");
	}// documentElement always represents the root node
	syncHelper=doc.documentElement;
	//set the DWREngine back to async default
	DWREngine.setAsync(true);
}

function doNothing(r){}
/****************************/