//////////////////////////////////////////////////////////////
//
// YOU SHOULD NEVER MODIFY THIS FILE!
//
// If you wish to modify a layout, you should place all your code
//   in the function 'initCustomNodes' in the 'nav.js' file.
//
// If you are writing a component, you should override the include
//   'custom_finish_layout_init' with the 'super' tag, and modify
//   the 'navBuilder' object there.
//
// If you wish to make modifications that require changes to this
//   file, you should instead create en entirely new layout based
//   on this one.
//
//////////////////////////////////////////////////////////////

/* Configuration variable: if set to false, trays will be eliminated and the left navigation area
	will become a single, connected tree of collections and items. */
var useTrays = true;

/* Configuration variable: if set to true, the user can have more than one tray open at a time;
	if set to 'false', only one tray can be open at a time (currently-open tray will automatically
	close when a new tray is opened). */
var allowMultipleTrays = false;


/* IMAGE DEFINITION CODE ***************************************************************************/
/***************************************************************************************************/

/* Nav tree image src values. */
var src_I = httpSkinRoot + "tree_I.gif";
var src_Icon_ColClosed = httpSkinRoot + "tree_icon_collection_closed.gif";
var src_Icon_ColOpen = httpSkinRoot + "tree_icon_collection_open.gif";
var src_Icon_Item = httpSkinRoot + "tree_icon_item.gif";
var src_L_ColClosed = httpSkinRoot + "tree_L_collection_closed.gif";
var src_L_ColOpen = httpSkinRoot + "tree_L_collection_open.gif";
var src_T_ColClosed = httpSkinRoot + "tree_T_collection_closed.gif";
var src_T_ColOpen = httpSkinRoot + "tree_T_collection_open.gif";
var src_L_Item = httpSkinRoot + "tree_L_item.gif";
var src_T_Item = httpSkinRoot + "tree_T_item.gif";
var src_tree_space = httpSkinRoot + "tree_space.gif";
var src_space = httpSkinRoot + "space.gif";
var src_Top_ColClosed = httpSkinRoot + "tree_top_collection_closed.gif";
var src_Top_ColOpen = httpSkinRoot + "tree_top_collection_open.gif";
var src_TopOnly_ColClosed = httpSkinRoot + "tree_top_only_collection_closed.gif";
var src_TopOnly_ColOpen = httpSkinRoot + "tree_top_only_collection_open.gif";
var src_Top_Item = httpSkinRoot + "tree_top_item.gif";
var src_TopOnly_Item = httpSkinRoot + "tree_top_only_item.gif";
var trayA_ArrowRight = httpSkinRoot + "trayA_arrow_right.gif";
var trayA_ArrowDown = httpSkinRoot + "trayA_arrow_down.gif";
var trayTabLeftSide_InFront = httpSkinRoot + "TrayTabLeftSide_InFront.gif";
var trayTabLeftSide_InBack = httpSkinRoot + "TrayTabLeftSide_InBack.gif";
var trayTabRightSide_InFront = httpSkinRoot + "TrayTabRightSide_InFront.gif";
var trayTabRightSide_InBack = httpSkinRoot + "TrayTabRightSide_InBack.gif";
var trayA_TrayCorner = httpSkinRoot + "TrayCorner.gif";

/* Nav tree image height and width values. */
var iconWidth_Col = "16";
var iconHeight_Col = "16";
var iconWidth_Item = "16";
var iconHeight_Item = "16";
var connectorWidth = "12";
var connectorHeight = "20";
var arrowRightImageWidth = "11";
var arrowRightImageHeight = "11";
var arrowDownImageWidth = "11";
var arrowDownImageHeight = "11";

/* Header/menu bar image src values */
var logoImage = httpSkinRoot + "HeaderLogo.gif";

var menuBarDividerImage = httpSkinRoot + "menu_bar_divider.gif";
var menuA_arrowDownImage = httpSkinRoot + "menuA_ArrowDown.gif";
var menuA_arrowDownOverImage = httpSkinRoot + "menuA_ArrowDown_over.gif";
var menuA_arrowRightImage = httpSkinRoot + "menuA_ArrowRight.gif";
var menuA_arrowRightOverImage = httpSkinRoot + "menuA_ArrowRight_over.gif";

var blankPageUrl = "about:blank";
if (httpBrowserFullCgiPath.indexOf("https") == 0)
	blankPageUrl = httpBrowserFullCgiPath + "?IdcService=PING_SERVER&IsJava&MergeInclude=std_definitions";

/* placeholder for the search tray urls */
var searchTrayTabArray = [ ["tab_0", httpCgiPath + "?IdcService=GET_DOC_PAGE&Action=GetTemplatePage&Page=TRAY_SEARCH_FORM"],
						   ["tab_1", ""] ];


/* PAGE DISPLAY INITIALIZATION CODE ****************************************************************/
/***************************************************************************************************/

function writeLayoutPageBegin()
{
	var beginHtml = "";
	var coreContentInitDisplay="block";

	/* These variables compensate for the fact that NN/Moz uses the total width or height of a parent as
		the basis for setting relative table dimensions, rather than the available width or height (total
		width or height minus padding). */
	if (its.mozilla || its.nn)
	{
		var mainContentTableHeight = "98%";
		var coreContentTableWidth = "97%";
	}
	else
	{
		var mainContentTableHeight = "100%";
		var coreContentTableWidth = "100%";
	}

	if (!coreContentOnly && !parent.leftNavWindow)
	{
		coreContentInitDisplay="none";

		beginHtml +=
		'<!-- Begin Navigation Shell container -->\n' +
		'<div id="navShell" style="display:none; width:100%; height:100%">\n' +
		'<table style="width:100%; height:100%" border="0" cellspacing="0" cellpadding="0">\n' +
		'<tr>\n' +
		'<td style="height:10px">\n' +
		'	<!-- Header Table -->\n' +
		'	<table id="headerTable" style="width:100%" border="0" cellspacing="0" cellpadding="0">\n' +
		'		<tr>\n' +
		'			<td colspan="4" class="menuA_HeaderLogoCell">\n' +
		'				<table style="width:100%" border="0" cellspacing="0" cellpadding="0">\n' +
		'					<tr>\n' +
		'						<td class="logoImageCell">\n' +
		'							<img src="' + logoImage + '"></td>\n' +
		'						<td id="quickSearchCell" style="white-space:nowrap; text-align:right; vertical-align:middle; padding-left:0pt; padding-right:6pt; padding-top:5px; padding-bottom:7px" nowrap>\n' +
		'							<!-- *** Quick Search container *** --></td>\n' +
		'					</tr>\n' +
		'				</table>\n' +
		'			</td>\n' +
		'		</tr>\n' +
		'		<tr>\n' +
		'			<td colspan="4" class="menuA_HeaderSpacerCell"><img src="' + src_tree_space + '" width="16" height="1"></td>\n' +
		'		</tr>\n' +
		'		<tr>\n' +
		'			<td id="menuA" class="menuA_HeaderMenuCell" width="10">\n' +
		'					<!-- *** Header Menu container *** --></td>\n' +
		'			<td class="menuA_TopMenuBarDividerCell" width="10">\n' +
		'					<img src="' + menuBarDividerImage + '" width="37" height="19"></td>\n' +
		'			<td id="menuBarExtrasCell" class="menuA_TopMenuBarRightCell">\n' +
		'				<!-- *** Menu Bar Extras container *** --></td>\n' +
		'		</tr>\n' +
		'	</table>\n' +
		'</td>\n' +
		'</tr>\n' +
		'<tr>\n' +
		'<td class="frameParentCell" style="vertical-align:top">\n' +
		'	<!-- Content Parent Table -->\n' +
		'	<div id="pageMask" style="position:absolute;background-image:url(' + src_tree_space + ');display:none"></div>\n' +
		'	<table style="width:100%;height:' + mainContentTableHeight + ';background:#FFFFFF" border="0" cellspacing="0" cellpadding="0">\n' +
		'		<tr>\n' +
		'			<td id="leftNavCell" class="leftNavFrameCell" style="width:200px">\n' +
		'				<iframe name="leftNavWindow" id="leftNavWindow" style="width:100%;height:100%" frameborder="0" scrolling="no" src="' + httpLayoutRoot + '/left_nav.htm">\n' +
		'				</iframe>\n' +
		'			</td>\n' +
		'			<td class="frameDividerCell" onmousedown="sizePageColumns(event)" onmouseover="this.style.cursor=\'e-resize\'">\n' +
		'				<div id="dragBar" class="frameDividerCell" style="position:absolute;display:none"></div>\n' +
		'			</td>\n' +
		'			<td id="contentCell" class="contentFrameCell">\n' +
		'				<iframe name="contentFrame" id="contentFrame" class="contentIFrame" style="width:100%;height:100%" frameborder="0" src="'+blankPageUrl+'">\n' +
		'				</iframe>\n' +
		'			</td>\n' +
		'		</tr>\n' +
		'	</table>\n' +
		'	<iframe name="hiddenActionWindow" id="hiddenActionWindow" style="position:absolute;left:-10px;visibility:hidden;width:0px;height:0px" src="'+blankPageUrl+'">\n' +
		'	</iframe>\n' +
		'</td>\n' +
		'</tr>\n' +
		'</table>\n' +
		'</div>\n' +
		'<!-- End Navigation Shell container -->\n';
	} // end if !coreContentOnly

	beginHtml +=
	'<!-- Begin Page Content container to be used for coreContentOnly page load.\n' +
	'(closing tag in std_page_end include) -->\n' +
	'<div id="pageContent" style="display:' + coreContentInitDisplay + ';width:100%;height:100%;vertical-align:top;margin-top:12px;margin-left:10px;margin-right:10px;margin-bottom:10px">\n' +
	'	<!-- Main display area table -->\n' +
	'	<table style="width:' + coreContentTableWidth + ';height:100%" border="0" cellspacing="0" cellpadding="0">\n' +
	'		<tr>\n' +
	'		  <td style="text-align:center;vertical-align:top">\n' +
	'				<center>\n';

	document.write(beginHtml);
	document.close();
}


