"use strict";

/*global jQuery */

(function ($) {

	$.fn.jshow = function (options) {

	return this.each(function () {

		var init, setupStage, injectClassnames, assignCurrent, injectControls, createElement, setDimensions, setDimensions_Fade, setDimensions_Scroll,

			pause, play, goTo, findIndex, findNextIndex, findPrevIndex, findItem, updateIndexes, animate, fade, scroll, arrayValueExists,

			container = this,
                        songiang = this,
			innerContainer,

			itemsArray = [],

			counters = {

				currentIndex: 0,

				nextIndex: 1,

				itemCount: 0

			},

			defaults = {

				effect: "fade", // Transition effect ['fade' | 'scroll']

				transitionSpeed: 1000, // Transition speed

				transitionInterval: 4000, // Interval time between transitions

				controls: [] // Slideshow controls to display ['pause', 'first', 'previous', 'items', 'next', 'last']

			},

			settings = $.extend(defaults, options),

			markup = {

				innerContainer: function (effect) {

					return '<div class="inner-container ' + effect + '"></div>';

				},

				controlsContainer: function () {

					return '<div class="controls"><ul></ul></div>';

				},

				controlItem: function (item) {

					return '<li class="control-' + item.type + ((item.classname) ? ' ' + item.classname : '') + '"><a href="#" title="' + item.title + '">' + item.title + '</a></li>';

				}

			},

			allowedControls = {

				fade: ['first', 'previous', 'items', 'next', 'last', 'pause'],

				scroll: ['previous', 'next', 'pause']

			},

			buttonClicked = "", buttonsLocked = false, slideshowPaused = false,

			controlsContainer;

		

		init = function () {

			setupStage();

			play();

		};

		

		setupStage = function () {

			injectClassnames();

			setDimensions();

			injectControls();

		};

		

		injectClassnames = function () {

			$(container).addClass("slideshow-generated");

			$(container).children("DIV").wrapAll(markup.innerContainer(settings.effect));

			innerContainer = $("DIV.inner-container", container);

			$(innerContainer).children("DIV:first").addClass("current").css({"z-index": "2"});

			$(innerContainer).children("DIV").each(function (index) {

				itemsArray.push($(this)[0]);

				$(this).addClass("slide slide-" + (index + 1));

			});

			counters.itemCount = itemsArray.length;

		};

		

		assignCurrent = function () {

			var nextItem = findItem(counters.nextIndex),

				nextControlItem = $(".control-" + (counters.nextIndex + 1), container);

			$(".current", container).removeClass("current");

			$(nextItem).addClass("current");

			$(nextControlItem, container).addClass("current");

		};

		

		injectControls = function () {

			var item, controls, i, j;

			if (settings.controls !== undefined && settings.controls.length > 0) {

				controlsContainer = $(markup.controlsContainer());

				$(container).append(controlsContainer);

				controls = settings.controls;

				for (i = 0; i < controls.length; i = i + 1) {

					if (arrayValueExists(allowedControls[settings.effect], controls[i])) {

						if (controls[i] === "items") {

							for (j = 1; j <= counters.itemCount; j = j + 1) {

								item = {type: j, title: j, index: j - 1, classname: 'item'};

								if (j === 1) {

									item.classname = "item current";

								}

								createElement(item);

							}

						}

						else {

							item = {type: controls[i], title: controls[i].slice(0, 1).toUpperCase() + controls[i].slice(1)};

							createElement(item);

						}

					}

				}

			}

		};

		

		createElement = function (item) {

			var element = $(markup.controlItem(item));

			$("UL", controlsContainer).append(element);

			$(element).click(function () {

				if (!buttonsLocked) {

					buttonClicked = item.type;

					if (item.type === "pause") {

						if ($(this).hasClass("control-pause")) {

							pause();

							$(this).removeClass("control-pause").addClass("control-play").children("A").text("Play").attr("title", "Play");

							slideshowPaused = true;

						}

						else {

							play();

							$(this).removeClass("control-play").addClass("control-pause").children("A").text("Pause").attr("title", "Pause");

							slideshowPaused = false;

						}

					}

					else {

						pause();

						goTo(findIndex(item));

						if (!slideshowPaused) {

							play();

						}

					}

				}

				return false;

			});

		};

		

		setDimensions = function () {

			switch (settings.effect) {

			case "fade":

				setDimensions_Fade();

				break;

			case "scroll":

				setDimensions_Scroll();

				break;

			}

		};

		

		setDimensions_Fade = function () {

			var divsArray = [],

			widest = 0, heighest = 0, i;

			$(innerContainer).css({position: 'relative'});

			$(innerContainer).children("DIV").each(function () {

				var width, height;

				width = $(this).width();

				height = $(this).height();

				if (width > widest) {

					widest = width;

				}

				if (height > heighest) {

					heighest = height;

				}

				$(this).css({

					position: 'absolute',

					top: '0px',

					left: '0px',

					display: 'none'

				});

				divsArray.push(this);

			});

			$(findItem(counters.currentIndex)).show();

			$(innerContainer).width(widest).height(heighest);

			for (i = 0; i < divsArray.length; i = i + 1) {

				$(divsArray[i]).width(widest).height(heighest);

			}

		};

		

		setDimensions_Scroll = function () {

			var divsArray = [],

			widest = 0, heighest = 0, count = 0, fullWidth, i;

			$(innerContainer).children("DIV").each(function () {

				var width, height;

				$(this).css({

					'float': 'left'

				});

				width = $(this).width();

				height = $(this).height();

				if (width > widest) {

					widest = width;

				}

				if (height > heighest) {

					heighest = height;

				}

				divsArray.push(this);

				count = count + 1;

			});

			fullWidth = widest * count;

			$(container).css({width: widest, overflow: "hidden", position: "relative"});

			$(innerContainer).css({width: fullWidth, height: heighest, position: "relative", left: 0});

			for (i = 0; i < divsArray.length; i = i + 1) {

				$(divsArray[i]).width(widest).height(heighest);

			}

		};

		

		pause = function () {

			clearInterval(songiang.interval);
 
		};



		play = function () {

			songiang.interval = setInterval(function () {

				goTo();

			}, settings.transitionInterval);

		};



		goTo = function (nextIndex) {

			counters.nextIndex = (nextIndex !== undefined) ? nextIndex : findNextIndex();

			if (counters.currentIndex !== counters.nextIndex) {

				assignCurrent();

				animate();

			}

		};

		

		findIndex = function (item) {

			var index;

			switch (item.type) {

			case "first" :

				index = 0;

				break;

			case "last" :

				index = counters.itemCount - 1;

				break;

			case "previous" :

				index = findPrevIndex();

				break;

			case "next" :

				index = findNextIndex();

				break;

			default :

				index = item.index;

				break;

			}

			return index;

		};

		

		findNextIndex = function () {

			var index = counters.currentIndex + 1;

			index = (index > itemsArray.length - 1) ? 0 : index;

			return index;

		};

		

		findPrevIndex = function () {

			var index = counters.currentIndex - 1;

			index = (index < 0) ? itemsArray.length - 1 : index;

			return index;

		};

		

		findItem = function (index) {

			return itemsArray[index];

		};

		

		updateIndexes = function () {

			counters.currentIndex = counters.nextIndex;

		};



		animate = function () {

			var currentItem = findItem(counters.currentIndex),

				nextItem = findItem(counters.nextIndex);

			buttonsLocked = true;

			

			if (settings.effect === "fade") {

				fade(currentItem, nextItem);

			}

			else if (settings.effect === "scroll") {

				scroll();

			}

			buttonClicked = "";

		};

		

		fade = function (currentItem, nextItem) {

			$(nextItem).css({"z-index": "1"}).show();

			$(currentItem).fadeOut(settings.transitionSpeed, function () {

				$(this).css({"z-index": "0"});

				$(nextItem).css({"z-index": "2"});

				updateIndexes();

				buttonsLocked = false;

			});

		};

		

		scroll = function () {

			var animateTo, blockWidth;

			blockWidth = $(innerContainer).children("DIV.slide:first").outerWidth(true);

			animateTo = blockWidth * -1;

			

			if (buttonClicked === "previous") {

				$(innerContainer).children("DIV.slide:last").prependTo(innerContainer);

				$(innerContainer).css({

					left: blockWidth * -1

				});

				$(innerContainer).animate(

					{left: 0},

					settings.transitionSpeed, function () {

						updateIndexes();

						buttonsLocked = false;

					}

				);

			}

			else {

				$(innerContainer).animate(

					{left: animateTo},

					settings.transitionSpeed, function () {

						$(innerContainer).children("DIV.slide:first").appendTo(innerContainer);

						$(innerContainer).css({

							left: 0

						});

						updateIndexes();

						buttonsLocked = false;

					}

				);

			}

		};

		

		arrayValueExists = function (array, obj) {

			var i;

			for (i = 0; i < array.length; i = i + 1) {

				if (array[i] === obj) {

					return true;

				}

			}

			return false;

		};

		

			init();

	});

	};

}(jQuery));
