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

		var intervalTimer = null;
		var isPlaying = false;

		var settings = $.extend( {
			id: null,
			interval: 3000,
			currentIndex: null,
			itemWidth: 238,
			itemHeight: 376,
			buttonNext: null,
			buttonPrev: null,
			focusedImageHook: null,
			focusedImageClickHook: function (event) {event.preventDefault();},
			onAnimationFinishHandler: function () {
				countAnimationStart--;

				if (countAnimationStart == 0 && onAnimationFinishHandler != null) {

					var onFinish = onAnimationFinishHandler;
					onAnimationFinishHandler = null;
					onFinish();
				}
			},
			autoplay: true
		}, options);
		
		var slidePanes		= [];
		var inAnimationPanes	= [];
		var countAnimationStart	= 0;
		var onAnimationFinishHandler = null;
		
		var animPositions = [
			{ // 0
				'z-index': 80,
				width: settings.itemWidth * 0.63,
				height: settings.itemHeight * 0.63,
				top: 100,
				left: 0
			},
			{ // 1
				'z-index': 90,
				width: settings.itemWidth * 0.86,
				height: settings.itemHeight * 0.86,
				top: 50,
				left: 89
			},
			{ // 2
				'z-index': 100,
				width: settings.itemWidth,
				height: settings.itemHeight,
				top: 16,
				left: 182
			},
			{ // 3
				'z-index': 90,
				width: settings.itemWidth * 0.86,
				height: settings.itemHeight * 0.86,
				top: 50,
				left: 308
			},
			{ // 4
				'z-index': 80,
				width: settings.itemWidth * 0.63,
				height: settings.itemHeight * 0.63,
				top: 100,
				left: 452
			},
			{ // 5
				'z-index': 0,
				width: settings.itemWidth * 0.5,
				height: settings.itemHeight * 0.5,
				top: 100,
				left: 250
			}
		];
		
		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 (event, focusedImageHookOff) {
			if (event != null)
				event.preventDefault()
			
			settings.currentIndex++;
			
			if (settings.currentIndex > slidePanes.length - 1) {
				settings.currentIndex = 0;
			}
			
			/* Animation Gears */
			var nextImageIndexForAnim = settings.currentIndex + 5;
			if (nextImageIndexForAnim >= slidePanes.length) {
				nextImageIndexForAnim = nextImageIndexForAnim - slidePanes.length;
			}
			inAnimationPanes.push($(slidePanes[nextImageIndexForAnim]));
			
			if ($(this).closest('.item').attr('rel') == 5) {
				
				onAnimationFinishHandler = $this.nextPane;
			}
			
			for (i in inAnimationPanes) {
				
				var options = null;
				
				var nextPosIndex = i - 1;
				if (nextPosIndex < 0)
					nextPosIndex = animPositions.length - 1;
				
				options = animPositions[nextPosIndex];
				
				inAnimationPanes[i].find('a').unbind('click', $this.prevPane);
				inAnimationPanes[i].find('a').unbind('click', $this.nextPane);
				inAnimationPanes[i].find('a').unbind('click', settings.focusedImageClickHook);
					
				if (i < 3) {
					
					inAnimationPanes[i].find('a').bind('click', $this.prevPane);
				}
				else if (i > 3) {
					
					inAnimationPanes[i].find('a').bind('click', $this.nextPane);
				} else {
					
					if (!focusedImageHookOff && settings.focusedImageHook != null && onAnimationFinishHandler == null) {
						
						settings.focusedImageHook(inAnimationPanes[i].find('a').click(settings.focusedImageClickHook));
					}
				}
				
				countAnimationStart++;
				
				var zIndex = options['z-index'];
				
				inAnimationPanes[i]
				.attr({rel: parseInt(i)})
				.css({'z-index': zIndex})
				.animate({
					width: options.width,
					height: options.height,
					top: options.top,
					left: options.left
				}, i == 0 ? 100 : 500, 'linear', settings.onAnimationFinishHandler );
			}
			
			inAnimationPanes.shift();
			
		}
		
		this.prevPane = function (event) {
			if (event != null)
				event.preventDefault()
			
			settings.currentIndex--;
			
			var nextImageIndexForAnim = settings.currentIndex + 1;
			
			if (settings.currentIndex < 0) {
				settings.currentIndex = slidePanes.length - 1;
			}
			
			/* Animation Gears */
			inAnimationPanes.unshift($(slidePanes[nextImageIndexForAnim]));
			
			if ($(this).closest('.item').attr('rel') == 1) {
				
				onAnimationFinishHandler = $this.prevPane;
			}
			
			for (i in inAnimationPanes) {
				if (i > slidePanes.length - 1)
					break;
				var options = null;
				
				var nextPosIndex = parseInt(i);
				
				options = animPositions[nextPosIndex];
				
				inAnimationPanes[i].find('a').unbind('click', $this.prevPane);
				inAnimationPanes[i].find('a').unbind('click', $this.nextPane);
				inAnimationPanes[i].find('a').unbind('click', settings.focusedImageClickHook);
					
				if (i < 2) {
					
					inAnimationPanes[i].find('a').bind('click', $this.prevPane);
				} else if (i > 2) {
					
					inAnimationPanes[i].find('a').bind('click', $this.nextPane);
				} else {
					
					if (settings.focusedImageHook != null && onAnimationFinishHandler == null) {
						settings.focusedImageHook(inAnimationPanes[i].find('a').click(settings.focusedImageClickHook));
					}
				}
				
				countAnimationStart++;
				
				var zIndex = options['z-index'];
				
				inAnimationPanes[i]
				.attr({rel: parseInt(i) + 1})
				.css({'z-index': zIndex})
				.animate({
					width: options.width,
					height: options.height,
					top: options.top,
					left: options.left
				},  i == 5 ? 100 : 500, 'linear', settings.onAnimationFinishHandler );
			}
			
			inAnimationPanes.pop();
			
		}
		
		this.nnAnimate = function (lastIndex) {
			
			//slidePanes[settings.currentIndex].animate({width: 100})
			//alert(lastIndex + ":" + settings.currentIndex);
			
		}
		
		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) {

					$(this)
					.css({
						'z-index': animPositions[i]['z-index'],
						width: animPositions[i].width,
						height: animPositions[i].height
					}).animate({
						top: animPositions[i].top,
						left: animPositions[i].left
					});

					if (i < 2) {
						$(this).find('a').bind('click', $this.prevPane);
					} else if (i > 2 && i < 5) {
						
						$(this).find('a').bind('click', $this.nextPane);
					}
					
					slidePanes[slidePanes.length] = $(this);
					
					if (i < 5) {

						inAnimationPanes.push($(this));
					}
				});
			
			if (slidePanes.length > 0) {
				settings.currentIndex = -1;
			}
			
			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();
		
		this.nextPane(null, true);
		
		return $this;
	};
})( jQuery );