function writeLayoutPageEnd()
{
	var endHtml =
	'				</center>\n' +
	'			</td>\n' +
	'		</tr>\n' +
	'	</table>\n' +
	'	<!-- End main display area table -->\n' +
	'<!-- this is where layout end should be -->\n' +
	'</div>\n' +
	'<!-- End Page Content container (opening tag is in std_main_page_begin include) -->\n';

	document.write(endHtml);
	document.close();
}


function layoutInitialize()
{
	if (window.name == "hiddenActionWindow")
	{
		// do nothing
		return;
	}
	if (window.name != "contentFrame")
	{
		document.getElementById("navShell").style.display = "block";
		loadPageContents();
	}
	else
	{
		var content = document.getElementById("pageContent");
		if (content != null)
			content.style.display = "block";
	}
}


function loadPageContents()
{
	if (leftNavWindow && contentFrame) //Don't attempt to load until all windows exist.
	{
		if (queryString == null || queryString.length == 0)
			queryString = "IdcService=GET_DOC_PAGE&Action=GetTemplatePage&Page=HOME_PAGE";

		contentFrame.location.replace(httpBrowserFullCgiPath + "?" + queryString + "&coreContentOnly=1");
	}
	else
	{
		setTimeout("loadPageContents()", 100);
	}
}


/* This function is called by the onload event of the nav_display.htm document. */
function generateNavigation()
{
	// init the top menu with just links
	coreNav.menuA = new navBuilder();
	coreNav.menuA.topLevelNodes = new Array (
		"LOGIN", "MICROSOFT_LOGIN", "SELF_REGISTRATION", "HOME", "LOCAL_HOME", "SEARCH",
		"NEW_CHECK_IN", "MY_PROFILE", "HELP");
	coreNav.menuA.makeOpeningHtml = menuA_MenuItem_OpeningHtml;
	coreNav.menuA.makeCoreHtml = menuA_MenuItem_CoreHtml;
	coreNav.menuA.makeClosingHtml = menuA_MenuItem_ClosingHtml;

	// init the top menu with the drop-down lists
	coreNav.trayA = new navBuilder();
	coreNav.trayA.topLevelNodes = new Array (
		"MY_STELLENT", "BROWSE_CONTENT", "SEARCH_TRAY", "PORTLET_1", "CONTENT_MANAGEMENT",
		"ADMINISTRATION" );
	coreNav.trayA.makeOpeningHtml = trayA_Item_OpeningHtml;
	coreNav.trayA.makeCoreHtml = trayA_Item_CoreHtml;
	coreNav.trayA.makeClosingHtml = trayA_Item_ClosingHtml;

	/* This function generates an associative array object containing pointers to
		all the elements in the master XML tree; this enables elements to be randomly
		accessed using the getNodeById() funciton. */
	mapXMLTree(coreNav.xmlRoot, coreNav.xmlNodeMap);
	//DEBUG_displayNodeMap(xmlNodeMap);

	/* initialize the navigation nodes */
	addStandardNavigationNodes(coreNav);
	initCustomNodes(coreNav);
	finishLayoutInit(coreNav);
	//DEBUG_displayNodeMap(coreNav.xmlNodeMap);

//***** MENU BAR CODE *************************************

	/* Run the routine that copies nodes from the master XML document to the dropdown menu XML
		fragment. The coreNav.menuA.topLevelNodes array is passed in as a parameter to provide the
		list of nodes to be included in this display group (coreNav.menuA.topLevelNodes is loaded
		in nav.js). */
	buildTopLevelItems(coreNav.menuA.topLevelNodes, coreNav.menuA.xmlRoot, coreNav);

	/* Create a map of the XML fragment to be used by the getNodeById() funciton. */
	coreNav.menuA.xmlNodeMap = new Object();
	mapXMLTree(coreNav.menuA.xmlRoot, coreNav.menuA.xmlNodeMap);
	//DEBUG_displayNodeMap(coreNav.menuA.xmlNodeMap);

	/* Ensure that the menuA htmlString variable is empty before generating menu code. */
	coreNav.menuA.htmlString = "";

	/* Run the routine that recursively generates HTML code from the dropdown menu XML fragment. */
	coreNav.menuA.buildHtmlStringFromXml(coreNav.menuA.xmlRoot);
	//window.open("javascript:document.write(opener.coreNav.menuA.htmlString)", 'testWin');

	/* Run the routine that inserts the HTML code string into the menuA container. */
	var menuA_Container = document.getElementById("menuA");
	insertHtml(coreNav.menuA.htmlString, menuA_Container);

//***** TREE MENU CODE - START *************************************

	/* Create XML fragment used to build dropdown menu item tree and
		establish a "navtree" root within it. */
	coreNav.trayA.xmlDocument = createXMLFromString('<?xml version="1.0" encoding="iso-8859-1"?><navtree></navtree>');
	coreNav.trayA.xmlRoot = coreNav.trayA.xmlDocument.documentElement;

	/* Run the routine that copies nodes from the master XML document to the tree menu XML
		fragment. The coreNav.trayA.topLevelNodes array is passed in as a parameter to provide the
		list of nodes to be included in this display group (coreNav.trayA.topLevelNodes is loaded
		in nav.js). */
	buildTopLevelItems(coreNav.trayA.topLevelNodes, coreNav.trayA.xmlRoot, coreNav);

	/* Create a map of the XML fragment to be used by the getNodeById() funciton. */
	coreNav.trayA.xmlNodeMap = new Object();
	mapXMLTree(coreNav.trayA.xmlRoot, coreNav.trayA.xmlNodeMap);
	//DEBUG_displayNodeMap(coreNav.trayA.xmlNodeMap);

	/* Ensure that the htmlString variable is empty before generating menu code. */
	coreNav.trayA.htmlString = "";

	/* Run the routine that recursively generates HTML code from the dropdown menu XML fragment. */
	coreNav.trayA.buildHtmlStringFromXml(coreNav.trayA.xmlRoot);
//top.contentFrame.document.write(coreNav.trayA.htmlString);
//top.contentFrame.document.close();

	/* Run the function that inserts the HTML code string into the menuA container.
		Note: this was broken out as a separate function to allow the leftNavWindow document
		time to load. */
	loadNavTree();

	if ((its.mozilla || its.nn) && its.rv < 1.4)
		adjustTrayContainers();	/* Display adjustment for early versions of NN7/Moz1 */


//***** CODE TO POPULATE ADD'L DISPLAY CONTAINERS ****************

	var quickSearchContainer = document.getElementById("quickSearchCell");
	insertHtml(quickSearchFormHtmlCode(coreNav), quickSearchContainer);

	var menuBarExtrasContainer = document.getElementById("menuBarExtrasCell");
	insertHtml(menuBarExtrasHtmlCode(), menuBarExtrasContainer);
}


