/*
 * Expandable unordered list implementation.
 * by David Lindquist <first name><at><last name><dot><net>
 * See:
 * http://www.gazingus.org/html/DOM-Scripted_Lists_Revisited.html
 * Modifies unordered lists so that sublists can be hidden and shown
 * by means of a switch. The switch is a node inserted into the DOM
 * tree as the first child of the list item containing the sublist.
 */

// The script will only be applied to unordered lists containing
// this class name, e.g.: <ul class="foo expandable">...</ul>.
var CLASS_NAME = "expandable";

// This value is the assumed initial display style for a sublist
// when it cannot be determined by other means. See below.
var DEFAULT_DISPLAY = "none";

// The namespace to use when using this script in an XML context.
var XMLNS = "http://www.w3.org/1999/xhtml";

function initExpandableLists() {
    if (!document.getElementsByTagName) return;

    // Top-level function to accommodate browsers that do not register
    // a click event when a link is activated by the keyboard.
    switchNode = function(id) {
        var node = document.getElementById(id);
        if (node && /^switch /.test(node.className)) node.onclick();
    }

    // Top-level function to be assigned as the event handler for the
    // switch. This could have been bound to the handler as a closure,
    // but closures are associated with memory leak problems in IE.
    actuate = function() {
        var sublist = this.parentNode.getElementsByTagName("ul")[0];
        if (sublist.style.display == "block") {
            sublist.style.display = "none";
            this.firstChild.data = "+";
            this.className = "switch off";
            this.title = this.title.replace("collapse", "expand");
        } else {
            sublist.style.display = "block";
            this.firstChild.data = "-";
            this.className = "switch on";
            this.title = this.title.replace("expand", "collapse");
        }
        return false;
    }

    // Create switch node from which the others will be cloned.
    if (typeof document.createElementNS == "function")
        var template = document.createElementNS(XMLNS, "a");
    else
        var template = document.createElement("a");
    template.appendChild(document.createTextNode(" "));

    var list, i = 0;
    var pattern = new RegExp("(^| )" + CLASS_NAME + "( |$)");

    while ((list = document.getElementsByTagName("ul")[i++])) {
        // Only lists with the given class name are processed.
        if (pattern.test(list.className) == false) continue;

        var item, j = 0;
        while ((item = list.getElementsByTagName("li")[j++])) {
            var sublist = item.getElementsByTagName("ul")[0];
            // No sublist under this list item. Skip it.
            if (sublist == null) continue;

            // Attempt to determine initial display style of the
            // sublist so the proper symbol is used.
            var symbol;
            switch (sublist.style.display) {
            case "none" : symbol = "+"; break;
            case "block": symbol = "-"; break;
            default:
                var display = DEFAULT_DISPLAY;
                if (sublist.currentStyle) {
                    display = sublist.currentStyle.display;
                } else if (document.defaultView &&
                           document.defaultView.getComputedStyle &&
                           document.defaultView.getComputedStyle(sublist, ""))
                {
                    var view = document.defaultView;
                    var computed = view.getComputedStyle(sublist, "");
                    display = computed.getPropertyValue("display");
                }
                symbol = (display == "none") ? "+" : "-";
                // Explicitly set the display style to make sure it is
                // set for the next read. If it is somehow the empty
                // string, use the default value from the (X)HTML DTD.
                sublist.style.display = display || "block";
                break;
            }

            var actuator = template.cloneNode(true);
            var uid = "switch" + i + "-" + j; // a reasonably unique ID
            actuator.id = uid;
            actuator.href = "javascript:switchNode('" + uid + "')";
            actuator.className = "switch " + ((symbol == "+") ? "off" : "on");
            actuator.title = ((symbol == "+") ? "expand" : "collapse") + " list";
            actuator.firstChild.data = symbol;
            actuator.onclick = actuate;
            item.insertBefore(actuator, item.firstChild);
        }
    }
}

// Props to Simon Willison:
// http://simon.incutio.com/archive/2004/05/26/addLoadEvent
var oldhandler = window.onload;
window.onload = (typeof oldhandler == "function")
    ? function() { oldhandler(); initExpandableLists(); } : initExpandableLists;
