/* Client-side Javascript for sidebar */
/* Copyright 2009,2010,2011 Disk Depot */
/*
 * New version alters behaviour so that you have to click on titles to expand (rather than just hover);
 * the old version is in sidebar-client-ORIGINAL.js and as of 1 March 2010 can be drop-in-replaced/restored by changing
 * the filename to sidebar-client.js
 *
 * IMPORTANT: Strongly recommended that any further major changes to sidebar menu should ditch this code in favour of a rewrite, as it would have been
 * simpler and more maintainable to have done that than modifying the existing menu code in the first place(!)
 *
 * Note that menu data itself is generated on the fly by sidebar.asp
 */

var		BASE_ID = 'pmn',
		SUBMENU_BASE_ID = 'spmn',
		LINK_BASE_ID = 'sblink',
		SIDEBAR_SUBMENU_NAME = 'sbsubmenu',
		SELECTED_BG = '#dddddd',
		UNSELECTED_BG = 'white',
		INCLUDE_ANCESTOR_SIBLINGS = true,
		SWAP_DIRECTION_AT = 10;			/* Top level element where we swap to top-up menus */
var		sbSelectedElmId = null,
		helpPopupCount = 0;

	function elmBg(elm, selected)
	{
		if (elm !== null) {
			elm.className = selected ? "sbMenuItemHl" : "sbMenuItemUl";
		}
	}

	function sidebarMouseOver(e, elmId)
	{
		var	mainElm = document.getElementById(elmId),
			trigElm = e.target ? e.target : e.srcElement,
			fromElm = e.relatedTarget ? e.relatedTarget : e.fromElement;
		
		if (sidebarIsDescendantOf(mainElm, trigElm) && !sidebarIsDescendantOf(mainElm, fromElm)) {
			elmBg(mainElm, true);
			sbSelectedElmId = elmId;
			showSubtree(e, elmId);
		}
	}

	function sidebarMouseOut(e, elmId)
	{
		//TEST_msg("OUT (" + e + "," + elmId + ")");

		var	mainElm = document.getElementById(elmId),
			trigElm = e.target ? e.target : e.srcElement,
			toElm = e.relatedTarget ? e.relatedTarget : e.toElement;
		
		if (sidebarIsDescendantOf(mainElm, trigElm) && !sidebarIsDescendantOf(mainElm, toElm)) {
			elmBg(mainElm, false);

			sbSelectedElmId = null;

			setTimeout("sidebarDelayedMouseOut('" + elmId + "')", 700);
		}
	}

	function sidebarDelayedMouseOut(elmId)
	{
		//TEST_msg("DELAYED OUT()");
		//document.getElementById(elmId).style.backgroundColor= 'cyan';
		
		if (sbSelectedElmId == null) {
			//TEST_msg("BEFORE {" + document.getElementById("spmn_10_4").innerHTML.replace(/</gi, "((") + "}<br /> ", true);
			hideAllElms(BASE_ID, 0, sbSelectedElmId);	
			//TEST_msg("<br />*<br />", true);
		}
	}

	/* Check if desc is a descendant of elm within DOM tree itself */
	function sidebarIsDescendantOf(elm, desc)
	{
		if (!elm || !desc) {
			return false;
		}

		do {
			if (elm == desc) {
				return true;
			}

			desc = desc.parentNode;
		} while (desc);

		return false;
	}

	function TEST_msg(msg, isAdd) {
		if (isAdd) {
			document.getElementById('testerer').innerHTML += "" + msg;
		} else {
			document.getElementById('testerer').innerHTML = msg;
		}
	}

	/**
	  * baseId: BASE_ID
	  * level: Always 0 for users calling this
	  * reatainBranchId: ID of an element, all of whose parent nodes will also stay displayed
	  *			if this value isn't set to null
	  */
	function hideAllElms(baseId, level, retainBranchId)
	{
		if ((level == 0) && (retainBranchId ===null)) {
			//alert('hiding all');
		       	hideAllSubmenus();
		}

		level += 1;
	
		var	i = 1, elm;
		do {				/* Do for each child element */
			var	childId = baseId + "_" + i;
			if (elm = document.getElementById(childId)) {	/* Assign & check */
				if (level > 1) {						/* TODO: Merge conditions? */
					if ((retainBranchId == null) || !isAncestorOf(retainBranchId, childId, INCLUDE_ANCESTOR_SIBLINGS, true)) {
						elm.style.display = 'none';
						//TEST_msg(elm.id + " ", true);

						if (i == 1) {		/* If >= 1 child, enclosing submenu elm must also exist, so hide that too */
							var	menuElm = document.getElementById(baseId.replace(BASE_ID, SUBMENU_BASE_ID));
							//var	imgElm = document.getElementById(baseId.replace(BASE_ID, JOIN_BASE_ID));

							//TEST_msg("ID IS {" + baseId.replace(BASE_ID, SUBMENU_BASE_ID) + "} ", true);
							if (menuElm) { 
								menuElm.style.display = 'none';
								menuElm.style.position = "fixed";
								menuElm.style.left = "-500px";
							}
							//if (imgElm) { imgElm.style.display = 'none';	}
						}
					}

				}

				hideAllElms(childId, level, retainBranchId);				/* Recursively call for each of child's children */
			}
			
			++i;
		} while (elm);
	}

	/* Determine if element parentId is an ancestor of element myId; assumes part of menu hierarchy, does not work directly on DOM per se */
	/* This is NOT the inverse of isDescendantOf()! */
	function isAncestorOf(myId, parentId, includeSiblingsOfAncestors, includeSelf)
	{
		if (myId == parentId)
			return includeSelf;
		if (myId.match(parentId + "_"))
			return true;
			
		/* If counting siblings of "true" ancestors" as ancestors, determine if parent is ancestor */
		if (includeSiblingsOfAncestors) {
			var	parentParentId = getParentId(parentId);
			return isAncestorOf(myId, parentParentId, false, false);
		}
				
		return false;
	}

	function getParentId(elmId)
	{
		var	matchPat = /_[0-9]*$/g;
		
		parentId = elmId.replace(matchPat, "");
		
		return (parentId == BASE_ID) ? null : parentId;
	}

	function showSubtree(e, id)
	{
		var	elm = document.getElementById(id);

		hideAllElms(BASE_ID, 0, id);	/* Hide all elm except branch to element with specified id (and all first-level elms) */
		
		childNodesDisp(elm, true);
	}

	/* Given a top-level element's ID, determine its corresponding order within the top level menu (i.e. 1, 2, 3...) */
	function getTopLevelOrder(elmId)
	{
		elmId = elmId.replace(BASE_ID + "_", "");
		elmId = elmId.replace(/_.*/gi, "");
		var order = parseInt(elmId);

		return order;
	}

	function propogateClick(e, myId)
	{
		e.cancelBubble = true;		// IE-style behaviour works in Firefox

		var	trigElm = e.target ? e.target : e.srcElement;

		var	ahrefId = myId.replace(BASE_ID, LINK_BASE_ID); 

		var	ahref = document.getElementById(ahrefId);

		window.location = ahref.href;
	}

	function sidebarHtmlRoot(root, level, myId)
	{
		var	result = "";		
		var	style = "";
		var	onMouseOver = "onmouseover='sidebarMouseOver(event, \"" + myId + "\")'";
		var	onMouseOut = "onmouseout='sidebarMouseOut(event, \"" + myId + "\")'";
		var	onClick = "onclick='propogateClick(event, \"" + myId + "\");'";
		var	bright = 16 - 2 * level;
		var	brightAll = (bright * 256) + (bright * 16) + bright;
		var	brightHex = brightAll.toString(16);
		var	hasChildren = (root.c  &&  root.c["1"]);
		var	cssClass;

		style += (level > 1) ?
				"padding-left:10px;" :
				"padding-right:10px;";
		style += (level > 1) ? "font-weight:normal;" : "font-weight:bold;";
		/* style += "background-color:#" + brightHex + ";"; */
		style += (level == 1) ? "width:125px;" : "";
		style += (level > 1) ? "display:none; width:125px;" : "";

		style += (!hasChildren) ? "padding-top:3px; padding-bottom:3px;" : "";

		style += (level == 1) ? "position:relative;" : "position:relative;";

		cssClass += "sbMenuItemUl ";

		result += "<div class='sbMenuItemUl' style='" + style + "' id='" + myId + "' " + onMouseOver + " " + onMouseOut + " " + onClick + " >";
		
		//for (var i = 0; i < (level - 1) * 5; ++i) {	result += "&nbsp;"; }
		var	nSplit = root.n.split(" "),
			nFinal = nSplit[nSplit.length -1];
		nSplit.length -= 1;

		var	aClass = (level == 1  ||  hasChildren) ? "sbnonleaf" : "sbleaf";

		/* var	escUrl = urlEscapeForPerlRedirects("http://www.diskdepot.co.uk/acatalog/" + root.u); */
		var	escUrl = urlEscapeForPerlRedirects(root.u);

		/* document.write(escUrl + "/"); */

		var	dynamicUrl = "http://www.diskdepot.co.uk/cgi-bin/ss000001.pl?SECTIONID=" + escUrl + "&NOLOGIN=1";
		var	wantedUrl;

		if (wantRedirectedTreeLinks) {							/* Used for two-level redirects when linking from blog */
			wantedUrl = "http://www.diskdepot.co.uk/acatalog/redirect.asp?redirectsiteurl=" + escape(dynamicUrl);
		} else if (wantStaticTreeLinks) {						/* Static link direct to page */
			wantedUrl = "http://www.diskdepot.co.uk/acatalog/" + root.u;
		} else {									/* Default is single-level ss000001.pl redirected link */
			wantedUrl = dynamicUrl;
		}

		var	linkId = myId.replace(BASE_ID, LINK_BASE_ID);
		if (hasChildren) {
			var	subId = myId.replace(BASE_ID, SUBMENU_BASE_ID);

			result += "<div name='" + SIDEBAR_SUBMENU_NAME + "' id='" + subId + "' style='background-color:pink; border: solid 1px black; position:fixed; left:-500px; display:none; z-index:" + (10000 + level) + ";'>" + sidebarHtmlChild(root.c, level, myId) + "</div>";	/* Cascading sub-menu */
			result += ("<div style='padding-top:3px; padding-bottom:3px;' ><a id='" + linkId + "' class='" + aClass + "' href='" + wantedUrl + "'><span>" + nSplit.join(" ") + " <span style='white-space:nowrap;'>" + nFinal);
			result += "&nbsp;&nbsp;<img border='none' src='http://www.diskdepot.co.uk/sidebarjs/arrow.gif' width='6' height='9' style='vertical-align:bottom;' id='arrow_" + myId + "' /></span></span></a></div>";
		} else {
			result += ("<a id='" + linkId + "' href='" + wantedUrl + "' class='" + aClass + "' >" + nSplit.join(" ") + " <span style='white-space:nowrap;'>" + nFinal);
			result += "</span></a>";
		}

		result += "</div>";

		return result;
	}
	
	function sidebarHtmlChild(pChild, level, parentId)
	{
		var	result = "";
	
		for (var i in pChild) {
			result += sidebarHtmlRoot(pChild[i], level + 1, parentId + "_" + i);
		}
		
		return result;
	}

	function sidebarRootDisplay(pChild, level, parentId)
	{
		return "<div style='margin-left:9px; z-index:1000; '>" + sidebarHtmlChild(pChild, level, parentId) + "</div>";
	}

	function fetchAllSubmenus()
	{
		var	menus = document.getElementsByName(SIDEBAR_SUBMENU_NAME);

		return menus;
	}

	function hideAllSubmenus()
	{
		var menus = fetchAllSubmenus();

		for (var i = 0; i < menus.length; ++i) {
			menus[i].style.display = "none";
		}	
	}

	function fetchChildren(nodeElm)
	{
		var	i,
			id = nodeElm.id,
			result = new Array(),
			temp;

		i = 1;
		while (temp = document.getElementById(id + "_" + i)) { /* Assigned value null? */

			result.push(temp);
			++i;
		}
		
		return result;
	}

	function fetchSubmenu(nodeElm)
	{
		var	id = nodeElm.id.replace(BASE_ID, SUBMENU_BASE_ID);

		return document.getElementById(id);
	}
	
	/* function fetchJoinImg(nodeElm)
	{
		var	id = nodeElm.id.replace(BASE_ID, JOIN_BASE_ID);

		return document.getElementById(id);
	} */

	/* function fetchShadowImg(nodeElm)
	{
		var	id = nodeElm.id.replace(BASE_ID, SHADOW_BASE_ID);

		var result = document.getElementById(id);

		return result;
	}*/

	function elmDisplay(elm, show)
	{
		if (elm.style) {
			elm.style.display = show ? "block" : "none";
		} 
	}
	
	function elmsDisplay(elms, show)
	{
		for (var x in elms) {
			elmDisplay(elms[x], show);
		}
	}

	function childNodesDisp(elm, show)
	{
		var	topLevelOrder = getTopLevelOrder(elm.id);
		var	subMenuElm = fetchSubmenu(elm);
		//var	joinImgElm = fetchJoinImg(elm);
		/* var	shadImgElm = fetchShadowImg(elm); */

		if (subMenuElm) {
			var width = parseInt(elm.clientWidth), height = parseInt(elm.clientHeight);

			var	children = fetchChildren(elm);
			elmsDisplay(children, show);	

			subMenuElm.style.backgroundColor = 'white';
			//subMenuElm.style.backgroundImage = 'url("/acatalog/plainbg1x1.png")';
			subMenuElm.style.position = show ? "absolute" : "fixed";
			subMenuElm.style.left = show ? (((width * 1) - 10) + "px") : "-500px";
					/* Positioned off-screen because have problems with them reappearing under IE otherwise even though display:none */
			elmDisplay(subMenuElm, show);
			var subWidth = parseInt(subMenuElm.clientWidth), subHeight = parseInt(subMenuElm.clientHeight);
			if (topLevelOrder >= SWAP_DIRECTION_AT) {
				subMenuElm.style.bottom = Math.floor((-subHeight/4) )+ "px";
			} else {
				subMenuElm.style.top = "-1px";
			}

			if (!oldIe) {
				subMenuElm.style.border='solid 1px black';
			} else {
				subMenuElm.style.border='none';
			}

			/* Nasty hack for border not appearing under IE, suspect this may be related to earlier positioning hack. Bleh :-6 */
			if (!oldIe) {
				setTimeout("document.getElementById('" + elm.id.replace(BASE_ID, SUBMENU_BASE_ID) + "').style.border='solid 1px black'", 150);
			}
			setTimeout("document.getElementById('" + elm.id.replace(BASE_ID, SUBMENU_BASE_ID) + "').style.backgroundColor='white'", 150);
		}
	}

	function sidebar_TEST1()
	{
		var	elma = document.getElementById('test_a');
		var	elmb = document.getElementById('test_b');
		var	elmc = document.getElementById('test_c');
		var	elmd = document.getElementById('test_d');

		alert("aa " + sidebarIsDescendantOf(elma, elma));
		alert("ab " + sidebarIsDescendantOf(elma, elmb));
		alert("ac " + sidebarIsDescendantOf(elma, elmc));
		alert("ad " + sidebarIsDescendantOf(elma, elmd));
		alert("bb " + sidebarIsDescendantOf(elmb, elmb));
		alert("bc " + sidebarIsDescendantOf(elmb, elmc));
		alert("bd " + sidebarIsDescendantOf(elmb, elmd));
		alert("cc " + sidebarIsDescendantOf(elmc, elmc));
		alert("cd " + sidebarIsDescendantOf(elmc, elmd));
		alert("dd " + sidebarIsDescendantOf(elmd, elmd));

		alert("ba " + sidebarIsDescendantOf(elmb, elma));
		alert("da " + sidebarIsDescendantOf(elmd, elma));
	}

	/* Escape urls that are accessed via a perl redirect page */
	function urlEscapeForPerlRedirects(url)
	{
		var	result = encodeURIComponent(url);

		result = result.replace(/\./g, "%2e");	

		return result;
	}

