/*
== This is a base for creating a simple quick expanding box. You get callbacks for after a collapse, after an expand and onStart of either action.
== TODO: Make it figure out the initial height of the box instead of requiring it to be specified.
*/
Fx.Expando = Class.create({
    initialize: function(options) {
        // element to expand
        this.expandoElement = $(options.expandoElement) || $$(options.expandoSelector)[0];
        // element to listen for events and toggle expansion
        this.toggleElement = $(options.toggleElement) || $$(options.toggleSelector)[0];
        // classname for when the element is expanded
        this.expandedClass = options.expandedClass || 'expanded';
        // classname for when the element is collapsed
        this.collapsedClass = options.collapsedClass || 'collapsed';
        // callback for after it's done expanding
        this.onExpandComplete = options.onExpandComplete || Prototype.emptyFunction;
        // callback for after it's done collapsing
        this.onCollapseComplete = options.onCollapseComplete || Prototype.emptyFunction;
        // callback for prior to it starting an action
        this.onStart = options.onStart || Prototype.emptyFunction;
        // callback function to occur just before starting the collapse effect
        this.onBeforeCollapse = options.onBeforeCollapse || Prototype.emptyFunction;
        // callback function to occur just before starting the collapse effect
        this.onBeforeExpand = options.onBeforeExpand || Prototype.emptyFunction;
        // how long should it do the effect for
        this.duration = options.duration || 500;
        // how tall it should be when it's expanded
        this.expandedHeight = options.expandedHeight;
        // how tall it should be when collapsed
        this.collapsedHeight = options.collapsedHeight || 0;
        // Auto set expandedHeight if none set and we have a valid element
        if (!this.expandedHeight) {
            this.expandedHeight = this.expandoElement && $(this.expandoElement).getHeight();
        }
        // new fx junk
        this.fx = new Fx.Style(this.expandoElement, "height", {
            options: { duration: this.duration, wait: true },
            onStart: this.onStart
        });
        // listen
        if (!!this.toggleElement) {
            this.toggleElement.observe('click', this.toggle.bind(this));
        }
    },
    toggle: function(event) {
        var that = this;
        if (this.expandoElement.hasClassName(this.expandedClass)) {
            // it's expanded
            that.onBeforeCollapse();
            this.fx.options.onComplete = function() {
                that.expandoElement.removeClassName(that.expandedClass).addClassName(that.collapsedClass);
                that.onCollapseComplete();
            };
            this.fx.start(this.expandedHeight, this.collapsedHeight);
        } else {
            that.onBeforeExpand();
            // it's collapsed
            this.fx.options.onComplete = function() {
                that.expandoElement.removeClassName(that.collapsedClass).addClassName(that.expandedClass);
                that.onExpandComplete();
            };
            this.fx.start(this.collapsedHeight, this.expandedHeight);
        }
        Event.stop(event);
    }
});
