/**
* @author pop webdev [cn] + [kh]
* @version: 0.4.1
* @classDescription: Handles flyout / meganav
* @dependencies: Prototype v1.6.1
*/
var FlyoutNav = Class.create({
    initialize: function (triggers, targets, options) {

        var triggers = $$(triggers);
        this.triggers = [];
        this.targets = $$(targets);

        this.options = Object.extend({
            animationDuration: 0.2, // time (in seconds) it takes for the appear animation to complete
            appearDelay: 0.2, // time (in seconds) to wait before starting appear effect
            fadeOutDelay: 0.5, // time (in seconds) to wait before starting fade out effect
            triggerClassName: 'hover', // add class name to triggers 
            targetClassName: 'mn' // target class names
        }, options || {});

        this.targets.invoke('hide'); // display block with CSS then hide via JS

        for (var i = 0; i < triggers.length; i++) {
            // make sure that the trigger actually has a mega dropdown... might not always be the case
            if (triggers[i].select(targets).length > 0) {
                this.triggers.push(triggers[i]);
                triggers[i].observe('mouseenter', this.__mouseEnter.bindAsEventListener(this));
                triggers[i].observe('mouseleave', this.__mouseLeave.bindAsEventListener(this));
            }
        }

    },

    // handle mouse enter events
    __mouseEnter: function (e) {
        var el = e.findElement('li');
        clearTimeout(this.fadeDelay); // clear out any existing fadeOut delays
        var appearDelay = this.options.appearDelay * 1000; // convert to milliseconds
        this.appearDelay = setTimeout(function () {
            this.showNav(el);
        }.bind(this), appearDelay);
    },

    // handle mouse leave events
    __mouseLeave: function (e) {
        var el = e.findElement('li');
        clearTimeout(this.appearDelay); // clear out appear delays
        var fadeOutDelay = this.options.fadeOutDelay * 1000; // convert to milliseconds
        this.fadeDelay = setTimeout(function() {
            this.hideNav(el);
        }.bind(this), fadeOutDelay);
        
    },

    // show dropdowns, by fading it in 
    showNav: function (el) {

        var index = this.triggers.indexOf(el);
        var target = this.targets[index];

        this.triggers.invoke('removeClassName', this.options.triggerClassName);
        el.addClassName(this.options.triggerClassName);
        if (this.fadeFx && this.fadeFx.state != 'finished') {
            this.fadeFx.cancel();
        }
        if (this.appearFx && this.appearFx.state != 'finished') {
            // cancel appear effect
            if (this.appearFx) {
                this.appearFx.cancel();
            }
            if (target) {
                target.hide();
            }
        }
        this.targets.without(target).invoke('hide');
        // make sure target actually exists, then create effect
        if (target) {
            this.appearFx = new Effect.Appear(target, {
                duration: this.options.animationDuration,
                queue: {
                    position: 'front',
                    scope: 'flyout',
                    limit: 2
                }
            });
        }


    },

    // hide the dropdowns, by fading it out
    hideNav: function (el) {

        var index = this.triggers.indexOf(el);
        var target = this.targets[index];

        if (this.appearFx && this.appearFx.state == 'finished') {
            if (this.appearFx) {
                this.appearFx.cancel();
            }
        }
        if (target) {
            this.fadeFx = new Effect.Fade(target, {
                duration: 0.01,
                afterFinish: function (e) {
                    this.targets.invoke('hide'); // hide all targets, just in case
                    this.triggers.invoke('removeClassName', this.options.triggerClassName); // remove all trigger class names
                } .bind(this)
            });
        }

    }
});
