;(function($)
{
	
$.fn.hidable = function(options)
{
	// Defaults.
	var settings =
	{
		duration: 400,
		fadeOut: false, 
		
		changeStart: $.noop, 
		changeEnd:   $.noop, 
		
		showStart:   $.noop, 
		showEnd:     $.noop, 
		
		hideStart:   $.noop, 
		hideEnd:     $.noop
	};
	
	// Effective settings.
	if(options) $.extend(settings, options);
	
	// Toggling.
	$(this).live('click', function(e)
	{
		e.preventDefault();
		
		var selector = $(this).attr('href');
		
		$(selector).filter(':not(:animated)').trigger('hidabletoggle', [this]);
	});
	
	// Set items of triggers indivudually.
	$(this).each(function()
	{
		var selector = $(this).attr('href');
		
		// Toggling effects.
		$(selector).bind('hidabletoggle', function(e, trigger)
		{
			$hidable = $(this);
			var hidden = $hidable.hasClass('hidden');
			
			// Move up / down.
			var properties = {
				height: (hidden ? $hidable.data('naturalHeight') : 0)
			};
			if(settings.fadeOut) properties.opacity = (hidden ? 1 : 0);
			
			var obj = 
			{
				container: $hidable, 
				trigger: trigger
			};
			
			// Trigger starting functions.
			settings.changeStart(e, obj);
			if(hidden)
				settings.showStart(e, obj);
			else
				settings.hideStart(e, obj);
			
			// Commence hiding/showing.
			$hidable.toggleClass('hidden', !hidden);
			$hidable.animate(properties, settings.duration, function()
			{
				// Trigger ending functions.
				settings.changeEnd(e, obj);
				if(hidden)
					settings.showEnd(e, obj);
				else
					settings.hideEnd(e, obj);
			});
			
			// Modify trigger.
			$(trigger).toggleClass('maximise');
		});
		
		// Set natural height of hidable object.
		$(selector).data('naturalHeight', $(selector).height());
	});
	
	return this;
};
	
})(jQuery);
