/*
    Behaviours for the Drop Down boxes used in the site - particularly in the header.

    Note these are also used for the options lists in the rich select widgets
*/

Site.Widgets.DropDown = Class.create
(
    Site.Base,
    {
        initialize: function($super, button, dropDown, options)
        {
            $super();
            
            this.button = button;
            this.dropDown = dropDown;
            
            this.setOptions
            (
                options,
                {
                    showDuration: Site.DEFAULT_SHOW_DURATION,
                    hideDuration: Site.DEFAULT_HIDE_DURATION,
                    hideDelay: 250, /* how long to wait after a mouse out before the dropdown is hidden */
                    hideOnDocumentClick: true,
                    hideOnButtonMouseOut: true,
                    hideOnDropDownMouseOut: true,
                    buttonActiveClassName: "active" /* this class will be added to the button when the dropdown is visible */
                }
            );
            
            this.addObservers("_onClick", "_onMouseOver", "_onMouseOut", "_documentOnClick");
            this.addBlocks("_afterShow", "_afterHide", "hideDropDown");
            
            if (this.options.hideOnDocumentClick)
            {
                // make a document click also hide the dropDown
                addEvent(document, "click", this.observers._documentOnClick);
            }
            
            this._setup();
        },
        
        showDropDown: function()
        {
            //this.dropDown.fire("dropDown:beforeShow");
            this.open = true;
            
            this.button.addClassName(this.options.buttonActiveClassName);
            
            if (this.options.showDuration > 0)
            {
                this._animating = true;
                new Effect.Appear(this.dropDown, { duration: this.options.showDuration, afterFinish: this.blocks._afterShow } );
            }
            else
            {
                this.dropDown.show();
                this._afterShow();
            }
        },
        
        hideDropDown: function()
        {
            //this.dropDown.fire("dropDown:beforeHide");
            this.open = false;
            
            if (this.options.hideDuration > 0)
            {
                this._animating = true;
                new Effect.Fade(this.dropDown, { duration: this.options.hideDuration, afterFinish: this.blocks._afterHide } );
            }
            else
            {
                this.dropDown.hide();
                this._afterHide();
            }

        },
        
        /* 
            Pseudo-private methods 
        */
        
        _setup: function()
        {
            // setup events
            addEvent(this.button, "click", this.observers._onClick);
            
            if (this.options.hideOnButtonMouseOut)
            {
                addEvent(this.button, "mouseout", this.observers._onMouseOut);
            }
            
            addEvent(this.button, "mouseover", this.observers._onMouseOver);

            if (this.options.hideOnDropDownMouseOut)
            {
                addEvent(this.dropDown, "mouseout", this.observers._onMouseOut);
                addEvent(this.dropDown, "mouseover", this.observers._onMouseOver);
            }
        },

        _afterHide: function()
        {
            this._animating = false;
            //this.dropDown.fire("dropDown:afterHide");
            if(this.button)this.button.removeClassName(this.options.buttonActiveClassName);
        },
        
        _afterShow: function()
        {
            this._animating = false;
            //this.dropDown.fire("dropDown:afterShow");
        },

        /*
            Event observers
        */
        
        _documentOnClick: function()
        {
            this.hideDropDown();
        },
        
        _onClick: function(event)
        {     
            //debugger;
            
            if (!this._animating)
            {
                if (this.open)
                    this.hideDropDown();
                else
                    this.showDropDown();                
            }
            
            var element = Event.element(event);
            
            if (element.blur)
                element.blur();
            
            Event.stop(event);
        },

        _onMouseOut: function(event)
        {
            this.hideTimeout = window.setTimeout(this.blocks.hideDropDown, this.options.hideDelay);
        },
        
        _onMouseOver: function(event)
        {
            // cancel any hide timeouts caused by mousing out of the button
            if (this.hideTimeout)
                window.clearTimeout(this.hideTimeout);
        },
        
        destroy: function()
        {
            this._animating = null;
            
            if (this.options.hideOnDocumentClick)
            {
                removeEvent(document, "click", this.observers._documentOnClick);
            }
            
            removeEvent(this.button, "click", this.observers._onClick);
            
            if (this.options.hideOnButtonMouseOut)
            {
                removeEvent(this.button, "mouseout", this.observers._onMouseOut);
            }
            
            removeEvent(this.button, "mouseover", this.observers._onMouseOver);

            if (this.options.hideOnDropDownMouseOut)
            {
                removeEvent(this.dropDown, "mouseout", this.observers._onMouseOut);
                removeEvent(this.dropDown, "mouseover", this.observers._onMouseOver);
            }
        }
    }
);
