/*
 * aqdd2.js, adapted by D. Wolverton from aqdd.js
 *    - supports menu bars (class="Menubar") and vertical menus (class="Navbar")
 *    - enhanced to mark leaf nodes with class "leaf"
 */

/*
aqdd.js

Converts an unordered list to a pulldown menu bar

To make this work, simply add one line to your HTML:
<script type="text/javascript" src="aqdd.js"></script>

and then make the top UL of your nested unordered list of class "aqdd".

That's it. No registration function, nothing.

http://www.kryogenix.org/code/browser/aqlists/

Stuart Langridge, November 2002
sil@kryogenix.org

Inspired by Aaron's labels.js (http://youngpup.net/demos/labels/) and Dave Lindquist's menuDropDown.js (http://www.gazingus.org/dhtml/?id=109)

*/

addEvent(window, "load", makeDDs);

function makeDDs() {
    // We don't actually need createElement, but we do
    // need good DOM support, so this is a good check.
    if (!document.createElement) return;
    
    uls = document.getElementsByTagName("ul");
    for (uli=0; uli<uls.length; uli++) {
        ul = uls[uli];
        if (ul.nodeName == "UL") {
            if (ul.className == "Menubar") {
                processULDD(ul,0,1);
            } else if (ul.className == "Navbar") {
                processULDD(ul,0,0);
            } else {
                // ignore
            }
        }
    }
}

function processULDD(ul,isSubUL,isMenubar) {
    if (!ul.childNodes || ul.childNodes.length == 0) return;
    // Iterate through LIs, which are menu headers in the menu bar
    for (var itemi=0; itemi<ul.childNodes.length; itemi++) {
        var item = ul.childNodes[itemi];
        if (item.nodeName == "LI") {
            // Iterate things in this LI: should be an A and a UL
            var a = null;
            var subul = null;
            for (var sitemi=0; sitemi<item.childNodes.length; sitemi++) {
                var sitem = item.childNodes[sitemi];
                switch (sitem.nodeName) {
                    case "A":
                        a = sitem;
                        break;
                    case "UL":
                        subul = sitem; 
                        processULDD(subul,1,isMenubar);
                        break;
                }
            }
            if (subul) {
                associateDD(a,subul);
                subul.style.display = "none";
                if (isSubUL) {
                    // this is a UL that is in a list
                    // and it has subuls of its own, which means that
                    // it's the head of a submenu
                    a.className += " submenuheader";
                    // make the submenu appear to the right of this one
                    subul.style.left = item.offsetLeft+item.offsetWidth+"px";
                    subul.style.top = item.offsetTop+"px";
                    subul.style.width = "200px";
                } else {
                    // this is the top level UL
                    // make this submenu appear *below* (or to the right of) this LI
                    if (isMenubar) {
                        subul.style.left = DL_GetElementLeft(a)+"px";
                        subul.style.top = (DL_GetElementTop(a)+a.offsetHeight)+"px";
                    } else { // Navbar
                        subul.style.left = (DL_GetElementLeft(a)+a.offsetWidth)+"px";
                        subul.style.top = DL_GetElementTop(a)+"px";
                    }
                }
            } else {
                // it is a leaf
                item.className += " leaf";
            }
        }
    }
}

function associateDD(a,ul) {
    a.onclick = function () {
	if (ul.style.display == "none") {
	    // Walk tree to get top level UL, saving ancestors
	    ancestors = []
	    cn = ul;
	    do {
	        if (cn.nodeName == "UL") ancestors[ancestors.length] = cn;
		  cn = cn.parentNode;
	    } while (cn.className != "Menubar" && cn.className != "Navbar")
	    // Undisplay all its children ULs
	    hideChildren(cn,cn);
	    cn.style.display = "block";
	    // Display all ul's ancestor uls, including ul itself
	    for (var idx=0; idx < ancestors.length; idx++) {
	        ancestors[idx].style.display = "block";
	    }
          a.onblur = function () {
              // hideChildren(ul,ul); ul.style.display = "none";
          }
	} else {
	    // Undisplay all ul's children uls
	    hideChildren(ul,ul);
	    // Undisplay ul itself
	    ul.style.display = "none";
          a.onblur = null;
	}
      return false;
    }
}

function hideChildren(nd,toplevel) {
    // Walk all of nd's children, and hide all ULs we find
    if (nd.childNodes && nd.childNodes.length > 0) {
        for (var ndi=0; ndi<nd.childNodes.length; ndi++) {
	    hideChildren(nd.childNodes[ndi],toplevel);
	}
    }
    if (nd.nodeName == "UL" && nd != toplevel) nd.style.display = "none";
}

/*              Utility functions                    */

function addEvent(obj, evType, fn){
  /* adds an eventListener for browsers which support it
     Written by Scott Andrew: nice one, Scott */
  if (obj.addEventListener){
    obj.addEventListener(evType, fn, true);
    return true;
  } else if (obj.attachEvent){
    return obj.attachEvent("on"+evType, fn);
  } else {
    return false;
  }
}

// DL_* functions from DHTML Diner:
// http://www.webreference.com/dhtml/diner/realpos1/
function DL_GetElementLeft(eElement)
{
    var nLeftPos = eElement.offsetLeft;
    var eParElement = eElement.offsetParent;  
    while (eParElement != null)
    { 
        nLeftPos += eParElement.offsetLeft;     
        eParElement = eParElement.offsetParent; 
    }
    return nLeftPos;                         
}

function DL_GetElementTop(eElement)
{
    var nTopPos = eElement.offsetTop;    
    var eParElement = eElement.offsetParent;
    while (eParElement != null)
    {                                    
        nTopPos += eParElement.offsetTop;      
        eParElement = eParElement.offsetParent; 
    }
    return nTopPos;                        
}



