//***********************************************
//* Slashdot Menu script- By DimX
//* Submitted to Dynamic Drive DHTML code library: http://www.dynamicdrive.com
//* Visit Dynamic Drive at http://www.dynamicdrive.com/ for full source code
//***********************************************

//***********************************************
//* May 2007: Modified by Ictinus for nested submenus and wrapping menu items.
//***********************************************
//* Note: rarely but reproducably a submenu can appear to be too long for the links 
//* within it, a slight reduction in width will usually make a link wrap to fill up the space.
//* The browser just isn't calculating the height correctly.
//***********************************************

var remember = false; //Remember menu states, and restore them on next visit.
//defaultStates - An array of zeros and ones (0,1,1,0) that represent open (0) and closed (1) menus.
//if the array is empty, no default state of menu will be loaded. if the array has values, but not as many as there are menus, you will be alerted.
var defaultStates = new Array(1,1,1,1,1,1,1,1,1,1,1,1,1,1); 
var contractall_default = true; //Should all submenus be contracted by default? (true or false)

//NOTE: order or priority for menu states is 'remember' (ie. use cookie), defaultStates (if array not empty), 'contractall_default'

var bypixels = 2;   //Basicly it's speed, 
					//but if the (number of submenu elements * bypixels) is larger than the submenu height
					//the menu will change height by ~50% each step.
var collapse_lastmenu = true; //if true, close the last menu that was opened if it was not a parent or child menu.
var collapse_topmenus_only = true; //if true, collapse top level menus only; requires collapse_lastmenu to be true.
var bInstantMenus = false; //if you want the menus to open instantly

var redraw_timeout = 30; //milliseconds to menu redraw incase of window or font resize.

var bRefreshMenu = true; //if true, the submenus will be refreshed if needed at the redraw_timeout interval.
						 //this allows the menu to work with font and window resizing.

var iSubmenuIndent = 8; //number of pixels for submenu menu title indents.
var iSubmenuItemIndent = 8; //number of pixels for submenu item indent level.

//================= should be no need to configure anything below this line, but feel free to be adventurous ===================================
var menu, titles, titletext, submenus, bypixels;
var submenu_haschildren = new Array();
var menuWidth = 0;
var menuHeight = 0;
var lastMenu = 0;
var refreshdelay;
var q = new Array();
var qOpen;
var qClose;
var submenuState = new Array();

function forceRedraw() {
	if ((q[0] == false) && (q[1] == false)) { 
		if ( ( (menuWidth != menu.offsetWidth) || (menuHeight != menu.offsetHeight) ) ) {
			restoreFromCookie();
		}
	}
}

function refreshmenu() {

	if (q[0] == true) {
		(bInstantMenus) ? hidemenunow(qClose, true) : hidemenu(qClose, true);
	}
	if (q[1] == true) {
		(bInstantMenus) ? showmenunow(qOpen, true, true) : showmenu(qOpen, true);
	}
	// only redraw the menu if we aren't closing or opening a submenu
	if ((q[0] == false) && (q[1] == false)) {
		//and only do it if the menu dimensions have changed
		if ( ( (menuWidth != menu.offsetWidth) || (menuHeight != menu.offsetHeight) ) ) { 
			if (bRefreshMenu) restoreFromMemory();
		}
	}
}

function slash_expandall(bStore){
	if (typeof menu!="undefined"){
		for(var i=submenus.length-1; i >= 0; i--){
			if (submenu_haschildren[i] == true)
				showmenunow(i, bStore, false);
		}
	}
}

function slash_contractall(bStore){
	if (typeof menu!="undefined"){
		for(var i=0; i<submenus.length; i++){
			hidemenunow(i, bStore);
		}
	}
}

