if (typeof IGLOO == "undefined") { var IGLOO = {}; }

/**
* make an accordion - a wrapper for multiple ShowHide components
* @constructor
* @param container [String|HTML Element] an HTML Element or Element ID
* @param {options} [Object] a javascript object containing setup options for the accordion
*/
IGLOO.Accordion = Class.create();
IGLOO.Accordion.prototype = {
	
	showNode : null,
	currentNode : null,
	duration : null,
	effects : [],
	animating : false,

	initialize: function (container, options) {
		this.container = $(container);
		if (!this.container) throw( "The specified element does not exist or could not be found" );
		var defaults = {
			duration : 0.4,
			transition: Effect.Transitions.sinoidal,
			selectors : {
				toggle : 'accordion_toggle',
				content : 'accordion_content'
			},
			activeClass: 'active',
			defaultSize : {
				height : null,
				width : null
			},
			direction : 'vertical',
			allowAllClosed: true,
			initialOpen: null,
			onEvent : 'click'
		};
		this.options = Object.extend(defaults, options || {});
		this.nodes = this.container.select('.' + this.options.selectors.toggle);
		for (var i = 0, len = this.nodes.length; i < len; ++i) {
			Event.observe(this.nodes[i], this.options.onEvent, this.activate.bind(this, this.nodes[i]), false);
			var options;
			if (this.options.direction == 'horizontal') { options = { width: '0px' }; }
			else { options = { height: '0px' }; }
			options = Object.extend(options, { display: 'none' });
			Element.setStyle(Element.next(this.nodes[i], 0), options);
		}
		if (this.options.initialOpen && (this.options.initialOpen <= this.nodes.length + 1) && (this.options.initialOpen - 1 >= 0)) {
			this.activate(this.nodes[this.options.initialOpen - 1] || this.nodes[0]);
		};
	},

	activate : function (node) {
		if (this.animating) return;
		this.effects = [];
		this.currentNode = $(Element.next(node, 0));
		Element.setStyle(this.currentNode, { display: 'block' });		
		Element.addClassName(node, this.options.activeClass);
		if (this.options.direction == 'horizontal') { this.scaling = { scaleX: true, scaleY: false }; }
		else { this.scaling = { scaleX: false, scaleY: true }; }
		if (this.currentNode == this.showNode) { if (this.options.allowAllClosed) this.deactivate(); }
		else { this._handleNode(); }
	},
	
	deactivate : function () {
		this.animating = true;
		var options = {
		  duration: this.options.duration,
			scaleContent: false,
			transition: this.options.transition,
			queue: {
				position: 'end', 
				scope: 'accordion'
			},
			scaleMode: {
				originalHeight: this.options.defaultSize.height ? this.options.defaultSize.height : this.currentNode.scrollHeight,
				originalWidth: this.options.defaultSize.width ? this.options.defaultSize.width : this.currentNode.scrollWidth
			},
			afterFinish: function () {
				Element.setStyle(this.showNode, {
          height: '0px',
					display: 'none'
				});
				this.showNode = null;
				this.animating = false;
			}.bind(this)
		};
    options = Object.extend(options, this.scaling);
    Element.removeClassName(Element.previous(this.showNode, 0), this.options.activeClass);
		new Effect.Scale(this.showNode, 0, options);
	},
	
	/**
		@private
	*/
	_handleNode : function () {		
		this.animating = true;
		var options = {
			sync: true,
			scaleFrom: 0,
			scaleContent: false,
			transition: this.options.transition,
			scaleMode: {
				originalHeight: this.options.defaultSize.height ? this.options.defaultSize.height : this.currentNode.scrollHeight,
				originalWidth: this.options.defaultSize.width ? this.options.defaultSize.width : this.currentNode.scrollWidth
			}
		};
    options = Object.extend(options, this.scaling);
		this.effects.push(new Effect.Scale(this.currentNode, 100, options));
		if (this.showNode) {
			Element.removeClassName(Element.previous(this.showNode, 0), this.options.activeClass);
			options = {
				sync: true,
				scaleContent: false,
				transition: this.options.transition
			};
	    options = Object.extend(options, this.scaling);
			this.effects.push(new Effect.Scale(this.showNode, 0, options));
		};
    new Effect.Parallel(this.effects, {
			duration: this.options.duration,
			queue: {
				position: 'end',
				scope: 'accordion'
			},
			afterFinish: function () {
				if (this.showNode) { Element.setStyle(this.showNode, { display: 'none' }); }
				Element.setStyle(this.currentNode, { height: 'auto' });
				this.showNode = this.currentNode;
				this.animating = false;
			}.bind(this)
		});
	}
};