jQuery.fn.gallery = function(options) 
{
	// =========================================================
	// == Settings =============================================
	// =========================================================
	var settings = jQuery.extend({
		onChange: function(){},
		page: ".navigation .page",
		next: ".navigation .next",
		prev: ".navigation .prev",
		pane: ".panes .pane",
		activePageClass: "active",
		disabledNavigationClass: "disabled",
		autorotate: false,
		duration: 6,
		wrap: false,
		stopOnNavigate: false
	}, options);
	
	settings.form = jQuery(this);
	
	// =========================================================
	// == Navigation ===========================================
	// =========================================================
	var navigation = new Object();
	navigation.nextRotation = null;
	navigation.SetPanesAndNavigation = function(newPane, oldPane) {
		if(newPane.length == 0)
			return;
			
		if(oldPane.length > 0)
			oldPane.fadeOut(400, function() { newPane.fadeIn(); });
		else newPane.fadeIn();

		settings.form.find(settings.page + "." + settings.activePageClass).removeClass(settings.activePageClass);
		settings.form.find(settings.page + ":eq(" + newPane.index(settings.pane) + ")").addClass(settings.activePageClass);

		if(!settings.wrap) {
			var hasNext = (newPane.next().length > 0);
			var hasPrev = (newPane.prev().length > 0);
			
			settings.form.find(settings.next).toggleClass(settings.disabledNavigationClass, !hasNext);
			settings.form.find(settings.prev).toggleClass(settings.disabledNavigationClass, !hasPrev);
		}
		
		settings.onChange(newPane);
		
		if(settings.autorotate) {
			navigation.Play();
		}
	}
	navigation.GoToPage = function(paneIndex) {
		var currentPane = settings.form.find(settings.pane + ":visible");
		var targetPane 	= settings.form.find(settings.pane + ":eq(" + paneIndex + ")");

		if(settings.stopOnNavigate)
		{
			settings.autorotate = false;
			clearTimeout(navigation.nextRotation);
		}
		
		navigation.SetPanesAndNavigation(targetPane, currentPane);	
	}
	navigation.MovePrevious = function() {
		var currentPane = settings.form.find(settings.pane + ":visible");
		var prevPane	= currentPane.prev(settings.pane);
		if(prevPane.length == 0 && settings.wrap)
			prevPane = settings.form.find(settings.pane + ":last");

		if(prevPane.length == 0)
			return;
			
		navigation.SetPanesAndNavigation(prevPane, currentPane);
	}
	navigation.MoveNext = function() {
		var currentPane = settings.form.find(settings.pane + ":visible");
		var nextPane	= currentPane.next(settings.pane);
		if(nextPane.length == 0 && settings.wrap)
			nextPane = settings.form.find(settings.pane + ":first");
			
		if(nextPane.length == 0)
			return;

		navigation.SetPanesAndNavigation(nextPane, currentPane);
	}
	navigation.Pause = function() {
		settings.autorotate = false;
		clearTimeout(navigation.nextRotation);
	}
	navigation.Play = function() {
		settings.autorotate = true;
		clearTimeout(navigation.nextRotation);
		navigation.nextRotation = setTimeout(navigation.MoveNext, settings.duration * 1000);
	}
	
	// =========================================================
	// == Initialization =======================================
	// =========================================================
	
	
	// Show the current pane
	var currentPane = settings.form.find(settings.pane + ":visible");
	if(currentPane.length == 0) {
		currentPane = settings.form.find(settings.pane + ":first");
		currentPane.show();
	}
	
	// Mark the current pane as active
	settings.form.find(settings.page + ":eq(" + settings.form.find(settings.pane).index(currentPane) + ")").addClass(settings.activePageClass);
	
	// Update the next and previous buttons
	if(!settings.wrap) {
		settings.form.find(settings.prev).addClass(settings.disabledNavigationClass);
		if(currentPane.next().length == 0)
			settings.form.find(settings.next).addClass(settings.disabledNavigationClass);
	}
	
	// Kick off the auto rotation
	if(settings.autorotate) 
		navigation.nextRotation = setTimeout(navigation.MoveNext, settings.duration * 1000);
	
	// =========================================================
	// == Events ===============================================
	// =========================================================	
	// Click of the specific page button
	settings.form.find(settings.page).click(function() {
		var index = settings.form.find(settings.page).index(this);
		
		navigation.GoToPage(index);
	});
	// Click of the previous button
	settings.form.find(settings.prev).click(function() {
		if(jQuery(this).hasClass(settings.disabledNavigationClass))
			return;

		navigation.MovePrevious();
	});
	// Click of the next button
	settings.form.find(settings.next).click(function() {
		if(jQuery(this).hasClass(settings.disabledNavigationClass))
			return;

		navigation.MoveNext();
	});
	
	return navigation;
}