function initmenu(){
	var sublvls;

    menu = getElementsByClassName("sdmenu", "div", document)[0];
    titles = getElementsByClassName("title", "span", menu);
    submenus = getElementsByClassName("submenu", "div", menu);
    titletext = getElementsByClassName("tt", "span", menu);

	if ((defaultStates.length > 0) && (defaultStates.length != submenus.length)) { alert('The number of default states is ' + defaultStates.length + ', but the number of menus is ' +submenus.length) }

    for(var i=0; i<submenus.length; i++) {
        titles[i].onclick = gomenu;
        titletext[i].onclick = gomenu;
        submenus[i].style.height = submenuHeight(submenus[i])+"px";
		submenu_haschildren[i] = (submenus[i].getElementsByTagName("*").length > 0)
    }
	setSubmenuMargins(menu, 0);

	//set the menu to the appropriate collapse/expand state
    (remember) ? restoreFromCookie() : restoreStates(defaultStates);
	
	refreshdelay = setInterval("refreshmenu()", redraw_timeout);

	q[0] = false; q[1] = false; //set no current menu activity

	var sublvls2;

    menu2 = getElementsByClassName("sdmenu-der", "div", document)[0];
    titles2 = getElementsByClassName("title-der", "span", menu2);
    submenus2 = getElementsByClassName("submenu-der", "div", menu2);
    titletext2 = getElementsByClassName("tt-der", "span", menu2);

	if ((defaultStates2.length > 0) && (defaultStates2.length != submenus2.length)) { alert('The number of default states is ' + defaultStates2.length + ', but the number of menus is ' +submenus2.length) }

    for(var i2=0; i2<submenus2.length; i2++) {
        titles2[i2].onclick = gomenu2;
        titletext2[i2].onclick = gomenu2;
        submenus2[i2].style.height = submenuHeight2(submenus2[i2])+"px";
		submenu_haschildren2[i2] = (submenus2[i2].getElementsByTagName("*").length > 0)
    }
	setSubmenuMargins2(menu2, 0);

	//set the menu2 to the appropriate collapse/expand state
    (remember2) ? restoreFromCookie2() : restoreStates2(defaultStates2);
	
	refreshdelay2 = setInterval("refreshmenu2()", redraw_timeout2);

	q2[0] = false; q2[1] = false; //set no current menu2 activity
}

function setSubmenuMargins(oElm, currentMargin) {
	var oElmCurrent = oElm.firstChild;
	while (oElmCurrent) {
		if (oElmCurrent.className == "submenu") {
			setSubmenuMargins(oElmCurrent, parseInt(currentMargin) + parseInt(iSubmenuIndent));
		} else if (oElmCurrent.nodeType == 1) {//nodeType test to skip non-HTML elements, i.e. text nodes
			if (oElmCurrent.nodeName == "A") {
				if ((oElmCurrent.firstChild.className == "title") || (oElmCurrent.firstChild.className == "titlehidden")) {//submenu title link
					oElmCurrent.firstChild.firstChild.style.marginLeft = String(currentMargin) + "px" ;
				} else {//normal menu link
					oElmCurrent.firstChild.style.marginLeft = String(parseInt(currentMargin)+(parseInt(iSubmenuItemIndent))) + "px" ;
				}
			} else if ((oElmCurrent.className == "title") || (oElmCurrent.className == "titlehidden")) {
				oElmCurrent.firstChild.style.marginLeft = String(currentMargin) + "px" ;
			}
		}
		oElmCurrent = oElmCurrent.nextSibling;
	}
}

function restoreStates(arrStates) {
	if (submenus.length == arrStates.length) {
		for (var i=arrStates.length-1; i>=0; i--) {
			if (arrStates[i] == 1 || submenu_haschildren[i] == false) {
				hidemenunow(i, true);
			} else {
				showmenunow(i, true, false);
			}
   		} 
	} else {
		if (submenus.length == defaultStates.length) {
			restoreStates(defaultStates);
		} else if (contractall_default == true) {
			slash_contractall(true);
		} else {
			slash_expandall(true);
		}
	}
}

function restoreFromMemory() {

	for (var i=submenuState.length-1; i>=0; i--) {
		if (submenuState[i] == 1) {
			if (parseInt(submenus[i].style.height) != 0 || submenu_haschildren[i] == false) {
				hidemenunow(i, false); // no need to store cookie info, it will be the same in the end
			}
		} else {
			if (parseInt(submenus[i].style.height) != submenuHeight(submenus[i])) {
				showmenunow(i, false, false); // no need to store cookie info, it will be the same in the end
			}
		}
   	}
}

function restoreFromCookie() {
    if (getcookie("menu") != null) {
        submenuState = getcookie("menu").split(",");
		restoreStates(submenuState);
    } else {
		restoreStates(defaultStates);
	}
	menuWidth = menu.offsetWidth;
	menuHeight = menu.offsetHeight;
}

