Accordion.Animation = Class.create({
	initialize: function(options){
		// option defaults
		this.options = Object.extend({
			duration: 1,
			transition: Effect.Transitions.puff
		}, options || {});
		
		this.accordion = this.options.accordion;
		this.currentlyAnimating = false;
		
		// listen for custom events
		document.observe(this.accordion.accordionId+"_accordion:initialized", this.setupAnimations.bindAsEventListener(this));
		document.observe(this.accordion.accordionId+"_tab:opened", this.openAnimation.bindAsEventListener(this));
		document.observe(this.accordion.accordionId+"_tab:closed", this.closeAnimation.bindAsEventListener(this));
		document.observe(this.accordion.accordionId+"_tab:parallel", this.parallelAnimation.bindAsEventListener(this));
	},
	setupAnimations: function(e){
		// get active and inactive tabs from event memo
		var activeTab = e.memo.activeTab;
		var inactiveTabs = e.memo.inactiveTabs;
		
		// set original drawer heights to "_height" property for use in animations
		this.accordion.drawers.each(function(currentDrawer){
			currentDrawer._height = currentDrawer.getHeight();
			currentDrawer.setStyle({overflow: "hidden"});
		}.bind(this));	
		
		// set inactive tabs drawer height to 0px to appear closed and for smoothness in animation
		inactiveTabs.each(function(currentTab){
			this.accordion.drawers[this.accordion.tabs.indexOf(currentTab)].setStyle({
				height: "0px"
			});
		}.bind(this));
		
		// set active tab drawer height to it's original height for smoothness in animation
		this.accordion.drawers[this.accordion.tabs.indexOf(activeTab)].setStyle({
			height: this.accordion.drawers[this.accordion.tabs.indexOf(activeTab)]._height+"px"
		});
	},
	openAnimation: function(e){
		var tabToOpen = Event.element(e);
		var drawerToOpen = this.accordion.drawers[this.accordion.tabs.indexOf(tabToOpen)];
		
		new Effect.Morph(
			drawerToOpen, {
				style: {height: drawerToOpen._height+"px"},
				duration: this.options.duration,
				transition: this.options.transition,
				queue: { 
					position: 'end', 
					scope: this.accordion.accordionId,
					limit: 10
				},				
				beforeStart: function(){
					this.currentlyAnimating = true;
				}.bind(this),
				afterFinish: function(){
					this.currentlyAnimating = false;
				}.bind(this)		
			}
		);
	},
	closeAnimation: function(e){
		var tabToClose = Event.element(e);
		var drawerToClose = this.accordion.drawers[this.accordion.tabs.indexOf(tabToClose)];
		
		new Effect.Morph(
			drawerToClose, {
				style: {height: "0px"},
				duration: this.options.duration,
				transition: this.options.transition,
				queue: { 
					position: 'end', 
					scope: this.accordion.accordionId,
					limit: 10
				},
				beforeStart: function(){
					this.currentlyAnimating = true;
				}.bind(this),						
				afterFinish: function(){
					this.currentlyAnimating = false;
				}.bind(this)
			}
		);
	},
	parallelAnimation: function(e){
		var tabToOpen = Event.element(e);
		var tabToClose = e.memo.tabToClose.first();
		var drawerToOpen = this.accordion.drawers[this.accordion.tabs.indexOf(tabToOpen)];
		var drawerToClose = this.accordion.drawers[this.accordion.tabs.indexOf(tabToClose)];
		
		new Effect.Parallel([
			new Effect.Morph(
				drawerToOpen, {
					style: {height: drawerToOpen._height+"px"},
					duration: this.options.duration,
					transition: this.options.transition,
					beforeStart: function(){
						this.currentlyAnimating = true;
					}.bind(this),						
					afterFinish: function(){
						this.currentlyAnimating = false;
						drawerToOpen.setStyle({
			                height: "auto"
		                });
					}.bind(this)		
				}
			),
			new Effect.Morph(
				drawerToClose, {
					style: {height: "0px"},
					duration: this.options.duration,
					transition: this.options.transition,
					beforeStart: function(){
						this.currentlyAnimating = true;
					}.bind(this),						
					afterFinish: function(){
						this.currentlyAnimating = false;
					}.bind(this)
				}
			)			
			],{
			sync: true,
			queue: { 
				position: 'end', 
				scope: this.accordion.accordionId,
				limit: 10
			}
		});
	}
});
