/*
 * Copyright (c) 2009 Cloudsca.pe <richard at cloudsca dot pe>
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * Provides automated and manual rotation through a collection of background
 * images. Each image can contain a caption
 */
(function($) {

	var backgroundCycleTimer;
	var currentBackgroundIndex = null;
	var settings;

	$.fn.backgroundRotator = function(options) {
		settings = $.extend({
			cycleInterval: 20000,
			cycleFadeSpeed: 2000,
			switchFadeSpeed: 500
		}, options);

		this.data("caption", $(settings.captionSelector));
		this.data("settings", settings);

		// Hook up the next/previous click events.
		var container = this;
		$(settings.nextBackgroundSelector)
		.click(function() {
			$.backgroundRotator.stopCycling(container);
			container.nextBackground(settings.switchFadeSpeed);
		});
		$(settings.previousBackgroundSelector)
		.click(function() {
			$.backgroundRotator.stopCycling(container);
			container.previousBackground(settings.switchFadeSpeed);
		});
		
		$.backgroundRotator.loadBackgrounds(this, settings);
	}

	$.fn.image = function(src, callback) {
		return this.each(function() {
			var i = new Image();
			i.onload = callback;
			i.src = src;
			this.appendChild(i);
		});
	}

	$.fn.nextBackground = function(fadeSpeed) {
		var backgrounds = this.children();
		var oldBackground = backgrounds.filter(".active");
		var oldBackgroundIndex = backgrounds.index(oldBackground);
		var newBackground = backgrounds.eq((oldBackgroundIndex + 1) % backgrounds.length);
		$.backgroundRotator.switchBackground(this, newBackground, fadeSpeed ? fadeSpeed : settings.switchFadeSpeed);
	}

	$.fn.previousBackground = function(fadeSpeed) {
		var backgrounds = this.children();
		var oldBackground = backgrounds.filter(".active");
		var oldBackgroundIndex = backgrounds.index(oldBackground);
		var newBackground = backgrounds.eq((oldBackgroundIndex + backgrounds.length - 1) % backgrounds.length);
		$.backgroundRotator.switchBackground(this, newBackground, fadeSpeed ? fadeSpeed : settings.switchFadeSpeed);
	}
	
	$.backgroundRotator = {	
	}

	$.backgroundRotator.loadBackgrounds = function(container, settings) {
		// Asynchronously load the background images.
		container
		.children()
		.shuffle()
		.each(function(backgroundIndex) {
			var background = $(this);
			var backgroundClass = background.attr("class").split(" ")[1];
			var backgroundImage = "/images/" + backgroundClass + ".jpg";

			background
			.addClass("loading")
			.css("background-image", "url(" + backgroundImage + ")")
			.image(backgroundImage, function() {
				background.removeClass("loading");

				if (backgroundIndex == 0) {
					$.backgroundRotator.switchBackground(container, background, settings.switchFadeSpeed, settings);
					$.backgroundRotator.startCycling(container, settings);
					
					if (settings.load != null) {
						settings.load();
					}
				}
			});
		});
	}

	$.backgroundRotator.startCycling = function(container, settings) {
		if (container.data("cycleTimer") == null) {
			container.data("cycleTimer", setInterval(function() {
				container.nextBackground(settings.cycleFadeSpeed);
			}, settings.cycleInterval));
		}
	}

	// Stops the background from automatically cycling.
	$.backgroundRotator.stopCycling = function(container) {
		if (container.data("cycleTimer") != null) {
			clearInterval(container.data("cycleTimer"));
			container.data("cycleTimer", null);
		}
	}

	$.backgroundRotator.switchBackground = function(container, newBackground, speed) {
		var oldBackground = container.children().filter(".active");

		// If we're changing backgrounds, ensure the old background has a lower z-index than the new background and fade it out.
		if (oldBackground != null) {
			oldBackground
			.removeClass("active")
			.css({"z-index": -5})
			.fadeOut(speed);
		}

		// Ensure the new background has a higher z-index than the old background and fade it in.
		newBackground
		.addClass("active")
		.css({"z-index": -4})
		.fadeIn(speed);

		// Copy the new background's caption into the background control area.
		var captionContent = newBackground.children(".caption").html();
		var captionContainer = container.data("caption");
		var oldCaption = captionContainer.children("div");
		var newCaption = $("<div>" + captionContent + "</div>");
		captionContainer.append(newCaption);

		if (oldCaption != null) {
			oldCaption
			.fadeOut(speed, function() {
				$(this).remove();
			})
		}

		newCaption
		.fadeIn(speed);
	}

})(jQuery);