/////////////////////////////////////////////////////////////////////
//
// Global parameters
//
// These parameters control the timing of the popup submenus.
//

// On mouseover, number of milliseconds to wait before opening a submenu,
// if no menu is open already.
var SUBMENU_INIT_DELAY   = 100;

// On mouseexit, number of milliseconds to wait before closing or changing
// a submenu that is already open.
var SUBMENU_CHANGE_DELAY = 300;

/////////////////////////////////////////////////////////////////////
//
// Global state variables
//
// These hold the state of the submenus.  This consists of a
// "current" and "pending" submenu.  Associated with the pending
// submenu is a timer, which counts in milliseconds.
//
// Note that there is, at most, a single pending submenu.
//

// The currently-enabled submenu, or null if there is none.
var submenu_current      = null;

// The pending submenu (displayed when the timer event fires),
// or null if there is none.
var submenu_pending      = null;

// The currently-enabled timer id (for the pending submenu),
// or null if there is none.
var submenu_timer        = null;

/////////////////////////////////////////////////////////////////////
//
// Callback functions
//
// These functions are called from the browser's event loop.
//

// Callback for mouseover events.
//
function submenu_mouseover(id) {
    // If there is no submenu currently displayed, then set the timer
    // to SUBMENU_INIT_DELAY.
    if (submenu_current == null) {
        submenu_set_pending(id, SUBMENU_INIT_DELAY);

    } else if (submenu_current == id) {
        // If this submenu is already displayed, there's nothing to
        // do except cancel any pending submenu.
        submenu_clear_pending();

    } else {
        // If a different submenu is currently displayed, set the timer
        // to SUBMENU_CHANGE_DELAY.
        submenu_set_pending(id, SUBMENU_CHANGE_DELAY);
    }
}

// Callback for mousexit events.
//
function submenu_mousexit(id) {
    if (submenu_current == id) {
        submenu_set_pending(null, SUBMENU_CHANGE_DELAY);
    }
}

// Callback for timer events.
//
function submenu_timer_event() {
    submenu_show_or_hide();
    submenu_timer = null;
}

/////////////////////////////////////////////////////////////////////
//
// State management functions
//
// These manage the state of the submenus.
//

// Set the pending submenu, to be displayed after the given timeout.
//
function submenu_set_pending(id, timeout) {
    submenu_pending = id;
    submenu_set_timer(timeout);
}

// Clear the pending submenu.
//
function submenu_clear_pending() {
    submenu_pending = null;
    submenu_clear_timer();
}

// Set the submenu timer.
//
function submenu_set_timer(timeout) {
    submenu_clear_timer();
    submenu_timer = setTimeout(submenu_timer_event, timeout);
}

// Cancel the pending timer event.
//
function submenu_clear_timer() {
    if (submenu_timer != null) {
        clearTimeout(submenu_timer);
        submenu_timer = null;
    }
}

// Show or hide the submenu, depending on the value of submenu_pending.
//
function submenu_show_or_hide() {

    // If there is already another submenu showing, hide it.
    if (submenu_current != null) {
        hide_submenu(submenu_current);
        submenu_current = null;
    }

    // If there is a submenu pending, enable it.
    if (submenu_pending != null) {
        show_submenu(submenu_pending);
        submenu_current = submenu_pending;
        submenu_pending = null;
    }
}

// Show or hide the submenu by toggling the "disabled" class.
function show_submenu(id) { $(id).removeClass('disabled'); }
function hide_submenu(id) { $(id).   addClass('disabled'); }

/////////////////////////////////////////////////////////////////////
//
// Initialization
//
// Add event handlers to all of the submenuitems and submenus.
// Also replaces <a> submenuitems with <div> elements.
//
window.addEvent('domready', function() {

    // Find all elements with the "submenuitem" class.
    $ES('.submenuitem').each( function(submenuitem) {

        // Nested within the .submenuitem is an <a> link and
        // a element with the "submenu" class.
        var link    = $E('a',        submenuitem);
        var submenu = $E('.submenu', submenuitem);

        // Create mouse-over and -out events that manage the
        // visibility of the submenu.
        var events = {
            'mouseover': submenu_mouseover.pass(submenu.id),
            'mouseout' :  submenu_mousexit.pass(submenu.id)
        };

        // Instead of merely adding events to the existing <a>
        // element, we create a new <div> to replace it.  The
        // submenuitem should only act as a link when Javascript
        // is disabled.
        var new_div = new Element('div', {
            'class'  : 'link',
            'events' : events
        });
        new_div.setText(link.getText());
        link.replaceWith(new_div);

        // Add the mouse events to the submenu as well.  Thus the
        // submenu will stay visible as long as the mouse is over
        // either the submenuitem or the submenu itself.
        submenu.addEvents(events);
    });
});