function gomenu(e) {
	// if we don't allow multiple menus to be manipulated at the same time, check to see if one is being manipulated
   	if ((q[0] == true || q[1] == true) && collapse_lastmenu == false) return;

    if (!e) var e = window.event;
    var ce = (e.target) ? e.target : e.srcElement;
    var sm;

	i = 0; sm = -1;
	while (i < titles.length && sm == -1) {
        if(titles[i] == ce || titletext[i] == ce) sm = i;
		i++;
    }

    if (submenu_haschildren[sm] == true) { //only expand the menu if it has sub elements
 		// do not allow the event to bubble up to containing span
		// keep anti-bubble code within "if submenu_haschildren[sm] == true"
		if( e.preventDefault ) { e.preventDefault(); }
		e.returnValue = false;
		if( e.stopPropagation ) { e.stopPropagation(); }
		e.cancelBubble = true;
		
    	if(parseInt(submenus[sm].style.height) > 0) {
				qClose = sm;
				q[0] = true;//action taken in function refreshMenus				
    	} else if (parseInt(submenus[sm].style.height) == 0) { //
				if (collapse_lastmenu == true) {
					//don't collapse lastmenu when it is related... menu 1/submenu 1.1/submenu 1.1.1
					if (isAncestor(submenus[sm], submenus[lastMenu]) != true) {
						if (isAncestor(submenus[lastMenu], submenus[sm]) != true) {
							qClose = lastMenu;
							q[0] = true; //action taken in function refreshMenus
						}
					}
		     	}
				qOpen = sm;
				q[1] = true; //action taken in function refreshMenus
    	}
	}
}

function isAncestor(oElm, oElmTest) {

	if (oElm.className != 'sdmenu') {
		if (oElm == oElmTest) {
			return (true);
		} else {
			return (isAncestor(oElm.parentNode, oElmTest));
		}
	} else {
		return (false);
	}	
}

function expandChildren(oElm) {
	//recursively expand child submenus (that are not hidden) of the given menu element
	//I don't believe this should be needed, but without it the auto-resize/restore function 
	//prevented submenus from being drawn as menus expand.

	var oElmCurrent = oElm.firstChild;

	while (oElmCurrent) {
		if (oElmCurrent.className == "submenu") {
			if (oElmCurrent.style.display != "none") {
				oElmCurrent.style.height = submenuHeight(oElmCurrent)+"px"; 
				expandChildren(oElmCurrent);
			}
		}	
		oElmCurrent = oElmCurrent.nextSibling;
	}
}

function changeHeight(oElm, iDelta) {
	//recursively change the height of the object oElm and its parent until the parent object is 'sdmenu' or the parent not displayed
	//Note: if iDelta is negative, the menu height will be decreased, if it is positive, the menu height will increase.
	var newHeight;

	expandChildren(oElm); //ensure submenus that should be displayed are displayed.
	while ((oElm.className != "sdmenu") && (oElm.style.display != "none")) {
		newHeight = parseInt(oElm.style.height) + iDelta;
		if (newHeight <= 0) {
			oElm.style.height = "0px";
		} else {
    		oElm.style.height = newHeight+"px";
   		}
		var lastElm = oElm;
		oElm = oElm.parentNode;
	}

}

function hidemenu(sm, bStore) {
	var iDelta = submenuChildCount(submenus[sm])*bypixels;

	if (iDelta >= parseInt(submenus[sm].style.height))
		iDelta = Math.floor((parseInt(submenus[sm].style.height)+1)/2);
	
	changeHeight(submenus[sm], -iDelta);

    if(parseInt(submenus[sm].style.height) == 0) {
        titles[sm].className = "titlehidden";
        titletext[sm].className = "tthidden";
        submenus[sm].style.display = "none";
 		if (bStore == true) { store(); }
		//must set q[0] here because this is the only time we know the hiding has finished.
		q[0] = false;
	}
}

function hidemenunow(sm, bStore) {
        //whatever the height is, reduce the height by this much to make it 0, make the same height change to parent elements
        changeHeight(submenus[sm], -parseInt(submenus[sm].style.height));
	    titles[sm].className = "titlehidden";
        titletext[sm].className = "tthidden";
        submenus[sm].style.display = "none";
 		if (bStore == true) store();
		//must set q[0] here because this is the only time we know hidemenu has finished.
		q[0] = false;
}


