/**
 * The "dropdown" plugin is used for doing a slide up / down dropdown
 * navigation with a delay.
 */
function Dropdown(elements, dropdown, delay) {
    this.elements = elements;
    this.dropdown = dropdown;
    this.delay = delay;

    this.elements.data('dropdown', 0);
    this.elements.mouseover(this.handler('mouseover'));
    this.elements.focusin(this.handler('mouseover'));
    this.elements.mouseout(this.handler('mouseout'));
    this.elements.focusout(this.handler('mouseout'));
}

Dropdown.prototype.handler = function(methodName) {
    var this_ = this;
    function inner(e) {
        this_[methodName](this, e);
    }
    return inner;
}

Dropdown.prototype.clearTimeout = function() {
    jQuery.each(this.elements, function(index, value) {
        var elem = jQuery(value);
        var timeout = elem.data()['dropdown'];
        if (timeout) {
            clearTimeout(timeout);
        }
    });
}

Dropdown.prototype.mouseover = function(element, e) {
    var elem = jQuery(element);
    var dropdown = elem.find(this.dropdown);
    // cancel the animation for all the other dropdowns that are waiting
    // to appear or disappear
    this.clearTimeout();

    // if the dropdown is already visible, no need to do anything
    if (dropdown.find(':visible').length > 0) {
        return;
    }

    var dropdowns = this.elements.find(this.dropdown);
    var elements = this.elements;
    function slide() {
        // hide other dropdowns before showing this one
        dropdowns.fadeOut('fast');
        elements.removeClass('expanded');
        elements.find('a.level1').removeClass('expanded');

        dropdown.slideDown('medium');
        elem.addClass('expanded');
        elem.find('a.level1').addClass('expanded');
        jQuery('#overlay').fadeIn('slow');
        elem.trigger('afterslidedown');
    }
    // set a delay before sliding down the dropdown
    var timeout = setTimeout(slide, this.delay);
    elem.data('dropdown', timeout);
}

Dropdown.prototype.mouseout = function(element, e) {
    var elem = jQuery(element);
    var dropdown = elem.find(this.dropdown);
    // cancel the animation for all the other dropdowns that are waiting
    // to appear or disappear
    this.clearTimeout();

    // if the dropdown is not visible, no need to do anything
    if (dropdown.find(':visible').length == 0) {
        return;
    }

    function slide() {
        dropdown.slideUp('medium');
        elem.removeClass('expanded');
        elem.find('a.level1').removeClass('expanded');
        jQuery('#overlay').fadeOut('slow');
        elem.trigger('afterslideup');
    }
    // set a delay before sliding up the dropdown
    var timeout = setTimeout(slide, this.delay);
    elem.data('dropdown', timeout);
}

jQuery.fn.dropdown = function(dropdown, delay) {
    new Dropdown(this, dropdown, delay);
    return this;
}