function loadNavTree()
{
	if (leftNavWindow == null)
		return;
	
	var topMenuContainer = leftNavWindow.document.getElementById("tree_menu");
	if (topMenuContainer)
	{
		insertHtml(coreNav.trayA.htmlString, topMenuContainer);
	}
	else
	{
		setTimeout("loadNavTree()", 100);
	}
}


function buildTopLevelItems(idList, XMLRoot, navBuilder)
{
	var nodeCopy;
	for (var i=0; i<idList.length; i++)
	{
		if (navBuilder.getNodeById(idList[i]))
		{
			nodeCopy = navBuilder.getNodeById(idList[i]).cloneNode(true);
			XMLRoot.appendChild(nodeCopy);
		}
	}
}


/* MENU_A DISPLAY CODE ***************************************************************************/
/***************************************************************************************************/

function menuA_MenuItem_OpeningHtml(parentElement, parentNodeLocation)
{
	var parentId = "menuA_" + parentNodeLocation;

	if (parentElement.tagName == "navtree") // Top-level horizontal menu listing
	{
		this.htmlString +=
			'<table border="0" cellpadding="0" cellspacing="0">\n' +
			'<tr>\n';
	}
	else if (parentElement.parentNode.tagName == "navtree") // First-tier child menus
	{
		this.htmlString +=
			'<div id="' + parentId + '_menu" class="menuA_TopChildCollectionContainer" style="display:none">\n' +
			'	<div class="menuA_TopChildCollectionOutline">\n' +
			'		<table class="menuA_TopChildListTable" border="0" cellpadding="0" cellspacing="0">\n' +
			'			<tr>\n' +
			'				<td>\n' +
			'					<img src="' + src_tree_space + '" width="1" height="2"></td>\n' +
			'			</tr>\n';
	}
	else // Sub-tier child menus.
	{
		this.htmlString +=
			'<div id="' + parentId + '_menu" class="menuA_SubChildCollectionContainer" style="display:none">\n' +
			'	<div class="menuA_SubChildCollectionOutline">\n' +
			'		<table class="menuA_SubChildListTable" border="0" cellpadding="0" cellspacing="0">\n' +
			'			<tr>\n' +
			'				<td>\n' +
			'					<img src="' + src_tree_space + '" width="1" height="2"></td>\n' +
			'			</tr>\n';
	}
}


function menuA_MenuItem_CoreHtml(childElement, nodeLocation)
{
	var labelString;
	var linkTarget = childElement.getAttribute("target");
	var label = childElement.getAttribute("label");
	var url = childElement.getAttribute("url");
	var id = "menuA_" + nodeLocation;

	if (childElement.parentNode.tagName == "navtree") // Top-level menu items
	{
		if (childElement.tagName == "item")
		{
			/* Generate target attribute code for the <a> tag if a target attribute exists in the XML. */
			if (linkTarget == null || linkTarget == "")
				linkTarget = "contentFrame";

			this.htmlString +=
				'<td id="' + id + '" class="menuA_TopLinkItem" nowrap onclick="linkItem_onclick(event, this)" onmouseover="linkItem_mouseover(this)" onmouseout="linkItem_mouseout(this)">\n' +
				'	<a class="menuA_TopLinkText" href="'+url+'" target="'+linkTarget+'">' + label + '</a>\n' +
				'</td>\n';
		}

		else if (childElement.tagName == "collection")
		{
			this.htmlString +=
				'<td id="' + id + '" onclick="topCollectionItem_onclick(event, this, \'vertical\')" onmouseover="topCollectionItem_mouseover(event, this)" onmouseout="topCollectionItem_mouseout(event, this)">\n' +
				'	<table id="' + id + '_itemTable" class="menuA_TopCollectionItemTable" border="0" cellpadding="0" cellspacing="0">\n' +
				'		<tr>\n' +
				'			<td id="' + id + '_arrowCell" class="menuA_TopCollectionItemArrowCell">\n' +
				'				<img id="' + id + '_arrowImg" src="' + menuA_arrowDownImage + '" width="' + arrowDownImageWidth + '" height="' + arrowDownImageHeight + '"></td>\n' +
				'			<td id="' + id + '_labelCell" class="menuA_TopCollectionItem" nowrap>\n' +
				'				' + label + '</td>\n' +
				'		</tr>\n' +
				'	</table>\n';
		}

	}
	else // Child menu items
	{
		if (childElement.tagName == "item")
		{
			/* Generate target attribute code for the <a> tag if a target attribute exists in the XML. */
			if (linkTarget == null || linkTarget == "")
				linkTarget = "contentFrame";

			this.htmlString +=
				'<tr>\n' +
				'	<td id="' + id + '" class="menuA_ChildLinkItem" nowrap onclick="linkItem_onclick(event, this)" onmouseover="linkItem_mouseover(this)" onmouseout="linkItem_mouseout(this)">\n' +
				'	<a class="menuA_ChildLinkText" href="'+url+'" target="'+linkTarget+'">' + label + '</a>\n'+
				'	</td>\n' +
				'</tr>\n';
		}

		else if (childElement.tagName == "collection")
		{
			this.htmlString +=
				'<tr>\n' +
				'	<td id="' + id + '" onclick="childCollectionItem_onclick(event, this)" onmouseover="childCollectionItem_mouseover(event, this)" onmouseout="childCollectionItem_mouseout(event, this)">\n' +
				'		<table id="' + id + '_itemTable" class="menuA_ChildCollectionItemTable" style="width:100%" border="0" cellpadding="0" cellspacing="0">\n' +
				'			<tr>\n' +
				'				<td id="' + id + '_labelCell" class="menuA_ChildCollectionItem" nowrap>\n' +
				'					' + label + '</td>\n' +
				'				<td id="' + id + '_arrowCell" class="menuA_ChildCollectionItemArrowCell">\n' +
				'					<img id="' + id + '_arrowImg" src="' + menuA_arrowRightImage + '" width="' + arrowRightImageWidth + '" height="' + arrowRightImageHeight + '"></td>\n' +
				'			</tr>\n' +
				'		</table>\n';
		}
	}
}


function menuA_MenuItem_ClosingHtml(parentElement)
{
	if (parentElement.tagName == "navtree") // Top-level horizontal menu listing
	{
		this.htmlString +=
			'	</tr>\n' +
			'</table>\n';
	}

	else if (parentElement.parentNode.tagName == "navtree") // First-tier child menus
	{
		this.htmlString +=
			'				<tr>\n' +
			'					<td>\n' +
			'						<img src="' + src_tree_space + '" width="1" height="2"></td>\n' +
			'				</tr>\n' +
			'			</table>\n' +
			'		</div>\n' +
			'	 </div>\n' +
			'</td>\n'; // Closing tag for parent cell
	}

	else // Sub-tier child menus
	{
		this.htmlString +=
			'				<tr>\n' +
			'					<td>\n' +
			'						<img src="' + src_tree_space + '" width="1" height="2"></td>\n' +
			'				</tr>\n' +
			'			</table>\n' +
			'		</div>\n' +
			'	 </div>\n' +
			'	</td>\n' + // Closing tag for parent cell.
			'</tr>\n'; // Closing tag for parent row.
	}
}


/* Standard function for generating html image tag code. */
function imageHtml(src, w, h)
{
	var imgHtml = '<img src="' + src + '" width="' + w + '" height="' + h + '" border="0" align="absmiddle">';
	return imgHtml
}


function quickSearchFormHtmlCode(navBuilder)
{
	var htmlString = "";
	var advSearchUrl = navBuilder.getNodeById("SEARCH").getAttribute("url");

	htmlString +=
		'<form target="contentFrame" style="display:inline; white-space:nowrap" nowrap name=MINISEARCHFORM method="GET" action="' + httpCgiPath + '" onSubmit="setMiniSearchQueryText(this)">\n' +
		'	 <input type=hidden name=IdcService value="GET_SEARCH_RESULTS">\n' +
		'	 <input type=hidden name=SortField value="' + lastSortField + '">\n' +
		'	 <input type=hidden name=SortOrder value="' + lastSortOrder + '">\n' +
		'	 <input type=hidden name=QueryText value="">\n' +
		'	 <input type=hidden name=ftx value="1">\n' +
		'	 <input class=quickSearchClass style="width:120px; height:19px; font-family:verdana; vertical-align:middle" type="text" name=MiniSearchText value="" size="15">\n' +
		'	 <input class="formButton" style="vertical-align:middle" type="submit" name="go" value="'+lc('wwQuickSearch')+'">&nbsp;&nbsp;\n' +
		'</form>\n';

	return htmlString;
}