function submenuChildCount(oElm) {
	var subMenuCC = 0;
	var oElmCurrent = oElm.firstChild;

	while (oElmCurrent) {
		if (oElmCurrent.className == "submenu") {
			if (oElmCurrent.style.display != "none") {
				subMenuCC = subMenuCC + submenuChildCount(oElmCurrent);
			}
		} else if (oElmCurrent.nodeType == 1) { //not submenu so add height of element...
			//nodeType test to skip non-HTML elements, i.e. text nodes
			subMenuCC = subMenuCC + 1;
		}	
		oElmCurrent = oElmCurrent.nextSibling;
	}
	return subMenuCC;
}

function submenuHeight(oElm) {
var th = 0;
var oElmCurrent;

	oElmCurrent = oElm.firstChild;

	while (oElmCurrent) {
		if (oElmCurrent.className == "submenu") {
			if (oElmCurrent.style.display != "none") {
				th = th + submenuHeight(oElmCurrent);
			}
		} else if (oElmCurrent.nodeType == 1) { //not submenu so add height of element...
			//nodeType test to skip non-HTML elements, i.e. text nodes
			th = th + oElmCurrent.offsetHeight;
		}	
		oElmCurrent = oElmCurrent.nextSibling;
	}
	return th;
}

function showmenu(sm, bStore, bRememberLastMenu) {
	
	var iDelta;
	var iChildCount = submenuChildCount(submenus[sm]);

    submenus[sm].style.display = "";
    titles[sm].className = "title";
   	titletext[sm].className = "tt";
	var i = 0;

	var submenuContentHeight = submenuHeight(submenus[sm]);
	iDelta = iChildCount*bypixels;

	if (iDelta >= submenuContentHeight - parseInt(submenus[sm].style.height)) {
		iDelta = Math.floor((submenuContentHeight - parseInt(submenus[sm].style.height)+1)/2);
	}
	changeHeight(submenus[sm], iDelta);
	
    if (parseInt(submenus[sm].style.height) == submenuContentHeight) {
		if ((collapse_topmenus_only != true) || (submenus[sm].parentNode == menu)) { lastMenu = sm; } //remember the appropriate lastmenu
	 	if (bStore == true) { store(); }
		//must set q[1] here because this is the only time we know showmenu has finished.
		q[1] = false;
	}
}

function showmenunow(sm, bStore, bRememberLastMenu) {
    submenus[sm].style.display = "";
    titles[sm].className = "title";
   	titletext[sm].className = "tt";

	//calculate the last iDelta, ie. the difference between the submenu div height and the submenu content height
    var iDelta = submenuHeight(submenus[sm]) - parseInt(submenus[sm].style.height);
    changeHeight(submenus[sm], iDelta);
	if (bRememberLastMenu && ((collapse_topmenus_only != true) || (submenus[sm].parentNode == menu))) { lastMenu = sm; } //remember the appropriate lastmenu
	if (bStore == true) store();
	//must set q[1] here because this is the only time we know the hiding has finished.
	q[1] = false;
}

function store() {
    submenuState = new Array();

    for (var i=0; i<submenus.length; i++) {
		if (submenus[i].style.display == "none" || submenu_haschildren[i] == false) {
			submenuState.push(1);  //collapsed
		} else {
            submenuState.push(0);  //expanded
		}
    }
    putcookie("menu", submenuState.join(","), 30);
}

function getElementsByClassName(strClassName, strTagName, oElm){
    var arrElements = (strTagName == "*" && document.all) ? document.all : oElm.getElementsByTagName(strTagName);
    var arrReturnElements = new Array();
    strClassName = strClassName.replace(/\-/g, "\\-");
    var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
    var oElement;
    for(var i=0; i<arrElements.length; i++){
        oElement = arrElements[i];      
        if(oRegExp.test(oElement.className)){
            arrReturnElements.push(oElement);
        }
    }
    return (arrReturnElements)
}

function putcookie(c_name,value,expiredays) {
    var exdate=new Date();
    exdate.setDate(exdate.getDate()+expiredays);
    document.cookie = c_name + "=" + escape(value) + ((expiredays==null) ? "" : ";expires="+exdate);
}

