/////////////////////////////////////////////////
// Menuing Controls
//
// By defining behavior in a data structure you
// can register onclick/mouseover/mouseout events
// for anything that gets regsitered with
// register_menu()
//
// Written by Justin Coffey justin@cooleremail.com
// 2008-07-24
/////////////////////////////////////////////////

    //
    // GLOBALS
    //

    var CLASS_MENU_ITEM_ON  = 'on';
    var CLASS_MENU_ITEM_OFF = '';

    //
    // Configure what happens each time a registered menu item is clicked.
    //
    // EXAMPLE:
    //
    //  ID of the menu item in question
    //  menu_item_id : {
    //
    //  location to turn "on" for content
    //      content_id : 'some_target_id',
    //
    //  functions to run when an onclick event is requested:
    //      onclick_funcs : [
    //          [ click_func, 'arg1', 'arg2' ],
    //      ],
    //
    //  functions to run when a mouseover event is requested:
    //      onmouseover_funcs : [
    //          [ mouseover_func, 'arg1', 'arg2' ],
    //      ],
    //
    //  functions to run when a mouseout event is requested:
    //      onmouseout_funcs : [
    //          [ mouseout_func, 'arg1', 'arg2' ],
    //      ],
    //      }
    //
    var CONFIG_FOR_MENU_ITEM_ID = {};

    //
    // END GLOBALS
    //

    //
    // Register detail menu items to use EXEC_MENU_ITEM function
    // for onclick events.
    //
    // ACCEPTS: menu_id, parent_menu_id, parent_item_id
    //
    //  menu_id:         the menu we're registering   (required)
    //  parent_menu_id:  the parent for this menu     (for recursion)
    //  parent_item_id:  the menu item for the parent (for recursion)
    //
    // RETURNS: true
    //
    // Our dynamically generated configuration for menu ids
    //  menu_id : {
    //      default_item_id : item_id,
    //      item_ids        : [ item_id1, item_id2 .. ], 
    //      content_ids     : { content_id1 => 1, content_id2 => 1 .. },
    //      sub_menu_ids    : [ menu_id1, menu_id2 .. ],
    //      parent_item_id  : item_id,
    //      parent_menu_id  : menu_id,
    //
    var CONFIG_FOR_MENU_ID  = {};
    var MENU_ID_FOR_ITEM_ID = {};
    function register_menu( this_menu_id, parent_menu_id, parent_item_id ) {

        //
        // Attempt to get our menu element--it must be a UL tag
        //
        var menu_elem = document.getElementById(this_menu_id);
        if (!menu_elem || menu_elem.tagName != 'UL') return 0;

        // init our config for this menu id
        CONFIG_FOR_MENU_ID[ this_menu_id ] = {
            parent_menu_id  : parent_menu_id,
            parent_item_id  : parent_item_id,
            default_item_id : '',
            item_ids        : [],
            content_ids     : {},
            sub_menu_ids    : []
            };

        //
        // save this menu id to the parent id list
        // -this is our list of "peer" menu ids for
        //  sub menus of a particular parent
        //
        if ( parent_menu_id ) {
            CONFIG_FOR_MENU_ID[ parent_menu_id ][ 'sub_menu_ids' ].push( this_menu_id );
        }

        // get all li tags for this menu, which are its "items"
        var menu_items = menu_elem.getElementsByTagName('li');

        // iterate over each li item, checking to see if it's got
        // any sub menus, as well.
        for (var i=0;i<menu_items.length;i++) {
            var item    = menu_items[i];
            var item_id = item.getAttribute('id');
    
            // register events and content switching for this item
            register_menu_item(this_menu_id,item_id);

            //
            // recurse here to see if this item has any sub menus
            //
            var sub_menu_id = this_menu_id + '_' + item_id;
            register_menu( sub_menu_id, this_menu_id, item_id );
        }
    
        return 1;
    }

    //
    // Register an individual menu item
    //
    function register_menu_item(menu_id,item_id) {

        var item = document.getElementById(item_id);
        if (!item) return;
    
        // register the menu id for this item--to know what should be on
        MENU_ID_FOR_ITEM_ID[ item_id ] = menu_id;

        // add this item to its menus list of items
        CONFIG_FOR_MENU_ID[ menu_id ][ 'item_ids' ].push( item_id );

        // if this item is already on, register it as the default for this menu
        if (item.className == CLASS_MENU_ITEM_ON) {
            CONFIG_FOR_MENU_ID[ menu_id ][ 'default_item_id' ] = item_id;
        }

        //
        // register functions for this item
        //
        item.mouseover  = menu_item_mouseover;
        item.mouseout   = menu_item_mouseout;
        item.onclick    = menu_item_click;

        // save this items target content id to our global list
        if (CONFIG_FOR_MENU_ITEM_ID[ item_id ]) {
            var this_content_id = CONFIG_FOR_MENU_ITEM_ID[ item_id ][ 'content_id' ];
            CONFIG_FOR_MENU_ID[ menu_id ][ 'content_ids' ][ this_content_id ] = 1;
        }

        return 1;
    }

    //
    // Set a menu item "on" (ie assign it and all of it's path members the class of CLASS_MENU_ITEM_ON)
    //
    function turn_on_menu_item( item_id ) {
        //
        // first get the item_id element to see if we've been given a valid id
        //
        var item = document.getElementById(item_id);
        if (!item) return;

        // get our item's menu_id
        var this_menu_id = MENU_ID_FOR_ITEM_ID[ item_id ];
        if (!this_menu_id) return;

        //
        // turn off all menu items (except ours--turn that one on!)
        //
        var item_ids = CONFIG_FOR_MENU_ID[ this_menu_id ][ 'item_ids' ];
        for (var i=0;i<item_ids.length;i++) {
            var this_item_id = item_ids[ i ];
            var this_item    = document.getElementById( this_item_id );

            this_item.className = (this_item_id == item_id) ? CLASS_MENU_ITEM_ON : CLASS_MENU_ITEM_OFF;
        }

        // update the default item id to be what we've just turned on
        CONFIG_FOR_MENU_ID[ this_menu_id ][ 'default_item_id' ] = item_id;

        //
        // turn off all sub menus (except ours--if it exists!)
        //
        var sub_menu_ids = CONFIG_FOR_MENU_ID[ this_menu_id ][ 'sub_menu_ids' ];
        var sub_menu_id  = this_menu_id + '_' + item_id;
        var default_sub_item_id = '';
        for (var i=0;i<sub_menu_ids.length;i++) {
            var this_sub_menu_id = sub_menu_ids[ i ];
            var this_sub_menu    = document.getElementById( this_sub_menu_id );
            
            if (this_sub_menu_id == sub_menu_id) {
                this_sub_menu.className = CLASS_MENU_ITEM_ON;

                // also determine the default on item for this menu
                default_sub_item_id = CONFIG_FOR_MENU_ID[ this_sub_menu_id ][ 'default_item_id' ];
            }
            else {
                this_sub_menu.className = CLASS_MENU_ITEM_OFF;
            }
        }

        // turn on this content id and off all others
        var content_ids     = CONFIG_FOR_MENU_ID[      this_menu_id ][ 'content_ids' ];
        var item_content_id = CONFIG_FOR_MENU_ITEM_ID[ item_id      ][ 'content_id'  ];
        for (var this_content_id in content_ids) {
            var content_elem = document.getElementById( this_content_id );
            content_elem.style.display = (this_content_id == item_content_id) ? 'block' : 'none';
        }

        return default_sub_item_id ? default_sub_item_id : item_id;
    }

    //
    // "Mouseover" a menu item
    //
    function menu_item_mouseover() {
    }

    //
    // "Mouseout" of a menu item
    //
    function menu_item_mouseout() {
    }

    //
    // "Click" a menu item
    //
    function menu_item_click() {
        //
        // get our element's id so we can determine input
        //
        var item_id = this.getAttribute('id');

        //
        // set this menu item (ie turn it on and others off)
        // -this returns the actual item id turned on
        //  which in the event of a sub-menu item may
        //  not be the item clicked on
        item_id = turn_on_menu_item( item_id ) || item_id;

        //
        // get our click functions
        //
        var onclick_funcs = CONFIG_FOR_MENU_ITEM_ID[ item_id ][ 'onclick_funcs' ];
        if (!onclick_funcs) return 1;

        //
        // execute each function in order
        //
        for (var i=0;i<onclick_funcs.length;i++) {
            var this_func_data  = onclick_funcs[i].slice();
            var this_func       = this_func_data.shift();

            // execute function
            this_func.apply(this,this_func_data);
        }

        return 1;
    }

//
// END MENU CONFIGURATION/CONTROL
// 
