/*
 * jQuery Accordion Plug-in
 *
 * Based on code published by John Resig.
 *
 * Revision: 3
 * Version: 0.3
 *
 * Revision History
 * v0.3
 * - Added a "hack" to fix bug which could occur if another panel
 *   was clicked to be open before the previous panel was fully open.
 *   You can not open another panel until the previous one is fully open.
 *
 * v0.2
 * - Added code to try and future proof the step() code.
 * - Added check for jQuery v1.2+
 *
 * v0.1
 * - First public release
 *
*/
(function ($){

	// set the defaults
	var defaults = {
		easing: "linear",
		duration: 300,
		onSelected: function (){}
	}
	, settings, bPercBased=(parseFloat(jQuery.fn.jquery) >= 1.2);

	// set default options
	$.accordion = {
		version: "0.3",
		setDefaults: function(options){
			$.extend(defaults, options);
		},
		setSettings: function(options){
			$.extend(settings, options);
		}
	};

	/*
	 * jQuery.fn.accordion()
	 *
	 * Examples:
	 * $("dl").accordion();
	 * > Creates an accordion out of a DL element
	 *
	 */
	// the accordion() method
	$.fn.accordion = function(options){
		// get the current settings
		settings = jQuery.extend({}, defaults, options);

		// create a reference to the current jQuery object
		var me = this, bRunning = false;

		// hide everything but the first
		$("dd:not(:first)", me).hide();

		// show the first dd
		$("dd:first", me).show();

		// make the first accordion active
		$("dt:first", me).addClass("focus");

		// add the click event handler
		$("dt a", me).click(function(){
			// blur the anchor (so it's not outlined)
			this.blur();

			// do not allow if animation running. this is quick hack to prevent errors
			// from occuring another panel was clicked on while the previous panel was
			// still in the process of being opened. in the long run better handling
			// should be added, but until you can cancel an jQuery FX, this is the
			// most straightforward hack
			if( bRunning ) return false;

			$("dt").removeClass("focus");

			$(this).parent("dt").addClass("focus");

			var visible = $("dd:visible", me),
				height = visible.height(),
				hidden = $(this).parent().next();

			if ( !hidden.is(":visible") ) {
				hidden.show();

				// an animation is running
				bRunning = true;

				visible.animate(
					{height:"hide"},
					{
						step: function(n){
							hidden.height(
								// if using jQuery v1.2+, then "n" is a percentage that indicates
								// the percentage of completion (0 - 1) of current animation step.
								// older versions of jQuery (v1.1 and below) pass in the current
								// pixel value of the effect
								Math.ceil( (bPercBased) ? (height - (height * n)) : (height - n) )
							);
						},
						complete: function(){
							// animation is complete
							bRunning = false;
						},
						duration: settings.duration,
						easing: settings.easing
					}
				);
			}
			settings.onSelected(this);

			return false;
		});

		// return the values as a comma-delimited string
		return me;
	};

})(jQuery);

