(function ($) {

	// Plugin definition.
	$.fn.animateSlideshow = function (options) {

		// Build options before element iteration.
		var o = $.extend({}, $.fn.animateSlideshow.defaults, options);

		// Iterate through and prepare each gallery for transitioning.
		return this.each(function () {
			var $gallery = $(this);
			var $items = $(' > li', $gallery);

			// Determine the currently active index and the number of items and store as element-specific data.
			$gallery.data('items', $items);
			$gallery.data('activeItemIndex', 0);
			$gallery.data('numberOfItems', $items.length);

			// Hide all items other than the first.
			$items.not(':first').hide();

			// Set interval to perform transition every {o.transitionDelay} millseconds.
			$gallery.data('transitionInterval', setInterval(function () { fadeOutActiveItem($gallery, o) }, o.transitionDelay));
		});
	};

	// Fade out the currently active item.
	function fadeOutActiveItem($obj, o) {

		// If the gallery is in mid-transition, don't attempt to fade out.
		if ($obj.data('isAnimating')) return;

		// Retrieve element-specific data and store as variables preventing inordinate use of jQuery data function.
		var $items = $obj.data('items');
		var activeItemIndex = $obj.data('activeItemIndex');

		// Fade out currently active item.
		$items.eq(activeItemIndex).fadeOut(o.fadeOutDuration, function () { fadeInNextItem($obj, o) });
	}

	// Fade in the soon-to-be-active item.
	function fadeInNextItem($obj, o) {

		var $items = $obj.data('items');
		var prevItemIndex = $obj.data('activeItemIndex');
		var numberOfItems = $obj.data('numberOfItems');

		// Calculate the index of the next item to be faded in and get reference to previously- and next-active item.
		var nextItemIndex = (prevItemIndex < numberOfItems - 1) ? prevItemIndex + 1 : 0;
		var $nextItem = $items.eq(nextItemIndex);
		var $prevItem = $items.eq(prevItemIndex);

		// Add 'current' class from to new item and remove it 'current' class from previously active item.
		$nextItem.addClass('active');
		$prevItem.removeClass('active');

		// Store new active item index.
		$obj.data('activeItemIndex', nextItemIndex);

		// Fade in newly active item.
		$nextItem.fadeIn(o.fadeInDuration, function () {

			// Indicate that the gallery is no longer in mid-transition.
			$obj.data('isAnimating', false);
		});
	}

	// Plugin defaults.
	$.fn.animateSlideshow.defaults = {
		fadeInDuration: 450,
		fadeOutDuration: 350,
		transitionDelay: 2500
	}
})(jQuery);