(function( $ ) {
	
	$.fn.nnSlideshow = function( options ) {

		var intervalTimer = null;
		var isPlaying = false;

		var settings = $.extend( {
			id: null,
			interval: 3000,
			currentIndex: null,
			effect: 'opacity', // Possible values: 'opacity', 'slide'
			itemWidth: 500,
			buttonNext: null,
			buttonPrev: null,
			autoplay: true
		}, options);
		
		var slidePanes = [];
		
		var $this = this;
		
		function genRandomString()    {
			
			var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
			var string_length = 16;
			var randomstring = '';
			for (var i=0; i<string_length; i++) {
				var rnum = Math.floor(Math.random() * chars.length);
				randomstring += chars.substring(rnum,rnum+1);
			}
			
			return randomstring;
		}
		
		this.nextPane = function () {
			
			var lastIndex = settings.currentIndex++;
			
			if (settings.currentIndex > slidePanes.length - 1) {
				settings.currentIndex = 0;
			}
			
			$this.nnAnimate(lastIndex);
		}
		
		this.prevPane = function () {
			
			var lastIndex = settings.currentIndex--;
			
			if (settings.currentIndex < 0) {
				settings.currentIndex = slidePanes.length - 1;
			}
			
			$this.nnAnimate(lastIndex);
		}
		
		this.nnAnimate = function (lastIndex) {
			
			if (settings.effect == "opacity") {
				
				slidePanes[lastIndex].animate({opacity: 0.1}, 500, 'swing', function () {
					$(this).hide();
					slidePanes[settings.currentIndex].css({opacity: 0.1}).show().animate({opacity: 1}, 500, 'swing', $this.nnAnimationEnd);
				});
			} else if (settings.effect == "slide") {
				
				$this.find(".wrapper").animate({left: -1 * settings.itemWidth * settings.currentIndex}, 500, 'swing', $this.nnAnimationEnd)
			}
		}
		
		this.nnAnimationEnd = function () {
			isPlaying = false;
		}
		
		this.playSlideshow = function () {
			
			if (isPlaying) return;
			
			$this.nextPane();
		}
		
		this.play = function () {
			
			this.pause();
			
			intervalTimer = setInterval(this.playSlideshow, settings.interval);
		}
		
		this.pause = function () {
			if (intervalTimer != null)
				clearInterval(intervalTimer);
			
			intervalTimer = null;
		}
		
		this.init = function () {
			
			settings.id = genRandomString();
			
			$(this)
				.attr({id: settings.id})
				.find('.item').each(function(i) {

					if (settings.effect == "opacity" && i > 0)
						$(this).hide();
					
					slidePanes[slidePanes.length] = $(this);
				});
			
			if (settings.effect == "slide") {
				
				settings.itemWidth = $(this).find('.item:first').width();
			}
			
			if (slidePanes.length > 0) {
				slidePanes[0].show();
				settings.currentIndex = 0;
			}
			
			if (settings.autoplay && settings.currentIndex != null) {
				this.play();
			}
			
			$(window).blur(function(){
				$this.pause();
			});
			$(window).focus(function(){
				
				if (settings.autoplay && settings.currentIndex != null) {
					$this.play();
				}

			});

			
			if (settings.buttonNext != null) {
				
				$(settings.buttonNext).click(function (event) {
					
					event.preventDefault();
					
					$this.pause();
					
					$this.nextPane();
				})
			}
			
			if (settings.buttonPrev != null) {
				
				$(settings.buttonPrev).click(function (event) {
					
					event.preventDefault();
					
					$this.pause();
					
					$this.prevPane();
				})
			}
		}
		
		/* init */
		this.init();
		
		return $this;
	};
})( jQuery );
