/* 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)) throw("Attempted to initalize accordion with id: "+ id + " which was not found.");
		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.contentsHeights = new Array();
        for(var i=0; i<this.contents.length; i++) {                  		                                
            this.contents[i].setAttribute('id','acnt_'+i);
            this.contentsHeights[i] = this.contents[i].getHeight();            
		}
		this.expandHeight = null;
		this.oldHeight = null;
        this.isAnimating = false;        
        this.current = defaultExpandedCount ? this.contents[defaultExpandedCount-1] : this.contents[0];
        this.toExpand = null;       

		this.initialHide();           	

        var clickHandler =  this.clickHandler.bindAsEventListener(this);
        this.accordion.observe('click', clickHandler);
		if(!defaultExpandedCount) {		
        	this.current.addClassName('first');
        	this.current.hide();			
		} 
	},  

    expand: function(el) {
        this.toExpand = el.next('div.'+this.options.contentClass);      
        if(this.current != this.toExpand){
			var currentToggleObj=this.current.previousSiblings();
			currentToggleObj=currentToggleObj[0];
			$(currentToggleObj).removeClassName('opened');
			$(currentToggleObj).addClassName('closed');
			this.toExpand.show();
            this.animate(false);
        }       
		else if((this.current == this.toExpand) && this.current.hasClassName('first')) {		
            var currentToggleObj=this.current.previousSiblings();
			currentToggleObj=currentToggleObj[0];
			$(currentToggleObj).removeClassName('opened');
			$(currentToggleObj).addClassName('closed');
        	this.toExpand.show();
            this.animate(true);
            this.current.removeClassName('first');
        }
        else if(this.current == this.toExpand) {
        	this.current.hide();        				
        	var currentToggleObj=this.current.previousSiblings();
			currentToggleObj=currentToggleObj[0];
			$(currentToggleObj).removeClassName('opened');
			$(currentToggleObj).addClassName('closed');
			$(currentToggleObj).scrollTo();
		}
	},

    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();                 	
			}
        }
    },

	animate: function(isFirst) {
		var expandHeightIndex=parseInt(this.toExpand.readAttribute('id').replace('acnt_',''));
		this.expandHeight=this.contentsHeights[expandHeightIndex];
		var oldHeightIndex=parseInt(this.current.readAttribute('id').replace('acnt_',''));
		this.oldHeight=this.contentsHeights[oldHeightIndex];
		var effects = new Array();
        var options = {
            sync: true,
            scaleFrom: 0,
            scaleContent: false,
            transition: Effect.Transitions.sinoidal,
            scaleMode: {
                originalHeight: this.oldHeight,
                originalWidth: this.accordion.getWidth()
            },
            scaleX: false,
            scaleY: true
        };

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

        if(!isFirst) {
        	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.75;       		
		
        new Effect.Parallel(effects, {
            duration: myDuration,
            fps: 35,
            queue: {
                position: 'end',
                scope: 'accordion'
            },
            beforeStart: function() {
                this.isAnimating = true;
                this.toExpand.setStyle({ height: "0px" });
                this.current.previous('div.'+this.options.toggleClass).removeClassName(this.options.toggleActive);
                this.toExpand.previous('div.'+this.options.toggleClass).addClassName(this.options.toggleActive);
            }.bind(this),            
            afterFinish: function() {
                if(!isFirst)
                	this.current.hide();                	              			
                new Effect.Morph(this.toExpand, {style:'height: '+this.expandHeight+'px;',duration:0.5});
                this.current = this.toExpand;                
                this.isAnimating = false;                
                var currentToggleObj=this.current.previousSiblings();
                currentToggleObj=currentToggleObj[0];
                $(currentToggleObj).removeClassName('closed');
				$(currentToggleObj).addClassName('opened');			
                $(currentToggleObj).scrollTo();
            }.bind(this)
        });      
	}

});
