// Javascript dealing with expandable menus

var ExpandableMenu = {
    BRANCH_NODE_CLASS: "branchNode",
    LEAF_NODE_CLASS: "leafNode",
    COLLAPSED_BRANCH_NODE_CLASS: "collapsedBranchNode",
    EXPANDED_BRANCH_NODE_CLASS: "expandedBranchNode",
    
    // Attach to menus as given by css selector
    attachByCss: function(menuCss) {
        $$(menuCss).each(
            function (menu) {
                ExpandableMenu.attach(menu);
            }
        );
    },
    
    // Attach to given menu
    attach: function(menu) {
        // Find menu
        menu = $(menu);
        if (menu == null) {
            return;
        }
        
        // Find all nodes
        var nodes = menu.getElementsBySelector("li");
        var nodesByType = nodes.partition(
            function(item) {
                return (item.down("ul") != null);
            }
        );
        
        var branchNodes = nodesByType[0];
        var leafNodes = nodesByType[1];
        
        // Mark all leaf nodes
        leafNodes.each(
            function(leafNode) {
                leafNode.addClassName(ExpandableMenu.LEAF_NODE_CLASS);
            }
        );
        
        // Attach functionality to branch nodes
        branchNodes.each(
            function(branchNode) {
                // Add branch css class
                branchNode.addClassName(ExpandableMenu.BRANCH_NODE_CLASS);
                // Add current state css class
                branchNode.addClassName(ExpandableMenu.EXPANDED_BRANCH_NODE_CLASS);
                // Toggle branch node
                ExpandableMenu.toggleItem(branchNode);
            }
        );
        
        // Listen to click on menu
        menu.observe("click", ExpandableMenu.toggleClick);
    },
    
    // Toggle click occured
    toggleClick: function(event) {
        var eventElement = Event.element(event);
        
        // If click on span take parent element
        // else take clicked element
        var toggleElement;
        if (eventElement.tagName.toLowerCase() == "span") {
            toggleElement = eventElement.up();
        } else {
            toggleElement = eventElement;
        }
        
        // Only toggle if event on branch node itself
        if (toggleElement.hasClassName(ExpandableMenu.BRANCH_NODE_CLASS)) {
            ExpandableMenu.toggleItem(toggleElement);
            Event.stop(event);
        }
    },
    
    // Toggle state of given branch node
    toggleItem: function(branchNode) {
        branchNode = $(branchNode);
        if (ExpandableMenu.isBranchExpanded(branchNode)) {
            branchNode.removeClassName(ExpandableMenu.EXPANDED_BRANCH_NODE_CLASS);
            branchNode.addClassName(ExpandableMenu.COLLAPSED_BRANCH_NODE_CLASS);
        } else {
            branchNode.removeClassName(ExpandableMenu.COLLAPSED_BRANCH_NODE_CLASS);
            branchNode.addClassName(ExpandableMenu.EXPANDED_BRANCH_NODE_CLASS);
        }
    },
    
    // Test if branch is expanded
    isBranchExpanded: function(branchNode) {
        branchNode = $(branchNode);
        return branchNode.hasClassName(ExpandableMenu.EXPANDED_BRANCH_NODE_CLASS);
    }
};

// Attach by css on init
Event.observe(window, "load", function() { ExpandableMenu.attachByCss("ul.expandableMenu"); });