function menuBarExtrasHtmlCode()
{
	var htmlString = "";

	htmlString +=
		'							<table align="right" border="0" cellpadding="0" cellspacing="0">\n' +
		'								<tr>\n';

	if (its.ie) // The addBookmark function only works with IE.
	{
		htmlString +=
			'									<td class="menuA_TopMenuBarExtraLink" onclick="addBookmark()" onmouseover="this.className=\'menuA_TopMenuBarExtraLink_over\'" onmouseout="this.className=\'menuA_TopMenuBarExtraLink\'">\n' +
			'										'+lc('wwAddToFavorites')+'</td>\n';
	}

	htmlString +=
		'									<td class="menuA_TopMenuBarExtraLink" onclick="window.contentFrame.location.reload(true)" onmouseover="this.className=\'menuA_TopMenuBarExtraLink_over\'" onmouseout="this.className=\'menuA_TopMenuBarExtraLink\'">\n' +
		'										'+lc('wwRefresh')+'</td>\n';
		'								</tr>\n' +
		'							</table>\n';

	return htmlString;
}


/* This function allows a bookmark to be added relative to the content document in a frameset.*/
function addBookmark()
{
	if (its.ie) // Make sure routine is only run by IE (not supported by other browsers).
	{
		contentUrl = String(window.contentFrame.location); // Had to be converted to String ob before applying RegExp replace function.
		contentUrl = contentUrl.replace(/&coreContentOnly=1/, ""); // Remove coreContentOnly parameter to ensure navshell loads when page is recalled.
		window.external.AddFavorite(contentUrl, window.contentFrame.document.title); // AddFavorite() is an IE-only method.
	}
}


/* Set global click event handler that's used to close menus when a user clicks anywhere
	outside of the menu objects. */
if (window.name == "contentFrame")
{
	var resetFunction = "parent.resetMenus";
}
else
{
	var resetFunction = "resetMenus";
}

document.onclick = eval(resetFunction);



/* LEFT NAV TREE DISPLAY CODE **********************************************************************/
/***************************************************************************************************/

/* This function is passed as a parameter to the buildHtmlStringFromXml method. It generates the opening html
	code for a single display collection/folder in the nav tree. */
function trayA_Item_OpeningHtml(parentElement, nodeLocation)
{
	if (parentElement.tagName == "navtree") // ROOT-LEVEL (Tray table)
	{
		if (useTrays)
			this.htmlString += '<table id="trayTable" class="trayA_topLevelTable" border="0" cellspacing="0" cellpadding="0">\n';
		else
		{
			this.htmlString +=
				'<table id="trayTable" class="trayA_topLevelTable" border="0" cellspacing="0" cellpadding="0">\n' +
				'	<tr>\n' +
				'		<td style="vertical-align:top;height:100%;width:100%">\n' +
				'			<div id="trayTableMainDiv" style="width:100%;height:100%;padding-left:5px;overflow:auto">\n';
		}
	}

	else if (parentElement.parentNode.tagName == "navtree" && useTrays == true) // TRAY-LEVEL
	{
		if (leftNavWindow != null && leftNavWindow.document.getElementById(parentElement.getAttribute("id")) == null)
		{
			if (parentElement.getAttribute("tray_doc") != null && parentElement.getAttribute("tray_doc") != "")
			/* If the node contains a tray_doc attribute, an IFrame is loaded into the container rather
				than menu items; the tray_doc attribute contains the URL that's used to load the IFrame. */
			{
				this.htmlString +=
				'  <tr>\n' +
				'    <td id="trayA_' + nodeLocation + '_cell" colspan="2" class="trayA_cell_closed">\n' +
				' 		 <table style="width:100%;height:100%;overflow:hidden;table-layout:fixed" border="0" cellpadding="0" cellspacing="0"><tr><td style="white-space:nowrap" nowrap>\n' +
				'				 <div id="trayA_' + nodeLocation + '_scrollBox" class="trayA_scrollBox" style="width:100%;height:1px;display:none;overflow:hidden">\n' +
				'					 <div id="' + parentElement.getAttribute("id") + '" class="trayA_content">\n' +
				'						 <iframe name="' + parentElement.getAttribute("id") + '_iframe" id="' + parentElement.getAttribute("id") + '_iframe" style="width:100%;height:100%" frameborder="0" scrolling="no" src="'+blankPageUrl+'">\n' +
				'						 </iframe>\n';
			}
			else
			/* This is a normal tray that just contains a node listing. */
			{
				this.htmlString +=
				'  <tr>\n' +
				'    <td id="trayA_' + nodeLocation + '_cell" colspan="2" class="trayA_cell_closed">\n' +
				' 		 <table style="width:100%;height:100%;overflow:hidden;table-layout:fixed" border="0" cellpadding="0" cellspacing="0"><tr><td style="white-space:nowrap" nowrap>\n' +
				'				 <div id="trayA_' + nodeLocation + '_scrollBox" class="trayA_scrollBox" style="width:100%;height:1px;display:none;overflow:auto">\n' +
				'					 <div id="' + parentElement.getAttribute("id") + '" class="trayA_content">\n';
			}
		}
	}

	else // SUB-TRAY-LEVELS
	{
		if (leftNavWindow != null && leftNavWindow.document.getElementById(parentElement.getAttribute("id")) == null)
		/* Only create the parent container if it doesn't already exist. */
		{
			this.htmlString += '<div id="' + parentElement.getAttribute("id") + '" style="display:none">\n';
		}
	}
}


/* This function is passed as a parameter to the buildHtmlStringFromXml method. It generates the core html
	code for a single display item in the nav tree. */
