(function($){
	$(function(){
		// optional images array, if empty will use just the elements already in slideshow div.
		var delay = 4000; /* Delay between animations */
		var fade = 1800; /* Duration of fade in animation */
		var curLayer = 'rand'; /* start from layer number */
		var zIndex = 2; /* z-index value. layers will use this value +/- 1 either side */
		var shownum = true; /* Show navigable image layer icons or not */
		// private variables do not change
		var timer = null;
		var activeIndex = 0;
		var icons = [];
		var slidewidth = $('#slideshow').width();
		var clickactive = true;
		/**
		 * Get childNode elements to be cycled though. Initialize with lowest zindex and 0 opacity.
		 */
		var layers = $('#slideshow').children().each(function(){
			$(this).css({zIndex: zIndex, left:slidewidth});
		});
		/**
		 * If curlayer is rand
		 */
		activeIndex = curLayer = curLayer == 'rand'? Math.floor(Math.random()*layers.length) : 0;
		/**
		 * Show numbers
		 */
		if(shownum && layers.length>2){
			nums = $('<div id="slideshownumbers"/>').appendTo($('#slideshow'));
			nums.css({zIndex: layers.length+zIndex});
			layers.each(function(i,item){
				var num = $('<span/>').appendTo(nums).html(i+1);
				num.bind('click',function(){
					if(activeIndex == i || !clickactive) return;
					clearTimeout(timer);
					$(layers[i]).css({'left':slidewidth,zIndex:zIndex-1});
					fadeInLayer(i, 900);
					curLayer = activeIndex = i;
				});
			});
			icons = $('span', nums);
			$(icons[activeIndex]).addClass('active');
		}
		/**
		 * Bring Layer to front and Fade in Animation with callback to cycleLayers.
		 */
		var fadeInLayer = function(i, speed){
			var speed = speed || fade;
			clearTimeout(timer);
			activeIndex = i;
			clickactive = false;
			$(layers[i]).css({zIndex:zIndex+1}).animate({'left':0}, speed, cycleLayers);
			$(layers[curLayer]).animate({'left':0-slidewidth}, speed, function(){ $(this).css({'left': slidewidth}); clickactive = true} );
			if(shownum && layers.length>2){
				$(icons).removeClass('active');
				$(icons[activeIndex]).addClass('active');
			}
		}
		/**
		 * Calculate next image, current image and previous image and layer zindex and opacity accordingly
		 */
		var cycleLayers = function(){
			var l = layers.length, c = curLayer;
			$(layers[c<=0?l-1:c-1]).css({'left':slidewidth, zIndex:zIndex-1});
			$(layers[c=curLayer=c>=l?0:c]).css({'left':0,zIndex:zIndex});
			timer = setTimeout(function(){ fadeInLayer(c+1==l?0:c+1); ++curLayer;}, delay);
		}
		/**
		 * Start the cycle layer process.
		 */
		if(layers.length > 1) cycleLayers(); else layers.css('left',slidewidth);
		
	});
})(jQuery);
