// menu2.js - rewrite of the menu system to use semantic markup
// uses jquery instead of mochikit

// when we mouse over an element, the child should be shown, and 
// all parents should be recursively shown, which means cancelling their hide timeouts

// TODO: 
// - sibling menu_uls must be closed instantly when a menu is shown
// fix borders
// remove unused attributes from the genshi macro


// duration of the hiding timeout
var hide_timeout_dur = 400;

// dict for the menu timeouts, key is the menu node id 
var menu_timeouts = new Array();

// menu_mouseover must show child ul.menu_lists and themselves
function menu_mouseover(evt){
    var menu_li = evt.src();
    //log("MENU_MOUSEOVER, menu_li: ", menu_li );
    var menu_ul = $(menu_li).parent('ul.menu_list')[0];
    //log("MENU_MOUSEOVER, menu_li:", menu_li.id, " menu:", menu_ul.id );
  
    // show menu_ul for this item, in case this menu is timing out
    if( menu_ul && window.menu_timeouts[ menu_ul.id ] ){
        //log('  - cancelling timeout for menu_ul: ', menu_ul.id );
        window.clearTimeout( window.menu_timeouts[ menu_ul.id ] );
    }
    // get the ul element that is the child menu of this node and show it
    // show_menu will also close all siblings right away
    var menu_child_ul = $(menu_li).children('ul.menu_list')[0];
    if( menu_child_ul ){
        //log("  - calling show_menu() for menu_child_ul: ", menu_child_ul.id );
        position_menu(menu_child_ul, menu_ul, menu_li);
        show_menu(menu_child_ul); 
    }
    // show the ancestors for this one too
    //log("  - calling show_menu_ancestors() for menu_ul: ", menu_ul.id );
    show_menu_ancestors( menu_ul );
}

// mouseout needs to hide menu lists that should not be showing
function menu_mouseout(evt){
    var menu_li = evt.src();
    //log("MENU_MOUSEOUT, menu_li:", menu_li.id);

    // find the menu_ul that is a child of this menu element and hide it
    var menu_child_ul = $(menu_li).children('ul.menu_list')[0];
    if( menu_child_ul ){
        //log('  - calling hide_menu() on child menu:', menu_child_ul.id );
        hide_menu(menu_child_ul);
    }
    // add a timeout to hide this menu if it's a submenu
    var menu_ul = $(menu_li).parent('ul.menu_list')[0];
    if( menu_ul && $(menu_ul).hasClass('sub_menu') ){
        hide_menu( menu_ul );
    }
    // recursively hide any menu ancestors that are sub_menus
    hide_menu_ancestors( menu_ul );
}

// show a menu list, this will contain the timeout manipulation too
function show_menu( menu_ul ){
    //log('SHOW_MENU() menu_ul:', menu_ul.id );
    
    // close sibling menus right away!
    var parent_menu = $(menu_ul).parent('li.menu_item').parent('ul.menu_list');
    var sibling_menus = $(parent_menu).children('li.menu_item').children('ul.menu_list');
    //var sibling_menus = $(menu_ul).parent('li').parent('ul').children('li').children('ul');
    $(sibling_menus).addClass('hidden');
    
    // if there is a timeout running for this menu, cancel it
    if( window.menu_timeouts[menu_ul.id] ){
        //log(" - cancelling timeout for menu_ul:", menu_ul.id );
        window.clearTimeout( window.menu_timeouts[ menu_ul.id] );
    }
    // if this is a sub_menu, position it relative to the parent menu

    // if this menu has hidden class, remove it, 
    // this happens last to negate the sibling close
    //log(' - removing class hidden from menu_ul:', menu_ul.id);
    $(menu_ul).removeClass('hidden');
}

// recursively show all the ancestor menus of a given menu ul
function show_menu_ancestors( menu_ul ){
    //log('SHOW_MENU_ANCESTORS(), menu_ul:', menu_ul.id );
    // get the parent menu ul of this menu ul 
    var parent_menu_ul = $(menu_ul).parent('li.menu_item').parent('ul.menu_list')[0];
    
    if( parent_menu_ul && $(parent_menu_ul).hasClass('sub_menu') ){
        //log(' - removing timeout and hidden for menu_ul:', parent_menu_ul.id );
        if( window.menu_timeouts[ parent_menu_ul.id ] ){  
            window.clearTimeout( window.menu_timeouts[ parent_menu_ul.id ] );
        }
        $(parent_menu_ul).removeClass('hidden');
        //log('  - recursing up show_menu_ancestors() for menu_ul:', parent_menu_ul.id );
        // recurse up the ancestors
        show_menu_ancestors( parent_menu_ul );
    }
}

// hide a menu list, this will contain the timeout manipulation too
function hide_menu( menu_ul ){
    //log('HIDE_MENU(), menu_ul:', menu_ul.id );
    // callback closure function to hide the menu_ul
    var cb_hide = function(){ 
        if( !$(menu_ul).hasClass('hidden') ) $( menu_ul ).addClass('hidden');
    }    
    // if there is already a timeout for this menu clear it
    if( window.menu_timeouts[menu_ul.id] ){ 
        window.clearTimeout( window.menu_timeouts[menu_ul.id] );
    }
    // now add the new time out to hide this menu 
    window.menu_timeouts[menu_ul.id] = window.setTimeout( cb_hide, hide_timeout_dur ); 
}

// recursively show all the ancestor menus of a given menu ul
function hide_menu_ancestors( menu_ul ){
    //log('HIDE_MENU_ANCESTORS(), menu_ul:', menu_ul.id );
    // get the parent menu ul of this menu ul 
    var parent_menu_ul = $(menu_ul).parent('li.menu_item').parent('ul.menu_list')[0];
   
    // if it's a submenu it gets hidden
    if( parent_menu_ul && $(parent_menu_ul).hasClass('sub_menu') ){
        hide_menu( parent_menu_ul );
        // recurse up the tree to hide more parents
        hide_menu_ancestors( parent_menu_ul );
    }
}

function position_menu( menu_ul, parent_menu_ul, parent_menu_li ){
    //log('POSITION_MENU()');
   
    // depth of 1
    if( $(menu_ul).hasClass('depth-1') ){
        var anchor = document.getElementById('outer_container');
        var parent_pos = getElementPosition( parent_menu_li, anchor );
        //log("position of parent: ", parent_menu_li.id, " : ", parent_pos);
        var new_pos = { x: parent_pos.x + 10, y: parent_pos.y + 20 }
        //log('depth 1 new_pos:', new_pos);
    // depth > 1 
    }else{
        var parent_pos = getElementPosition( parent_menu_li, parent_menu_ul );
        //log("position of parent: ", parent_menu_li.id, " : ", parent_pos);
        var new_pos = { x: parent_pos.x + 80, y: parent_pos.y + 15 }
        //log('depth > 1 new_pos:', new_pos);
    }    
    //log("setting position for ", menu_ul.id );
    setElementPosition( menu_ul, new_pos );
}


function menu_initialize(){
    //log("menu_initialize() running");

    function connect_mouseover( el ){ connect( el, 'onmouseover', el, menu_mouseover ); } 
    map( connect_mouseover, getElementsByTagAndClassName( "li", "menu_item" ) );
    function connect_mouseout( el ){ connect( el, 'onmouseout', el, menu_mouseout ); } 
    map( connect_mouseout,  getElementsByTagAndClassName( "li", "menu_item" ) );
}




