/**
 * Interface Elements for jQuery
 * Accordion
 * 
 * http://interface.eyecon.ro
 * 
 * Copyright (c) 2006 Stefan Petre
 * Dual licensed under the MIT (MIT-LICENSE.txt) 
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 */

/**
 * Create an accordion from a HTML structure
 *
 * @desc Converts definition list with id 'myAccordion' into an accordion width dt tags as headers and dd tags as panels
 * 
 * @name Accordion
 * @description Create an accordion from a HTML structure
 * @param Hash hash A hash of parameters
 * @option Integer panelHeight the pannels' height
 * @option String headerSelector selector for header elements
 * @option String panelSelector selector for panel elements
 * @option String activeClass (optional) CSS Class for active header
 * @option String hoverClass (optional) CSS Class for hovered header
 * @option Function onShow (optional) callback called whenever an pannel gets active
 * @option Function onHide (optional) callback called whenever an pannel gets incative
 * @option Function onClick (optional) callback called just before an panel gets active
 * @option Mixed speed (optional) animation speed, integer for miliseconds, string ['slow' | 'normal' | 'fast']
 * @option Integer crrentPanel (otional) the active panel on initialisation
 *
 * @type jQuery
 * @cat Plugins/Interface
 * @author Stefan Petre
 */
jQuery.iAccordion = {
	build : function(options){
		return this.each(
			function(){
				if (!options.headerSelector || !options.panelSelector)
					return;
				var el = this;
				el.accordionCfg = {
					panelHeight			: options.panelHeight||300,
					headerSelector		: options.headerSelector,
					panelSelector		: options.panelSelector,
					activeClass			: options.activeClass||'fakeAccordionClass',
					hoverClass			: options.hoverClass||'fakeAccordionClass',
					onShow				: options.onShow && typeof options.onShow == 'function' ? options.onShow : false,
					onHide				: options.onShow && typeof options.onHide == 'function' ? options.onHide : false,
					onClick				: options.onClick && typeof options.onClick == 'function' ? options.onClick : false,
					headers				: jQuery(options.headerSelector, this),
					panels				: jQuery(options.panelSelector, this),
					speed				: options.speed||400,
					currentPanel		: options.currentPanel||0
				};
				el.accordionCfg.panels.hide().css('height', '1px').eq(el.accordionCfg.currentPanel).css({
					height: el.accordionCfg.panelHeight + 'px',
					display: 'block'
				}).end();
					
				el.accordionCfg.headers.each(function(nr){
					this.accordionPos = nr;
				}).hover(function() {
					jQuery(this).addClass(el.accordionCfg.hoverClass);
				}, function() {
					jQuery(this).removeClass(el.accordionCfg.hoverClass);
				}).bind('click', function(e){
					if (el.accordionCfg.currentPanel == this.accordionPos)
						return;
					var nextPanel = el.accordionCfg.panels.eq(this.accordionPos).css({height: 0, display: 'block'});
					el.accordionCfg.headers.eq(el.accordionCfg.currentPanel).removeClass(el.accordionCfg.activeClass)
						.end().eq(this.accordionPos).addClass(el.accordionCfg.activeClass);
					
					el.accordionCfg.panels.eq(el.accordionCfg.currentPanel).animate({height:0}, {
							duration: el.accordionCfg.speed,
							step: function(curr, _this) {
								_this.now = Math.floor(curr);
								nextPanel.css('height', el.accordionCfg.panelHeight - _this.now + 'px');
							},
							complete: function() {
								this.style.display = 'none';
								if (el.accordionCfg.onHide) {
									el.accordionCfg.onHide.apply(el, [this]);
								}
							}
						}
					);
					
					if (el.accordionCfg.onClick) {
						el.accordionCfg.onClick.apply(el,[
							this, 
							el.accordionCfg.panels.get(this.accordionPos),
							el.accordionCfg.headers.get(el.accordionCfg.currentPanel),
							el.accordionCfg.panels.get(el.accordionCfg.currentPanel)
						]);
					}
					el.accordionCfg.currentPanel = this.accordionPos;
				}).eq(el.accordionCfg.currentPanel).addClass(el.accordionCfg.activeClass).end();
				jQuery(this).css('height', jQuery(this).css('height')).css('overflow', 'hidden');
			}
		);
	}
};

jQuery.fn.Accordion = jQuery.iAccordion.build;