function trayA_Item_CoreHtml(childElement, nodeLocation)
{
	if (childElement.parentNode != null &&
		childElement.parentNode.tagName == "navtree" && useTrays == true) ///// ** TRAY-LEVEL
	{
		this.htmlString +=
			'  <tr>\n' +
			'    <td id="trayA_' + nodeLocation + '_header" class="trayA_header" nowrap>\n' +
			' 		 <table style="width:100%;overflow:hidden;table-layout:fixed" border="0" cellpadding="0" cellspacing="0"><tr><td style="white-space:nowrap" nowrap>\n' +
			'				 <a class="trayA_headerLink_closed" href="javascript:parent.toggleTrayDisplay(\'' + childElement.getAttribute("id") + '\')" target="_self">\n' +
			'					 <img src="' + trayA_ArrowRight + '" width="9" height="9" border="0"><span style="padding-left:3px">' + childElement.getAttribute("label") + '</span></a></td></tr></table></td>\n' +
			'    <td style="width:30px"><img src="' + trayA_TrayCorner + '" width="30" height="18" border="0"></td>\n' +
			'  </tr>\n';
	}
	else ///// ** SUB-TRAY-LEVELS
	{
		/* Declare string variables for markup. */
		var iconImageHtml = "";
		var connectorImageHtml = "";
		var offsetImagesHtml = "";
		var imageCellWidth = 0;
		var labelTextHtml = "";
		var id = nodeLocation;

		// **** COLLECTION ****
		if (childElement.tagName == "collection")
		{
			/* Define icon image and image attributes for current element. */
			if (childElement.getAttribute("icon"))
			{
				var iconSrc = httpSkinRoot + childElement.getAttribute("icon");
			}
			else
			{
				var iconSrc = src_Icon_ColClosed;
			}
			var iconWidth = iconWidth_Col;
			var iconHeight = iconHeight_Col;

			/* This block tests any top-level collections to see if they are the first collection in the listing
				(e.g. they have no previous sibling in their display group). This is used below to define
				the unique connector images used for the top collection. */
			var isFirstMenuItem = false;
			if (useTrays)
			{
				if (childElement.parentNode.parentNode.tagName == "navtree" && previousSiblingElement(childElement) == null)
					isFirstMenuItem = true;
			}
			else
			{
				if (childElement.parentNode.tagName == "navtree" && previousSiblingElement(childElement) == null)
					isFirstMenuItem = true;
			}

			/* Define connector image for the current collection. */
			if (isFirstMenuItem)
			{
				if (nextSiblingElement(childElement) == null)
				{
					var connectorSrc = src_TopOnly_ColClosed;
				}
				else
				{
					var connectorSrc = src_Top_ColClosed;
				}
			}
			else if (nextSiblingElement(childElement) != null)
			{
				var connectorSrc = src_T_ColClosed;
			}
			else
			{
				var connectorSrc = src_L_ColClosed;
			}
		}

		// **** ITEM ****
		else
		{
			/* Define icon image and image attributes for current element. */
			if (childElement.getAttribute("icon"))
			{
				var iconSrc = httpSkinRoot + childElement.getAttribute("icon");
			}
			else
			{
				var iconSrc = src_Icon_Item;
			}
			var iconWidth = iconWidth_Item;
			var iconHeight = iconHeight_Item;

			/* This block tests any top-level items to see if they are the first item in the listing
				(e.g. they have no previous sibling in their display group). This is used below to define
				the unique connector images used for the top item. */
			var isFirstMenuItem = false;
			if (useTrays)
			{
				if (childElement.parentNode != null && childElement.parentNode.parentNode != null &&
					childElement.parentNode.parentNode.tagName == "navtree" && previousSiblingElement(childElement) == null)
				{
					isFirstMenuItem = true;
				}
			}
			else
			{
				if (childElement.parentNode != null &&
					childElement.parentNode.tagName == "navtree" && previousSiblingElement(childElement) == null)
				{
					isFirstMenuItem = true;
				}
			}

			/* Define connector image for the current item. */
			if (isFirstMenuItem)
			{
				if (nextSiblingElement(childElement) == null)
				{
					var connectorSrc = src_TopOnly_Item;
				}
				else
				{
					var connectorSrc = src_Top_Item;
				}
			}
			else if (nextSiblingElement(childElement) != null)
			{
				var connectorSrc = src_T_Item;
			}
			else
			{
				var connectorSrc = src_L_Item;
			}
		}

		/* Generate the html code for the icon and node-connection point graphics using image
			property values determined in the block above. */
		iconImageHtml = imageHtml(iconSrc, iconWidth, iconHeight);
		connectorImageHtml = imageHtml(connectorSrc, connectorWidth, connectorHeight);

		/* Loop upward through the ancestors of the current element to generate html code for
			the offset image graphics (either dotted lines or spaces in this implementation).
			Also keep a count of the number of levels to use in calculating the width of the table
			cell that will contain the images. */
		var parent = childElement.parentNode;
		var offsetCount = 0;
		var referenceParent;
		while (parent.tagName != "navtree")
		{
			if (useTrays)
				referenceParent = parent.parentNode;
			else
				referenceParent = parent;

			if (nextSiblingElement(parent) && referenceParent.tagName != "navtree")
			{
				offsetImagesHtml = imageHtml(src_I, connectorWidth, connectorHeight) + offsetImagesHtml;
			}
			else
			{
				offsetImagesHtml = imageHtml(src_tree_space, connectorWidth, connectorHeight) + offsetImagesHtml;
			}
			offsetCount++;
			parent = parent.parentNode;
		}

		/* Calculate the width of the table cell containing the images. First the total width of all offset
			images is calculated, then the widths of the node point connector and the icon are added. */
		imageCellWidth = (offsetCount * connectorWidth) + parseInt(connectorWidth) + parseInt(iconWidth);

		/* Generate target attribute code for the <a> tag (if a target attribute exists in the XML). */
		if (childElement.getAttribute("target") != null && childElement.getAttribute("target") != "")
		{
			var linkTarget = ' target="' + childElement.getAttribute("target") + '"';
		}
		else
		{
			var linkTarget = "";
		}

		/* Generate html code for the node point connector and icon graphics and associated links.
			In this implementation, the icon for an "item" will be a link to the url from the
			item's xml "url" attribute; a "collection" will have both the node point connector and icon contained in a common
			<span> tag with an onclick event that calls the function to open the collection folder. */
		if (childElement.tagName == "item")
		{
			var nodeImagesHtml = connectorImageHtml + '<a href="' + childElement.getAttribute("url") + '"' + linkTarget + '>' + iconImageHtml + '</a>';
		}

		else
		{
			var nodeImagesHtml = '<a id="' + childElement.getAttribute("id") + '_link" onClick="parent.toggleDisplay(\'' + childElement.getAttribute("id") + '\')">' + connectorImageHtml + iconImageHtml + '</a>';
		}

		/* Generate the html code for the label text. A link will be included if the xml data contains
			a value for the "url" atrribute (either "items" or "collections" may contain a link). */
		if (childElement.getAttribute("url") != null && childElement.getAttribute("url") != "")
		{
			/* This branch had to be added because the addition of the mini search page in the tray in the
				left menu area seemed to confuse the link targeting mechanisms. */
			if (linkTarget == "" || linkTarget == "contentFrame")
			{
				labelTextHtml = '<a href="' + childElement.getAttribute("url") + '" class="navItemLink"' + linkTarget + '>' + childElement.getAttribute("label") + '</a>';
			}
			else
			{
				labelTextHtml = '<a href="' + childElement.getAttribute("url") + '" class="navItemLink"' + linkTarget + '>' + childElement.getAttribute("label") + '</a>';
			}
		}
		else
		{
			labelTextHtml = childElement.getAttribute("label");
		}

		/* Append the final html table code for the item to the global html string variable. */
		this.htmlString +=
			'<table id="' + id + '" class="navItemTable" border="0" cellspacing="0" cellpadding="0">\n' +
			'	<tr>\n' +
			'		<td style="width:' + imageCellWidth.toString() + 'px; text-align:left; white-space:nowrap" nowrap>' + offsetImagesHtml + nodeImagesHtml + '</td>\n' +
			'		<td class="navItemText" nowrap>' + labelTextHtml + '</td>\n' +
			'	</tr>\n' +
			'</table>\n';
	}
}


/* This function is passed as a parameter to the buildHtmlStringFromXml method. It generates the closing html
	code for a single display collection/folder in the nav tree. */
function trayA_Item_ClosingHtml(parentElement)
{
	/* Generate closing <div> tag or tray table closing code for current element
		(only if parent container didn't exist initially). */
	if (leftNavWindow != null && leftNavWindow.document.getElementById(parentElement.getAttribute("id")) == null)
	{
		if (parentElement.tagName == "navtree") // ROOT-LEVEL (Left nav table)
		{
			if (useTrays)
			{
				this.htmlString +=
					'  <tr>\n' +
					'    <td id="trayA_buffer" colspan="2" class="trayA_buffer" style="height:auto">\n' +
					'			<img src="' + src_space + '" width="1" height="1"></td>\n' +
					'  </tr>\n' +
					'</table>\n';
			}
			else
			{
				this.htmlString +=
					'  		</div>\n' +
					'  	</td>\n' +
					'  </tr>\n' +
					'</table>\n';
			}
		}
		else if (parentElement.parentNode.tagName == "navtree" && useTrays == true) // TRAY-LEVEL
		{
			this.htmlString +=
				'							</div>\n' +
				'						</div>\n' +
				'					</td>\n' +
				'				</tr>\n' +
				'			</table>\n' +
				'		</td>\n' +
				'  </tr>\n';
		}
		else
		{
			this.htmlString += '</div>\n';
		}
	}
}


/* Standard function for generating html image tag code. */
function imageHtml(src, w, h)
{
	var imgHtml = '<img src="' + src + '" width="' + w + '" height="' + h + '" border="0" align="absmiddle">';
	return imgHtml
}


/* LEFT NAV TREE DHTML *****************************************************************************/
/***************************************************************************************************/

/* Initialize count variable. */
var openTrayCount = 0;
var openTrayId = "";