function getcookie(c_name) {
    if(document.cookie.length > 0) {
        var c_start = document.cookie.indexOf(c_name + "=");
        if(c_start != -1) {
            c_start = c_start + c_name.length + 1;
            var c_end = document.cookie.indexOf(";",c_start);
            if(c_end == -1)
                c_end = document.cookie.length;
            return unescape(document.cookie.substring(c_start, c_end));
        }
    }
    return null;
}
//***********************************************
//* Slashdot Menu script- By DimX
//* Submitted to Dynamic Drive DHTML code library: http://www.dynamicdrive.com
//* Visit Dynamic Drive at http://www.dynamicdrive.com/ for full source code
//***********************************************

//***********************************************
//* May 2007: Modified by Ictinus for nested submenus2 and wrapping menu2 items.
//***********************************************
//* Note: rarely but reproducably a submenu-der can appear to be too long for the links 
//* within it, a slight reduction in width will usually make a link wrap to fill up the space.
//* The browser just isn't calculating the height correctly.
//***********************************************

var remember2 = false; //Remember menu2 states, and restore them on next visit.
//defaultStates2 - An array of zeros and ones (0,1,1,0) that represent open (0) and closed (1) menus.
//if the array is empty, no default state of menu2 will be loaded. if the array has values, but not as many as there are menus, you will be alerted.
var defaultStates2 = new Array(1,0,1,1,1,1,1); 
var contractall_default2 = true; //Should all submenus2 be contracted by default? (true or false)

//NOTE: order or priority for menu2 states is 'remember2' (ie. use cookie), defaultStates2 (if array not empty), 'contractall_default2'

var bypixels2 = 2;   //Basicly it's speed, 
					//but if the (number of submenu-der elements * bypixels2) is larger than the submenu-der height
					//the menu2 will change height by ~50% each step.
var collapse_lastmenu2 = true; //if true, close the last menu2 that was opened if it was not a parent or child menu2.
var collapse_topmenus_only2 = true; //if true, collapse top level menus only; requires collapse_lastmenu2 to be true.
var bInstantMenus2 = false; //if you want the menus to open instantly

var redraw_timeout2 = 30; //milliseconds to menu2 redraw incase of window or font resize.

var bRefreshMenu2 = true; //if true, the submenus2 will be refreshed if needed at the redraw_timeout2 interval.
						 //this allows the menu2 to work with font and window resizing.

var iSubmenuIndent2 = 8; //number of pixels for submenu-der menu2 title indents.
var iSubmenuItemIndent2 = 8; //number of pixels for submenu-der item indent level.

//================= should be no need to configure anything below this line, but feel free to be adventurous ===================================
var menu2, titles2, titletext2, submenus2, bypixels2;
var submenu_haschildren2 = new Array();
var menuWidth2 = 0;
var menuHeight2 = 0;
var lastMenu2 = 0;
var refreshdelay2;
var q2 = new Array();
var qOpen2;
var qClose2;
var submenuState2 = new Array();

function forceRedraw2() {
	if ((q2[0] == false) && (q2[1] == false)) { 
		if ( ( (menuWidth2 != menu2.offsetWidth) || (menuHeight2 != menu2.offsetHeight) ) ) {
			restoreFromCookie2();
		}
	}
}

function refreshmenu2() {

	if (q2[0] == true) {
		(bInstantMenus2) ? hidemenunow2(qClose2, true) : hidemenu2(qClose2, true);
	}
	if (q2[1] == true) {
		(bInstantMenus2) ? showmenunow2(qOpen2, true, true) : showmenu2(qOpen2, true);
	}
	// only redraw the menu2 if we aren't closing or opening a submenu-der
	if ((q2[0] == false) && (q2[1] == false)) {
		//and only do it if the menu2 dimensions have changed
		if ( ( (menuWidth2 != menu2.offsetWidth) || (menuHeight2 != menu2.offsetHeight) ) ) { 
			if (bRefreshMenu2) restoreFromMemory2();
		}
	}
}

function slash_expandall2(bStore2){
	if (typeof menu2!="undefined"){
		for(var i2=submenus2.length-1; i2 >= 0; i2--){
			if (submenu_haschildren2[i2] == true)
				showmenunow2(i2, bStore2, false);
		}
	}
}

function slash_contractall2(bStore2){
	if (typeof menu2!="undefined"){
		for(var i2=0; i2<submenus2.length; i2++){
			hidemenunow2(i2, bStore2);
		}
	}
}

