/* Simple Accordion Script
 * Requires Prototype and Script.aculo.us Libraries
 * By: Brian Crescimanno <brian.crescimanno@gmail.com>
 * http://briancrescimanno.com
 * This work is licensed under the Creative Commons Attribution-Share Alike 3.0
 * http://creativecommons.org/licenses/by-sa/3.0/us/
 */

if (typeof Effect == 'undefined'){
    throw("You must have the script.aculo.us library to use this accordion");
}
var Accordion = Class.create({

    initialize: function(id, defaultExpandedCount) {
        if(!$(id)) {
            return;
        }
        this.accordion = $(id);
        this.options = {
            toggleClass: "accordion-toggle",
            toggleActive: "accordion-toggle-active",
            contentClass: "accordion-content"
        }
        this.contents = this.accordion.select('div.'+this.options.contentClass);
        this.toggles = this.accordion.select('h3.'+this.options.toggleClass);
        this.initialHeights = new Array();
        this.checkInitialHeights();
        this.isAnimating = false;
        this.maxHeight = 0;
        this.current = defaultExpandedCount ? this.contents[defaultExpandedCount-1] : this.contents[0];
        this.toExpand = null;

        this.checkMaxHeight();
        this.initialHide();

        var clickHandler =  this.clickHandler.bindAsEventListener(this);
        this.accordion.observe('click', clickHandler);
    },

    expand: function(el) {
        this.toExpand = el.next('div.'+this.options.contentClass);
        if(this.current != this.toExpand){
            this.toExpand.show();
            this.animate(el);
        }
    },

    checkInitialHeights: function() {
        for(var i=0; i<this.contents.length; i++) {
            this.initialHeights[i] = i+":"+ this.contents[i].getHeight();
        }
    },

    getNewHeight: function(index) {
        for(var i=0; i<this.initialHeights.length; i++) {
            var initIndex = this.initialHeights[i].substring(0, this.initialHeights[i].indexOf(":"));
            if(initIndex.indexOf(index) != -1) {
                return this.initialHeights[i].substring(this.initialHeights[i].indexOf(":")+1, this.initialHeights[i].length);
            }
        }
    },

    clickHandler: function(e) {
        var el = e.element();
        if(el.hasClassName(this.options.toggleClass) && !this.isAnimating) {
            this.expand(el);
        }
    },

    initialHide: function(){
        for(var i=0; i<this.contents.length; i++){
            if(this.contents[i] != this.current) {
                this.contents[i].hide();
                this.contents[i].setStyle({
                    height: 0
                });
            }
        }
    },

    checkMaxHeight: function() {
        this.maxHeight =  0;
        this.maxHeight = this.maxHeight + $("accordion").firstDescendant().getHeight();
        var maxContentHeight = 0;
        for(var i=0; i<this.contents.length; i++) {
            if(this.contents[i].getHeight() > maxContentHeight) {
                maxContentHeight = this.contents[i].firstDescendant().getHeight();
            }
        }
        this.maxHeight = this.maxHeight + maxContentHeight;

        for(var i=0; i<this.toggles.length; i++) {
            this.maxHeight = this.maxHeight + this.toggles[i].getHeight();
        }
        $("accordion").style.height = this.maxHeight+"px";
    },

    animate: function(el) {
        var effects = new Array();
        var options = {

            sync: true,
            scaleFrom: 0,
            scaleContent: false,
            transition: Effect.Transitions.sinoidal,
            scaleMode: {
                originalHeight: this.getNewHeight(el.id.substring(6, el.id.length)),
                originalWidth: this.accordion.getWidth()
            },
            scaleX: false,
            scaleY: true
        };

        effects.push(new Effect.Scale(this.toExpand, 100, options));

        options = {
            sync: true,
            scaleContent: false,
            transition: Effect.Transitions.sinoidal,
            scaleX: false,
            scaleY: true
        };

        effects.push(new Effect.Scale(this.current, 0, options));

        var myDuration = 0.5;

        new Effect.Parallel(effects, {
            duration: myDuration,
            fps: 35,
            queue: {
                position: 'end',
                scope: 'accordion'
            },
            beforeStart: function() {
                this.isAnimating = true;
                this.current.previous('h3.'+this.options.toggleClass).removeClassName(this.options.toggleActive);
                this.toExpand.previous('h3.'+this.options.toggleClass).addClassName(this.options.toggleActive);
            }.bind(this),
            afterFinish: function() {
                this.newHeight = this.getNewHeight(this.toExpand.id.substring(7, this.toExpand.id.length));
                this.current.hide();
                this.toExpand.setStyle({
                    height: this.newHeight+"px"
                    });
                this.current = this.toExpand;
                this.isAnimating = false;
            }.bind(this)
        });
    }

});

document.observe("dom:loaded", function(){
    //accordion = new Accordion("accordion", $$('.accordion-content').length);
    var accordion = new Accordion("accordion", 1);
})