function toggleTrayDisplay(nodeId)
{
	var trayContainer = leftNavWindow.document.getElementById(nodeId);
	var trayBuffer = leftNavWindow.document.getElementById("trayA_buffer");
	var parentOb = trayContainer;
	var trayScrollBox, trayCell;

	while (parentOb.id != "trayTable")
	{
		if (parentOb.id.indexOf("scrollBox") != -1) { trayScrollBox = parentOb; }
		else if (parentOb.id.indexOf("cell") != -1) { trayCell = parentOb; }
		parentOb = parentOb.parentNode;
	}

	var trayId = trayScrollBox.id.split("_")[1];
	var trayHeader = leftNavWindow.document.getElementById("trayA_" + trayId + "_header");
	var trayHeaderLink = trayHeader.getElementsByTagName("A")[0];
	var trayArrowImage = trayHeader.getElementsByTagName("IMG")[0];

	if (trayCell.className == "trayA_cell_closed")
	{
		trayScrollBox.style.display = "block";
		trayScrollBox.style.height = "100%";
		trayCell.className = "trayA_cell_open";
		trayHeaderLink.className = "trayA_headerLink_open";
		trayArrowImage.src = trayA_ArrowDown;
		openTrayCount++;

		if (allowMultipleTrays == false)
		{
			if (openTrayId != "")
			{
				toggleTrayDisplay(openTrayId);
			}
			openTrayId = nodeId;
		}

		/* Declare variables used to reference XML node in order to get attribute values. */
		var xmlNode = coreNav.trayA.getNodeById(nodeId);

		/* Declare variable used to determine value (and/or existence) of collection service. In this
			implementation, collection service is used to dynamically generate and insert child nodes
			for collections in the Library (index) sub-tree (for nodes that don't have a collection
			service, their child nodes were generated at the time the page is initially loaded). */
		var collectionService = xmlNode.getAttribute("collection_service");

		/* Declare variable to determine value (and/or existence) of tray_doc attribute. In cases where
			a tray contains an IFrame used to load a separate document (such as the Search tray), the
			tray_doc attribute provides the URL of the document to be loaded when the tray is opened. */
		var trayDoc = xmlNode.getAttribute("tray_doc");

		if (collectionService && trayContainer.getElementsByTagName("table").length == 0)
		/* Run the collection service routines only if the child nodes haven't been loaded already
			(e.g. the <div> container doesn't already contain any <table> code). */
		{
			if (collectionService.indexOf("javascript:") == 0)
			/* This conditional was added to allow use with Javascript-based collection services.
				This is included to enable a broader range of customization; it isn't currently used
				in this implementation. */
			{
				jsLoadFunction = collectionService.split(":")[1];
				eval(jsLoadFunction);
			}
			else
			{
				/* Load hidden frame with lm_dir_page.htm template. The onload event of this page calls the
				parseChildNodesXml() function. This can potentially be used with other services for different
				customizations.*/
				hiddenActionWindow.location.replace(collectionService);
			}
			/* Note: the code that displays the container is located in the collection service-related functions.*/
		}

		else if (xmlNode.getAttribute("tray_doc"))
		/* If the current node has a tray_doc attribute, load that URL into the corresponding iframe for that
			node (if the frame hasn't been loaded already).  */
		{
			var trayIframe = leftNavWindow.document.getElementById(trayContainer.id + "_iframe");
			if (trayIframe.src == null || trayIframe.src == "" || trayIframe.src == blankPageUrl)
			{
				trayIframe.src = xmlNode.getAttribute("tray_doc");
			}
		}
	}

	else
	{
		trayScrollBox.style.display = "none";
		trayScrollBox.style.height = "1px";
		trayCell.className = "trayA_cell_closed";
		trayHeaderLink.className = "trayA_headerLink_closed";
		trayArrowImage.src = trayA_ArrowRight;
		openTrayCount--;

		if (allowMultipleTrays == false)
		{
			openTrayId = "";
		}
	}

	if (openTrayCount == 0) trayBuffer.style.height = "auto";
	else trayBuffer.style.height = "1px";

	if ((its.mozilla || its.nn) && its.rv < 1.4)
	/* Display adjustment for early versions of NN7/Moz1*/
	{
		dynamicTrayAdjustInit();
	}
}


/* DHTML function that hides or displays the children of a collection on the tree. */
function toggleDisplay(nodeId)
{
	/* Declare variables containing the two images that need to be swapped
		ASSUMPTION: The first (and usually only) two children of the linkObject container
		will be the tree connector and the collection/folder icon respectively. */
	var linkObject = leftNavWindow.document.getElementById(nodeId + "_link");
	var treeConnectorImage = linkObject.childNodes[0];
	var treeIconImage = linkObject.childNodes[1];
	var divContainer = leftNavWindow.document.getElementById(nodeId);

	/* Toggle the display status of the associated DIV container accordingly. */
	if (treeConnectorImage.src.indexOf("closed.gif") > -1)
	{
		/* Declare variables used to determine value (and/or existence) of collection service. In this
			implementation, collection service is used to dynamically generate and insert child nodes
			for collections in the Library (index) sub-tree (for nodes that don't have a collection
			service, their child nodes were generated at the time the page is initially loaded). */
		var xmlNode = coreNav.trayA.getNodeById(nodeId);
		var collectionService = xmlNode.getAttribute("collection_service");

		if (collectionService && divContainer.getElementsByTagName("table").length == 0)
		/* Run the collection service routines only if the child nodes haven't been loaded already
			(e.g. the <div> container doesn't already contain any <table> code). */
		{
			if (collectionService.indexOf("javascript:") == 0)
			/* This conditional was added to allow use with Javascript-based collection services.
				This is included to enable a broaded range of customization; it isn't currently used
				in the standard implementation. */
			{
				jsLoadFunction = collectionService.split(":")[1];
				eval(jsLoadFunction);
			}
			else
			{
				/* Load hidden frame with lm_dir_page.htm template. The onload event of this page calls the
				parseChildNodesXml() function. This can potentially be used with other services for different
				customizations.*/
				hiddenActionWindow.location.replace(collectionService);
			}
			/* Note: the code that displays the container is located in the collection service-related functions.*/
		}
		else
		{
			if (divContainer.hasChildNodes())
			{
				divContainer.style.display = "block"; // Display existing child nodes.
			}
		}
		/* Swap the tree graphics to indicate change of display state.
			ASSUMPTION: The file names of the connector and icon graphics will end with either
			"open" or "closed".*/
		treeConnectorImage.src = treeConnectorImage.src.replace(/closed\.gif/, "open.gif");
		treeIconImage.src = treeIconImage.src.replace(/closed\.gif/, "open.gif");
	}
	else
	{
		// Hide child nodes.
		divContainer.style.display = "none";
		/* Swap the tree graphics to indicate change of display state.
			ASSUMPTION: The file names of the connector and icon graphics will end with either
			"open" or "closed".*/
		treeConnectorImage.src = treeConnectorImage.src.replace(/open\.gif/, "closed.gif");
		treeIconImage.src = treeIconImage.src.replace(/open\.gif/, "closed.gif");
	}
}


/* Set display adjustment event handler for early versions of NN7/Moz1.*/
if ((its.mozilla || its.nn) && its.rv < 1.4)
{
	window.onresize = parent.dynamicTrayAdjustInit;
}


/* Another Netscape display fix function. This one is used with the onresize event; for
	some reason the div containers must first be collapsed down to a small size (1px) before
	firing the adjustTrayContainers() function to force them to match the size of the parent
	cell. */
function dynamicTrayAdjustInit()
{
	var i = 0;
	var trayCell = leftNavWindow.document.getElementById("trayA_" + i + "_cell");
	var trayScrollBox = leftNavWindow.document.getElementById("trayA_" + i + "_scrollBox");

	while (trayCell != null)
	{
		if (trayCell.className.indexOf("_open") != -1)
		{
			trayScrollBox.style.height = "1px";
		}
		i++;
		trayCell = leftNavWindow.document.getElementById("trayA_" + i + "_cell");
		trayScrollBox = leftNavWindow.document.getElementById("trayA_" + i + "_scrollBox");
	}
	adjustTrayContainers();
}


/* This function fixes a Netscape display problem. It goes through the tray container
	div tags and forces their height to match that of the parent cell (for some reason
	the 100% height attribute doesn't work when the parent cell is set to "auto".)*/
function adjustTrayContainers()
{
	/* This sizes the tray table to match the height of the left nav cell */
	if (document.getElementById("leftNavCell") != null && leftNavWindow.document.getElementById("trayTable") != null)
	{
		var leftNavCell = document.getElementById("leftNavCell");
		var trayTable = leftNavWindow.document.getElementById("trayTable");
		trayTable.style.height = leftNavCell.offsetHeight;
	}

	var i = 0;
	var trayCell = leftNavWindow.document.getElementById("trayA_" + i + "_cell");
	var trayScrollBox = leftNavWindow.document.getElementById("trayA_" + i + "_scrollBox");
	/* These loops will probably have to be adjusted to walk through an XML fragment
		and find containers based upon ID values.*/
	while (trayCell != null)
	{
		if (trayCell.className.indexOf("_open") != -1)
		{
			trayScrollBox.style.height = trayScrollBox.offsetParent.offsetHeight;
			trayScrollBox.style.display = "block";
		}
		i++;
		trayCell = leftNavWindow.document.getElementById("trayA_" + i + "_cell");
		trayScrollBox = leftNavWindow.document.getElementById("trayA_" + i + "_scrollBox");
	}
}


/* DYNAMIC NODE-INSERTION CODE *********************************************************************/
/***************************************************************************************************/