function setSubmenuMargins2(oElm2, currentMargin) {
	var oElmCurrent2 = oElm2.firstChild;
	while (oElmCurrent2) {
		if (oElmCurrent2.className == "submenu-der") {
			setSubmenuMargins2(oElmCurrent2, parseInt(currentMargin) + parseInt(iSubmenuIndent2));
		} else if (oElmCurrent2.nodeType == 1) {//nodeType test to skip non-HTML elements, i2.e. text nodes
			if (oElmCurrent2.nodeName == "A") {
				if ((oElmCurrent2.firstChild.className == "title-der") || (oElmCurrent2.firstChild.className == "titlehidden-der")) {//submenu-der title link
					oElmCurrent2.firstChild.firstChild.style.marginLeft = String(currentMargin) + "px" ;
				} else {//normal menu2 link
					oElmCurrent2.firstChild.style.marginLeft = String(parseInt(currentMargin)+(parseInt(iSubmenuItemIndent2))) + "px" ;
				}
			} else if ((oElmCurrent2.className == "title-der") || (oElmCurrent2.className == "titlehidden-der")) {
				oElmCurrent2.firstChild.style.marginLeft = String(currentMargin) + "px" ;
			}
		}
		oElmCurrent2 = oElmCurrent2.nextSibling;
	}
}

function restoreStates2(arrStates) {
	if (submenus2.length == arrStates.length) {
		for (var i2=arrStates.length-1; i2>=0; i2--) {
			if (arrStates[i2] == 1 || submenu_haschildren2[i2] == false) {
				hidemenunow2(i2, true);
			} else {
				showmenunow2(i2, true, false);
			}
   		} 
	} else {
		if (submenus2.length == defaultStates2.length) {
			restoreStates2(defaultStates2);
		} else if (contractall_default2 == true) {
			slash_contractall2(true);
		} else {
			slash_expandall2(true);
		}
	}
}

function restoreFromMemory2() {

	for (var i2=submenuState2.length-1; i2>=0; i2--) {
		if (submenuState2[i2] == 1) {
			if (parseInt(submenus2[i2].style.height) != 0 || submenu_haschildren2[i2] == false) {
				hidemenunow2(i2, false); // no need to store2 cookie info, it will be the same in the end
			}
		} else {
			if (parseInt(submenus2[i2].style.height) != submenuHeight2(submenus2[i2])) {
				showmenunow2(i2, false, false); // no need to store2 cookie info, it will be the same in the end
			}
		}
   	}
}

function restoreFromCookie2() {
    if (getcookie2("menu2") != null) {
        submenuState2 = getcookie2("menu2").split(",");
		restoreStates2(submenuState2);
    } else {
		restoreStates2(defaultStates2);
	}
	menuWidth2 = menu2.offsetWidth;
	menuHeight2 = menu2.offsetHeight;
}

function gomenu2(e) {
	// if we don't allow multiple menus to be manipulated at the same time, check to see if one is being manipulated
   	if ((q2[0] == true || q2[1] == true) && collapse_lastmenu2 == false) return;

    if (!e) var e = window.event;
    var ce2 = (e.target) ? e.target : e.srcElement;
    var sm2;

	i2 = 0; sm2 = -1;
	while (i2 < titles2.length && sm2 == -1) {
        if(titles2[i2] == ce2 || titletext2[i2] == ce2) sm2 = i2;
		i2++;
    }

    if (submenu_haschildren2[sm2] == true) { //only expand the menu2 if it has sub elements
 		// do not allow the event to bubble up to containing span
		// keep anti-bubble code within "if submenu_haschildren2[sm2] == true"
		if( e.preventDefault ) { e.preventDefault(); }
		e.returnValue = false;
		if( e.stopPropagation ) { e.stopPropagation(); }
		e.cancelBubble = true;
		
    	if(parseInt(submenus2[sm2].style.height) > 0) {
				qClose2 = sm2;
				q2[0] = true;//action taken in function refreshMenus				
    	} else if (parseInt(submenus2[sm2].style.height) == 0) { //
				if (collapse_lastmenu2 == true) {
					//don't collapse lastmenu when it is related... menu2 1/submenu-der 1.1/submenu-der 1.1.1
					if (isAncestor2(submenus2[sm2], submenus2[lastMenu2]) != true) {
						if (isAncestor2(submenus2[lastMenu2], submenus2[sm2]) != true) {
							qClose2 = lastMenu2;
							q2[0] = true; //action taken in function refreshMenus
						}
					}
		     	}
				qOpen2 = sm2;
				q2[1] = true; //action taken in function refreshMenus
    	}
	}
}

