/* 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 IE = /*@cc_on!@*/false;
var Accordion = Class.create({
    initialize: function(id, defaultExpandedCount) {
    	var a = $(id);
        if(!a){ throw("Attempted to initalize accordion with id: "+ id + " which was not found.");}
        this.accordion = a;
        this.options = {
            toggleClass: "accordionToggle",
            toggleActive: "accordionToggleActive",
            parentToggleClass: "accordionItem",
            parentToggleActive: "accordionItem-toggleActive",
            contentClass: "accordionContent"
        }
        this.contents = this.accordion.select('div.'+this.options.contentClass);
        this.isAnimating = false;
        this.maxHeight = 0;
        this.current = defaultExpandedCount ? this.contents[defaultExpandedCount-1] : this.contents[0];
        this.toExpand = null;
        this.previousToExpand = null;
        this.previousParallelEffect = null;
        this.checkMaxHeight();
        this.maxHeight = this.maxHeight + 10;
        this.initialHide();
        this.attachInitialMaxHeight();
        var clickHandler = this.clickHandler.bindAsEventListener(this);
        this.accordion.observe('click', clickHandler);
    },

    expand: function(el) {
	var obj = $(el),
	parentNode = obj.up('div.' + this.options.parentToggleClass);

	if (!parentNode.hasClassName(this.options.parentToggleActive)) {

		if (obj.hasClassName(this.options.toggleClass)) {
			this.toExpand = obj.next('div.' + this.options.contentClass);
		} else {
			this.toExpand = parentNode.down('div.' + this.options.contentClass);
		}
		this.toExpand.show();
		this.animate();
	}
    },

    checkMaxHeight: function() {
        for(var i=0; i<this.contents.length; i++) {
            if(this.contents[i].getHeight() > this.maxHeight) {
                this.maxHeight = this.contents[i].getHeight();
            }
        }
    },

    attachInitialMaxHeight: function() {
		this.current.previous('ul.'+this.options.toggleClass).addClassName(this.options.toggleActive)
			    .up('div.' + this.options.parentToggleClass).addClassName(this.options.parentToggleActive);
        if(this.current.getHeight() != this.maxHeight){
			this.current.setStyle({height: this.maxHeight +"px"});
		}
    },

    clickHandler: function(e) {
        var el = e.element();
		this.expand(el);
    },

	initialHide: function(){
		for(var i=0; i<this.contents.length; i++){
            if(this.contents[i] != this.current) {
                this.contents[i].setStyle({height: 0});
            }
        }
    },

    animate: function() {
	var t = this,
	o = t.options,
	myDuration = 0.75,
	effects = [],
	options = {
	    sync: true,
	    scaleFrom: 0,
	    scaleContent: false,
	    transition: Effect.Transitions.sinoidal,
	    scaleMode: {
		originalHeight: t.maxHeight,
		originalWidth: t.accordion.getWidth()
	    },
	    scaleX: false,
	    scaleY: true
	};

	effects.push(new Effect.Scale(t.toExpand, 100, options));

	for (var h, i = 0, c = t.contents, cl = c.length; i < cl; i++) {

		if (t.toExpand != c[i] && (h = c[i].getHeight()) > 0) {

			options = {
			    scaleFrom: h / t.maxHeight * 100,
			    sync: true,
			    scaleContent: false,
			    transition: Effect.Transitions.sinoidal,
			    scaleMode: {
				originalHeight: t.maxHeight,
				originalWidth: t.accordion.getWidth()
			    },
			    scaleX: false,
			    scaleY: true
			};

			effects.push(new Effect.Scale(c[i], 0, options));

			c[i].previous('ul.' + o.toggleClass).removeClassName(o.toggleActive)
				.up('div.' + o.parentToggleClass).removeClassName(o.parentToggleActive);
		}
	}

	if (t.isAnimating) {

		t.previousParallelEffect.cancel();
	}

	if (IE) {
	
		t.current.select('div').each(function(e){ e.hide();})
	}

	t.current.previous('ul.' + o.toggleClass).removeClassName(o.toggleActive)
		.up('div.' + o.parentToggleClass).removeClassName(o.parentToggleActive);
	t.toExpand.previous('ul.' + o.toggleClass).addClassName(o.toggleActive)
		.up('div.' + o.parentToggleClass).addClassName(o.parentToggleActive);

	t.previousToExpand = t.toExpand;
	t.isAnimating = true;

	t.previousParallelEffect = new Effect.Parallel(effects, {
	    duration: myDuration,
	    fps: 35,
	    queue: {
		position: 'end',
		scope: 'accordion'
	    },
	    afterFinish: function() {
		if(IE){ this.toExpand.select('div').each(function(e){ e.show();}) } else {t.current.hide();}
		t.toExpand.setStyle({ height: t.maxHeight+"px" });
		t.current = t.toExpand;
		t.toExpand.setStyle({ display: "none" });
		t.toExpand.setStyle({ display: "block" });
		t.isAnimating = false;
	    }.bind(t)
	});
    }

});