/**** BEGIN - COMMON CODE */
/* insertType parameter must be one of three values: "replace" or "addToTop" or "addToBottom" */
function insertParsedChildNodes(childList, destinationXmlParent, insertType)
{
	if (insertType == "replace")
	/* Clear existing children from parent node (otherwise, new children will be added to existing). */
	{
		var destinationChildList = destinationXmlParent.childNodes;
		for (var i=destinationChildList.length-1; i>=0; i--)
		{
			destinationXmlParent.removeChild(destinationChildList[i]);
		}
	}

	if (insertType == "replace" || insertType == "addToBottom")
	{
		for (var j=0; j<childList.length; j++)
		/* Loop through child list and insert nodes into parent XML collection node. Since this
			is done using the appendChild() method, the new nodes are added to the bottom, after any
			existing child nodes in the list. */
		{
			if (childList[j].nodeType == 1)
			{
				var childNodeClone = childList[j].cloneNode(true);
				destinationXmlParent.appendChild(childNodeClone);
			}
		}
	}
	else if (insertType == "addToTop")
	{
		var destinationChildList = destinationXmlParent.childNodes;
		var originalTopNode = destinationChildList[0];

		for (var j=0; j<childList.length; j++)
		/* Loop through child list and insert nodes into parent XML collection node. Each node is
			inserted before the top-most existing node. */
		{
			if (childList[j].nodeType == 1)
			{
				var childNodeClone = childList[j].cloneNode(true);
				destinationXmlParent.insertBefore(childNodeClone, originalTopNode);
			}
		}
	}

	/* Remap the treeMenu fragment after the new nodes have been inserted. */
	coreNav.trayA.xmlNodeMap = new Object();
	mapXMLTree(coreNav.trayA.xmlRoot, coreNav.trayA.xmlNodeMap);
	//DEBUG_displayNodeMap(coreNav.trayA.xmlNodeMap);
}


function generateChildNodeDisplayCode(parentXmlNode, htmlContainer)
{
	/* Determine the location pointer value of the parent node (used as argument in buildHtmlStringFromXml method call). */
	var parentPathIndex = coreNav.trayA.xmlNodeMap[parentXmlNode.getAttribute("id")].location;

	/* Delete contents of htmlString variable before generating new code. */
	coreNav.trayA.htmlString = "";

	/* Generate HTML markup string for the new nodes by walking the treeMenu XML fragment
		starting at the parent containing the new children. */
	coreNav.trayA.buildHtmlStringFromXml(parentXmlNode, parentPathIndex);
//top.contentFrame.document.write(htmlString);
//top.contentFrame.document.close();

	/* Insert the markup for the new children into the appropriate tree menu <div> container. */
	insertHtml(coreNav.trayA.htmlString, htmlContainer);

	if (coreNav.trayA.htmlString == "") return false
	else return true
}
/**** END - COMMON CODE */


/**** LIBRARY CODE */
var libNavBuilder = null;
/* This function is called from the lm_dir_page.htm template (this template gets loaded into
	a hidden Iframe (hiddenActionWindow) and populates the tempNavBuilder XML object with nodes
	when the user opens a library folder).*/
function libraryNodeLoadSequence(tempNavBuilder)
{
	if (tempNavBuilder)
		libNavBuilder = tempNavBuilder;

	var childNodesXmlRoot = libNavBuilder.xmlDocument.getElementsByTagName("navtree")[0];

	if (childNodesXmlRoot != null)
	{
		/* Set object variables to be used as parameters of the insertParsedChildNodes()
			and generateChildNodeDisplayCode() funcitons. */
		var childNodeList = childNodesXmlRoot.childNodes;
		var parentId = childNodesXmlRoot.getAttribute("page_name");
		var parentNode = coreNav.trayA.getNodeById(parentId);
		var parentHtmlContainer = leftNavWindow.document.getElementById(parentId);

		insertParsedChildNodes(childNodeList, parentNode, "replace");

		if (generateChildNodeDisplayCode(parentNode, parentHtmlContainer))
		/* Change the display of the container only if nodes were actually added to it. */
		{
			parentHtmlContainer.style.display = "block";
		}
		else
		{
			parentHtmlContainer.style.display = "none";
		}
	}
	else
	{
		setTimeout("libraryNodeLoadSequence()", 100);
	}
}


/**** PERSONAL URL UPDATE CODE */
/* This function is conditionally called by the updatePersonalURLS() function in the
	lm_pne_portal_personal_urls_page.htm (located in custom/LayoutManager/templates). */
function updatePersonalUrlTree(titleArray, urlArray)
{
	var tempNavBuilder = new navBuilder();

	for(var i=0; i<titleArray.length; i++)
	{
		var urlString = urlArray[i];
		var titleString = titleArray[i];

		// Encode XML escape character entities.
		titleString = xmlEncode(titleArray[i]);
		urlString = xmlEncode(urlArray[i]);

		tempNavBuilder.addChildNodeTo('NAVTREE', 'item', 'id==PERSONAL_URL_'+(i+1), 'label=='+titleString,
			'url=='+urlString, 'target==_blank');
	}

	personalUrlLoadSequence(tempNavBuilder);
}

var urlNavBuilder = null;
function personalUrlLoadSequence(tempNavBuilder)
{
	if (tempNavBuilder)
		urlNavBuilder = tempNavBuilder;

	var childNodesXmlRoot = urlNavBuilder.xmlDocument.getElementsByTagName("navtree")[0];

	if (childNodesXmlRoot != null)
	{
		/* Set object variables to be used as parameters of the insertParsedChildNodes()
			and generateChildNodeDisplayCode() funcitons. */
		var childNodeList = childNodesXmlRoot.childNodes;
		var parentNode = coreNav.trayA.getNodeById("MY_PERSONAL_URLS");
		var parentHtmlContainer = leftNavWindow.document.getElementById("MY_PERSONAL_URLS");

		/* Run the routines that insert the parsed XML into the appropriate fragment, and
			dynmically modify the html display code. */
		insertParsedChildNodes(childNodeList, parentNode, "replace");
		generateChildNodeDisplayCode(parentNode, parentHtmlContainer);

		/* Set image variable to be used in display-setting block below. */
		var treeConnectorImage = leftNavWindow.document.getElementById("MY_PERSONAL_URLS_link").getElementsByTagName("IMG")[0];

		if (treeConnectorImage.src.indexOf("open.gif") > -1)
		{
			if (childNodeList.length > 0)
			/* If the collection was empty but the user had the folder open, display the html container
				if items were added to the node list by the update. */
			{
				parentHtmlContainer.style.display = "block";
			}
			else if (childNodeList.length == 0)
			/* If the collection previously had contents and the user had the folder open, supress display
				of the html container if all items were removed from the node list by the update. */
			{
				parentHtmlContainer.style.display = "none";
			}
		}
	}
	else
	{
		setTimeout("personalUrlLoadSequence()", 100);
	}
}


/**** ADD SAVED QUERY CODE */
/* This function is conditionally called by the saveSearchQuery() function in the
	query_form_submit_script include override located in lm_std_page.htm (when the Save
	button is clicked on a search results page). */
function addSavedQueryToTree(qTitle, qUrl)
{
	// Declare variables for use in FOR loop below.
	var savedQueriesParentNode = coreNav.trayA.getNodeById("MY_SAVED_QUERIES");
	var savedQueriesNodeList = savedQueriesParentNode.childNodes;

	// delete the node from the tree if there are too many
	if (savedQueriesNodeList.length >= maxSavedSearchResults)
		coreNav.trayA.deleteItem('MY_SAVED_QUERY_' + maxSavedSearchResults);

	/* Loop upward through the XML node list of saved queries and re-set the ID values by adding
		one to the index number within each. This allows the new query to be added to the top
		of the list with the sequentially-correct ID value of MY_SAVED_QUERY_1. */
	for (var i=savedQueriesNodeList.length-1; i>=0; i--)
	{
		if (savedQueriesNodeList[i].nodeType == 1)
		{
			var idIndexArray = savedQueriesNodeList[i].getAttribute("id").split("_");
			idIndexArray[3] = parseInt(idIndexArray[3]) + 1;
			idIndexArray[3].toString();
			savedQueriesNodeList[i].setAttribute("id", idIndexArray.join("_"));
		}
	}

	// add the new saved query to the list with index 1
	var tempNavBuilder = new navBuilder();
	qTitle = xmlEncode(qTitle);
	qUrl = xmlEncode(qUrl);
	tempNavBuilder.addChildNodeTo('NAVTREE', 'item', 'id==MY_SAVED_QUERY_1', 'label=='+qTitle, 'url=='+qUrl);
	addQueryLoadSequence(tempNavBuilder);
}