function isAncestor2(oElm2, oElmTest) {

	if (oElm2.className != 'sdmenu-der') {
		if (oElm2 == oElmTest) {
			return (true);
		} else {
			return (isAncestor2(oElm2.parentNode, oElmTest));
		}
	} else {
		return (false);
	}	
}

function expandChildren2(oElm2) {
	//recursively expand child submenus2 (that are not hidden) of the given menu2 element
	//I don't believe this should be needed, but without it the auto-resize/restore function 
	//prevented submenus2 from being drawn as menus expand.

	var oElmCurrent2 = oElm2.firstChild;

	while (oElmCurrent2) {
		if (oElmCurrent2.className == "submenu-der") {
			if (oElmCurrent2.style.display != "none") {
				oElmCurrent2.style.height = submenuHeight2(oElmCurrent2)+"px"; 
				expandChildren2(oElmCurrent2);
			}
		}	
		oElmCurrent2 = oElmCurrent2.nextSibling;
	}
}

function changeHeight2(oElm2, iDelta2) {
	//recursively change the height of the object oElm2 and its parent until the parent object is 'sdmenu-der' or the parent not displayed
	//Note: if iDelta2 is negative, the menu2 height will be decreased, if it is positive, the menu2 height will increase.
	var newHeight2;

	expandChildren2(oElm2); //ensure submenus2 that should be displayed are displayed.
	while ((oElm2.className != "sdmenu-der") && (oElm2.style.display != "none")) {
		newHeight2 = parseInt(oElm2.style.height) + iDelta2;
		if (newHeight2 <= 0) {
			oElm2.style.height = "0px";
		} else {
    		oElm2.style.height = newHeight2+"px";
   		}
		var lastElm2 = oElm2;
		oElm2 = oElm2.parentNode;
	}

}

function hidemenu2(sm2, bStore2) {
	var iDelta2 = submenuChildCount2(submenus2[sm2])*bypixels2;

	if (iDelta2 >= parseInt(submenus2[sm2].style.height))
		iDelta2 = Math.floor((parseInt(submenus2[sm2].style.height)+1)/2);
	
	changeHeight2(submenus2[sm2], -iDelta2);

    if(parseInt(submenus2[sm2].style.height) == 0) {
        titles2[sm2].className = "titlehidden-der";
        titletext2[sm2].className = "tthidden-der";
        submenus2[sm2].style.display = "none";
 		if (bStore2 == true) { store2(); }
		//must set q2[0] here because this is the only time we know the hiding has finished.
		q2[0] = false;
	}
}

function hidemenunow2(sm2, bStore2) {
        //whatever the height is, reduce the height by this much to make it 0, make the same height change to parent elements
        changeHeight2(submenus2[sm2], -parseInt(submenus2[sm2].style.height));
	    titles2[sm2].className = "titlehidden-der";
        titletext2[sm2].className = "tthidden-der";
        submenus2[sm2].style.display = "none";
 		if (bStore2 == true) store2();
		//must set q2[0] here because this is the only time we know hidemenu2 has finished.
		q2[0] = false;
}


function submenuChildCount2(oElm2) {
	var subMenuCC2 = 0;
	var oElmCurrent2 = oElm2.firstChild;

	while (oElmCurrent2) {
		if (oElmCurrent2.className == "submenu-der") {
			if (oElmCurrent2.style.display != "none") {
				subMenuCC2 = subMenuCC2 + submenuChildCount2(oElmCurrent2);
			}
		} else if (oElmCurrent2.nodeType == 1) { //not submenu-der so add height of element...
			//nodeType test to skip non-HTML elements, i2.e. text nodes
			subMenuCC2 = subMenuCC2 + 1;
		}	
		oElmCurrent2 = oElmCurrent2.nextSibling;
	}
	return subMenuCC2;
}

