(function($) {

	/** Plugin starter */
	$(document).ready(function() {
		$('.banner-wrapper').floatingBanners(floatingBannerSettings);
	});

	/**
	 * Wacom UI - Floating banner component
	 *
	 * This jQuery plugin provides an new frontend
	 * component which shows off banner that are
	 * floating around a container.
	 *
	 * The navigation controls the active banner.
	 *
	 * The basic structure is fixed and should build up towards
	 * this structures:
	 *
	 * HTML structure - Banners:
	 * <div class="banner-wrapper">
	 *    <div class="banner-box">
	 *        <img src="[banner-url]" class="banner-image" />
	 *
	 *        <div class="banner-content">
	 *            <h2>[article-name]</h2>
	 *
	 *            <p>[banner-desc]</p>
	 *
	 *            <p class="action">
	 *                <a href="[article-url]">[button-desc]</a>
	 *            </p>
	 *     </div>
	 * </div>
	 *
	 * HTML structure - Navigation:
	 * <div class="banner-navigation">
	 *    <ul>
	 *        <li>
	 *            <div class="inner-navigation">
	 *               <div class="arrow">[arrow-name]</div>
	 *               <h3>[article-name]</h3>
	 *               <p>[banner-subject]</p>
	 *            </div>
	 *        </li>
	 *     </ul>
	 * </div>
	 *
	 * Example usage:
	 * $('[selector]').floatingBanners([settings])
	 *
	 * @param {obj} settings
	 */
	$.fn.floatingBanners = function(settings) {
		
		/**
		 * This function drives the animation. It fades in the banner,
		 * performs the ken burns effect, handles the navigation
		 * and handles the fadings
		 *
		 * @param {int} active - the number of the active item
		 * @param {obj} config - plugin configuration
		 * @param {obj} wrapper - banner wrapper
		 * @param {obj} navigation - banner navigation
		 */
		function driveAnimation(active, config, wrapper, navigation) {

			var box = wrapper.find('.banner-box:nth-child('+ active +')'),
				image = box.find('.banner-image'), timeout;

			/** Start animation */
			image.animate({
				'top': (config.interactionSpace * -1)
			}, config.animationTime, config.effect);

			return window.setTimeout(function() {

				navigation.find('li:nth-child('+active+').background').animate({
					'opacity': 0
				}, config.fadeOutSpeed);
				image.parent().fadeOut(config.fadeOutSpeed, function() {

					/** Check counter */
					active = active + 1;
					if(active > config._count) { active = 1; }

					/** Set active item in the navigation */
					navigation.find('.' + config.activeCls).removeClass(config.activeCls);
					navigation.find('li:nth-child(' + active + ')').addClass(config.activeCls);

					/** Fade in the new banner */
					wrapper.find('.banner-box:nth-child('+ active +')').fadeIn(config.fadeInSpeed, function() {

						/** Set the wrapper dimensions to the image (needed for the Ken Burns effect) */
						image.css({
							'top': 0
						});
					});
				});

			}, config.animationTime + 1500);
		}

		/** Default configuration */
		var config = {
			'activeCls': 'active',
			'arrowCls': 'arrow',
			'effect': 'linear',
			'animationTime': 8000,
			'fadeInSpeed': 1500,
			'fadeOutSpeed': 1500,
			'interactionSpace': 100,
			'_count': 0,
			'_interval': null,
			'_timeout': null
		};

		/** Extend the default configuration with the provided user settings */
		if(settings) { $.extend(config, settings); }

		/** Loop through all incoming elements and return this for jQuery's chaining support */
		return this.each(function() {

			/** Declaration */
			var wrapper = $(this),
				navigation = wrapper.next(),
				active = null;

			/** Get the total count of banners */
			config._count = wrapper.find('.banner-image').length;

			/** First of all hide all banners expect the first one */
			wrapper.find('.banner-box').hide();
			wrapper.find('.banner-box:first').show();
			active = 1;

			/** Set active menu item to active */
			navigation.find('li:first').addClass(config.activeCls);
			/** Start the animation of the first image */
			config._timeout = driveAnimation(active, config, wrapper, navigation);
			active++;

			/** Set interval to loop the animation */
			config._interval = window.setInterval(function() {

				/** Start animation for the next active image */
				config._timeout = driveAnimation(active, config, wrapper, navigation);
				active++;

				if(active > config._count) {
					active = 1;
				}

			}, config.animationTime);

			/** Loop through all navigation points and add an internal index to them */
			navigation.find('li').each(function(i, el) {
				$(this).data('index', i + 1);
			});

			/** Event listener which changes the actual image */
			navigation.find('li').bind('click', function() {
				var $me = $(this),
					box = wrapper.find('.banner-box:nth-child('+ (active - 1) +')'),
					image = box.find('.banner-image');

				/** Clear interval to stop all pending animations */
				clearInterval(config._interval);
				clearTimeout(config._timeout);
				image.stop(true, true);
				
				/** Fade out the active item */
				wrapper.find('.banner-box:visible').fadeOut(config.fadeOutSpeed / 2, function() {

					/** Set new active item in the navigation */
					navigation.find('.' + config.activeCls).removeClass(config.activeCls);
					navigation.find('li:nth-child(' + $me.data('index') + ')').addClass(config.activeCls);

					var next = wrapper.find('.banner-box:nth-child(' + $me.data('index') + ')');

					next.find('.banner-image').css('top', 0);

					/** Fade in the selected banner */
					next.fadeIn(config.fadeInSpeed / 2, function() {
						var image = wrapper.find('.banner-image:visible');

						image.animate({
							'top': (config.interactionSpace * -1)
						}, config.animationTime, config.effect);

					});
				});

			});
		});
	};
})(jQuery);