var queryNavBuilder = null;
function addQueryLoadSequence(tempNavBuilder)
{
	if (tempNavBuilder)
		queryNavBuilder = tempNavBuilder;

	var childNodesXmlRoot = queryNavBuilder.xmlDocument.getElementsByTagName("navtree")[0];

	if (childNodesXmlRoot != null)
	{
		/* Set object variables to be used as parameters of the insertParsedChildNodes()
			and generateChildNodeDisplayCode() funcitons. */
		var childNodeList = childNodesXmlRoot.childNodes;
		var parentNode = coreNav.trayA.getNodeById("MY_SAVED_QUERIES");
		var parentHtmlContainer = leftNavWindow.document.getElementById("MY_SAVED_QUERIES");

		/* Run the routines that insert the parsed XML into the appropriate fragment, and
			dynmically modify the html display code. */
		insertParsedChildNodes(childNodeList, parentNode, "addToTop");
		generateChildNodeDisplayCode(parentNode, parentHtmlContainer);

		/* Set image variable to be used in display-setting block below. */
		var treeConnectorImage = leftNavWindow.document.getElementById("MY_SAVED_QUERIES_link").getElementsByTagName("IMG")[0];

		if (treeConnectorImage.src.indexOf("open.gif") > -1)
		{
			if (childNodeList.length > 0)
			/* If the collection was empty but the user had the folder open, display the html container
				if items were added to the node list by the update. */
			{
				parentHtmlContainer.style.display = "block";
			}
			else if (childNodeList.length == 0)
			/* If the collection previously had contents and the user had the folder open, supress display
				of the html container if all items were removed from the node list by the update. */
			{
				parentHtmlContainer.style.display = "none";
			}
		}
	}
	else
	{
		setTimeout("addQueryLoadSequence()", 100);
	}
}


/**** SAVED QUERY UPDATE CODE */
/* This function is conditionally called by the updateSavedQueries() function in the
	lm_pne_portal_saved_queries_page.htm (located in custom/LayoutManager/templates). */
function updateSavedQueriesTree(deleteString)
{
	var deleteItemArray = deleteString.split(",");
	var parentNode = coreNav.trayA.getNodeById("MY_SAVED_QUERIES");
	var parentHtmlContainer = leftNavWindow.document.getElementById("MY_SAVED_QUERIES");
	var savedQueriesNodeList = parentNode.childNodes;

	/* Loop upward through the node list; check each label attribute value against the query
		title values in the deleteItemArray. If a match is found, delete the node from the tree.
		Note: had to loop upward rather than downward since node list contents are dynamic. */
	for (var i=savedQueriesNodeList.length-1; i>=0; i--)
	{
		if (savedQueriesNodeList[i].nodeType == 1)
		{
			var queryTitle = savedQueriesNodeList[i].getAttribute("label");
			for (var j=0; j<deleteItemArray.length; j++)
			{
				if (queryTitle == deleteItemArray[j])
				{
					parentNode.removeChild(savedQueriesNodeList[i]);
					break;
				}
			}
		}
	}

	/* Remap the treeMenu fragment after the nodes have been deleted. */
	coreNav.trayA.xmlNodeMap = new Object();
	mapXMLTree(coreNav.trayA.xmlRoot, coreNav.trayA.xmlNodeMap);
	//DEBUG_displayNodeMap(coreNav.trayA.xmlNodeMap);

	/* Run the routine that dynmically modifies the html display code based upon the
		modified tree. */
	generateChildNodeDisplayCode(parentNode, parentHtmlContainer);
}


/* NAVIGATION SHELL DHTML **************************************************************************/
/***************************************************************************************************/


/* This function allows the main page columns to be resized by dragging on the bar between the left
	nav and content areas. An indirect method of resizing is used, where the user drags a floating bar
	to the desired location, and the table then snaps to the new size upon mouseup. This was done to
	prevent the continuous refresh problems associated with dragging and sizing the table cells directly. */
function sizePageColumns(event)
{
	document.body.style.cursor = "e-resize";

	/* Declare object variables */
	var leftCol = document.getElementById("leftNavCell");
	var rightCol = document.getElementById("contentCell");
	var dragBar = document.getElementById("dragBar");
	var frameDividerCell = dragBar.parentNode;
	var pageMask = document.getElementById("pageMask");
	var frameParentCell = pageMask.parentNode;

	/* Make the drag bar object visible, and set its size and position to match those of
		the frame divider cell. */
	dragBar.style.display = "block";
	var frameDividerCellInfo = new dimensionFinder(frameDividerCell);
	dragBar.style.height = frameDividerCellInfo.height;
	dragBar.style.width = frameDividerCellInfo.width;
	dragBar.style.top = frameDividerCellInfo.relativeTop;
	dragBar.style.left = frameDividerCellInfo.relativeLeft;

	/* Place a mask over the page area to prevent iframe documents from taking control
		of events away from the top-level document. */
	pageMask.style.display = "block";
	var frameParentCellInfo = new dimensionFinder(frameParentCell);
	pageMask.style.height = frameParentCellInfo.height;
	pageMask.style.width = frameParentCellInfo.width;
	pageMask.style.top = frameParentCellInfo.relativeTop;
	pageMask.style.left = frameParentCellInfo.relativeLeft;

	// Set the starting X-position of the mouse.
	var startPosX = event.clientX;

	// Register the event handlers that will respond to the mousemove events
	// and the mouseup event that follow this mousedown event.
	if (document.addEventListener)
	{ // DOM Level 2 Event Model
		// (Note: I left the DOM branching in case IE supports these standards in the future).
		document.addEventListener("mousemove", moveHandler, true);
		document.addEventListener("mouseup", upHandler, true);
	}
	else if (document.attachEvent)
	{ // IE 5+ Event Model
		document.attachEvent("onmousemove", moveHandler);
		document.attachEvent("onmouseup", upHandler);
	}

	// We've handled this event.  Don't let anybody else see it.
	if (event.stopPropagation) event.stopPropagation();   // DOM Level 2
	else event.cancelBubble = true;                       // IE

	// Now prevent any default action.
	if (event.preventDefault) event.preventDefault();     // DOM Level 2
	else event.returnValue = false;                       // IE

	/**
	 * This is the handler that captures mousemove events when an element
	 * is being dragged.  It is responsible for moving the element.
	 **/
	function moveHandler(e)
	{
		if (!e) e = window.event;  // IE event model

		var startDragBarPosX = dragBar.offsetLeft;
		var maxDragPosX = document.body.clientWidth - 100;

		// Set new dragBar position based upon cursor location (conditionals limit the max an min drag positions).
		if (startDragBarPosX - (startPosX - e.clientX) > 25 && startDragBarPosX - (startPosX - e.clientX) < maxDragPosX)
		{
			var newDragBarPosX = startDragBarPosX - (startPosX - e.clientX);
			dragBar.style.left = newDragBarPosX + "px";
		}

		// Reset starting mouse position.
		startPosX = e.clientX;

		// And don't let anyone else see this event.
		if (e.stopPropagation) e.stopPropagation();       // DOM Level 2
		else e.cancelBubble = true;                       // IE
	}

	/**
	 * This is the handler that captures the final mouseup event that
	 * occurs at the end of a drag.
	 **/
	function upHandler(e)
	{
		if (!e) e = window.event;  // IE event model

		/* Resize the left table cell based upon the final position of the dragBar. The right cell
		  (content area) should size automatically to take the remaining space in the window. */
		var dragBarEndPosX = dragBar.offsetLeft;
		leftCol.style.width = (dragBarEndPosX) + "px";

		// Unregister the capturing event handlers.
		if (document.removeEventListener)
		{	// DOM Event Model
				document.removeEventListener("mouseup", upHandler, true);
				document.removeEventListener("mousemove", moveHandler, true);
		}
		else if (document.detachEvent)
		{	// IE 5+ Event Model
				document.detachEvent("onmouseup", upHandler);
				document.detachEvent("onmousemove", moveHandler);
		}

		/* Hide the IE mask. */
		pageMask.style.display = "none";

		/* Hide the drag bar object. */
		dragBar.style.display = "none";

		document.body.style.cursor = "auto";

		// And don't let the event propagate any further.
		if (e.stopPropagation) e.stopPropagation();       // DOM Level 2
		else e.cancelBubble = true;                       // IE
	}
}