function submenuHeight2(oElm2) {
var th2 = 0;
var oElmCurrent2;

	oElmCurrent2 = oElm2.firstChild;

	while (oElmCurrent2) {
		if (oElmCurrent2.className == "submenu-der") {
			if (oElmCurrent2.style.display != "none") {
				th2 = th2 + submenuHeight2(oElmCurrent2);
			}
		} else if (oElmCurrent2.nodeType == 1) { //not submenu-der so add height of element...
			//nodeType test to skip non-HTML elements, i2.e. text nodes
			th2 = th2 + oElmCurrent2.offsetHeight;
		}	
		oElmCurrent2 = oElmCurrent2.nextSibling;
	}
	return th2;
}

function showmenu2(sm2, bStore2, bRememberLastMenu) {
	
	var iDelta2;
	var iChildCount2 = submenuChildCount2(submenus2[sm2]);

    submenus2[sm2].style.display = "";
    titles2[sm2].className = "title-der";
   	titletext2[sm2].className = "tt-der";
	var i2 = 0;

	var submenuContentHeight2 = submenuHeight2(submenus2[sm2]);
	iDelta2 = iChildCount2*bypixels2;

	if (iDelta2 >= submenuContentHeight2 - parseInt(submenus2[sm2].style.height)) {
		iDelta2 = Math.floor((submenuContentHeight2 - parseInt(submenus2[sm2].style.height)+1)/2);
	}
	changeHeight2(submenus2[sm2], iDelta2);
	
    if (parseInt(submenus2[sm2].style.height) == submenuContentHeight2) {
		if ((collapse_topmenus_only2 != true) || (submenus2[sm2].parentNode == menu2)) { lastMenu2 = sm2; } //remember2 the appropriate lastmenu
	 	if (bStore2 == true) { store2(); }
		//must set q2[1] here because this is the only time we know showmenu2 has finished.
		q2[1] = false;
	}
}

function showmenunow2(sm2, bStore2, bRememberLastMenu) {
    submenus2[sm2].style.display = "";
    titles2[sm2].className = "title-der";
   	titletext2[sm2].className = "tt-der";

	//calculate the last iDelta2, ie. the difference between the submenu-der div height and the submenu-der content height
    var iDelta2 = submenuHeight2(submenus2[sm2]) - parseInt(submenus2[sm2].style.height);
    changeHeight2(submenus2[sm2], iDelta2);
	if (bRememberLastMenu && ((collapse_topmenus_only2 != true) || (submenus2[sm2].parentNode == menu2))) { lastMenu2 = sm2; } //remember2 the appropriate lastmenu
	if (bStore2 == true) store2();
	//must set q2[1] here because this is the only time we know the hiding has finished.
	q2[1] = false;
}

function store2() {
    submenuState2 = new Array();

    for (var i2=0; i2<submenus2.length; i2++) {
		if (submenus2[i2].style.display == "none" || submenu_haschildren2[i2] == false) {
			submenuState2.push(1);  //collapsed
		} else {
            submenuState2.push(0);  //expanded
		}
    }
    putcookie2("menu2", submenuState2.join(","), 30);
}

function getElementsByClassName(strClassName, strTagName, oElm2){
    var arrElements2 = (strTagName == "*" && document.all) ? document.all : oElm2.getElementsByTagName(strTagName);
    var arrReturnElements2 = new Array();
    strClassName = strClassName.replace(/\-/g, "\\-");
    var oRegExp2 = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
    var oElement2;
    for(var i2=0; i2<arrElements2.length; i2++){
        oElement2 = arrElements2[i2];      
        if(oRegExp2.test(oElement2.className)){
            arrReturnElements2.push(oElement2);
        }
    }
    return (arrReturnElements2)
}

function putcookie2(c_name,value,expiredays) {
    var exdate=new Date();
    exdate.setDate(exdate.getDate()+expiredays);
    document.cookie = c_name + "=" + escape(value) + ((expiredays==null) ? "" : ";expires="+exdate);
}

function getcookie2(c_name) {
    if(document.cookie.length > 0) {
        var c_start = document.cookie.indexOf(c_name + "=");
        if(c_start != -1) {
            c_start = c_start + c_name.length + 1;
            var c_end = document.cookie.indexOf(";",c_start);
            if(c_end == -1)
                c_end = document.cookie.length;
            return unescape(document.cookie.substring(c_start, c_end));
        }
    }
    return null;
}
