function getSublist(item) {
    if (item.tagName == 'OL' || item.tagName == 'UL') return item;
    var nodes = item.childNodes;
    for (var i = 0; nodes[i]; i++) {
        if (nodes[i].tagName == 'OL' || nodes[i].tagName == 'UL') {
            return nodes[i];
        }
    }
}

function getSubitems(item) {
    var list = getSublist(item);
    var results = [];
    if (list) {
        var nodes = list.childNodes;
        for (var i = 0; nodes[i]; i++) {
            if (nodes[i].tagName == 'LI') results.push(nodes[i]);
        }
    }
    return results;
}

function isOpen(item) {
    return getSublist(item).style.display != 'none';
}

function setOpen(item, open, propagate) {
    var list = getSublist(item);
    if (list) {
        list.style.display = open ? 'block' : 'none';
        var button = item.getElementsByTagName('IMG')[0];
        button.src = open ? 'open.png' : 'closed.png';
        if (propagate) {
            var items = getSubitems(item);
            for (var i = 0; items[i]; i++) setOpen(items[i], open, propagate);
        }
    }
}

function setupDisclosure(root) {
    var activeItem = null, activeButton = null, propagate = false;

    var frames = ['open-dark.png', 'opening-dark.png',
                  'closing-dark.png', 'closed-dark.png'];
    var frame, direction;

    for (var i = 0; frames[i]; i++) new Image().src = frames[i];

    function press(event) {
        event.preventDefault();
        activeItem = activeButton = event.target;
        propagate = event.shiftKey;
        while (activeItem.tagName != 'LI') activeItem = activeItem.parentNode;
        activeButton.src = isOpen(activeItem) ?
            'open-dark.png' : 'closed-dark.png';
    }

    function release(event) {
        if (activeItem) {
            activeButton.src = isOpen(activeItem) ? 'open.png' : 'closed.png';
            activeItem = activeButton = null;
        }
    }

    function toggle(event) {
        event.stopPropagation();
        if (event.target == activeButton) {
            direction = isOpen(activeItem) ? 1 : -1;
            frame = direction > 0 ? 0 : 3;
            advance();
        } else release(event);
    }

    function advance() {
        activeButton.src = frames[frame];
        frame = frame + direction;
        if (frames[frame]) setTimeout(advance, 40);
        else {
            setOpen(activeItem, direction < 0, propagate);
            activeItem = activeButton = null;
        }
    }

    var items = root.getElementsByTagName('LI');
    for (var i = 0; items[i]; i++) {
        if (getSublist(items[i])) {
            button = document.createElement('img');
            button.className = 'disclosure';
            button.src = 'open.png';
            button.addEventListener('mousedown', press, false);
            button.addEventListener('mouseup', toggle, false);
            items[i].insertBefore(button, items[i].firstChild);
        }
    }

    var body = document.getElementsByTagName('BODY')[0];
    body.addEventListener('mouseup', release, false);
}

