/*
 * Slideshow jQuery plugin with animated strips
 * Author: Dmytro Danylov
 */
(function($) {	
	// Slider class
	function dmSlider(container, options)
	{
		// Define default options
		this.options = $.extend(
		{
			animation: 'random',
			speed: 400,
			autoScrollInterval: 5000,
			autoScroll: false
		}, options);
		
		delete options;
		
		// Define common variables
		this.prev = 0;
		this.current = 0;
		this.container = $(container);
		this.interval = null;
		this.iterator = 0;
		this.direction = 1;
		this.autoScrollInterval = null;
		this.speed = Math.ceil(this.options.speed / 6);
		this.rand = 0;
		this.stripsIdx = [];
		this.strips = [];
		this.images = [];
		this.wait = false;
		this.stop = false;
		
		var that = this;
		
		// Get height, width, and strip width, number of strips, and animation
		var classes = container.className.split(/\s/);
		var params;
		for (var i = 0; i < classes.length; ++i)
		{
			if (classes[i].search(/^[0-9]{1,4}x[0-9]{1,4}x[0-9]{1,2}(x[a-z]{2,})?$/i) != -1)
			{
				params = classes[i];
				break;
			}
		}
		var size = params.match(/[0-9]{1,4}/g);
		this.width = parseInt(size[0]);
		this.height = parseInt(size[1]);
		this.stripsNum = parseInt(size[2]);
		this.stripW = parseInt(this.width / this.stripsNum);
		
		var animation = params.match(/[a-z]{2,}/);
		if (animation !== null)
			this.options.animation = animation[0].substring(1);
		
		// Get the slideshow items
		var ul = this.container.children('ul:first');
		this.items = ul.children();
		
		// Hide all images and build a list of images' urls
		this.items = ul.children();
		var i = 0;
		this.items.each(function() {
			var li = $(this);
			var img = li.children('img:first');
			that.images[i] = img.attr('src');
			img.hide();
			if (i > 0)
				li.css('display', 'none');
			++i;
		});
		this.imagesMax = i;
		
		// Prepare required css
		this.container.css({'background-image': 'url('+this.images[this.current]+')', 'position': 'relative',
			height: this.height, width: this.width});
		ul.css({position: 'absolute', 'z-index': 7, bottom: 0, left: 0, width: '100%', 'opacity': 0});
		
		// Create strips
		var posX = 0;
		var marginLeft = 1;
		var tempW = -this.width / 2;
		var plus = false;
		for (var i = 0; i < this.stripsNum; ++i)
		{
			if (marginLeft == 0)
			{
				plus = true;
				marginLeft = 0;
			}
			
			if (plus == false)
				marginLeft = tempW + posX;
			else
				marginLeft += this.stripW;
			
			this.strips[i] = $('<div class="slideshow_strip"></div>');
			this.strips[i].css({
				'background-position': -posX+'px top',
				'background-repeat': 'no-repeat',
				'height': this.height,
				'width': this.stripW + 'px',
				'position': 'absolute',
				'top': 0,
				'left': posX
			});
			this.container.append(this.strips[i]);
			posX += this.stripW;
			this.stripsIdx[i] = i;
		}
		
		var controlsContainer = this.container.children('.slideshow_controls:first');
		var controls = controlsContainer.children('a');
		
		controlsContainer.css('opacity', 0);
		
		this.container.hover(function()
		{
			controlsContainer.stop().animate({opacity: 1}, 'fast');
			ul.stop().animate({opacity: .9}, 'fast');
			that.stop = true;
		}, function()
		{
			controlsContainer.stop().animate({opacity: 0}, 'fast');
			ul.stop().animate({opacity: 0}, 'fast');
			that.stop = false;
		});
		
		controls.eq(0).bind('click', function(event) {
			event.preventDefault();
			that.changeImage(that.options.animation, 'prev');
		});
		
		controls.eq(1).bind('click', function(event) {
			event.preventDefault();
			var a = $(this);
			if (a.hasClass("start"))
			{
				that.startAutoScroll();
				a.removeClass("start").addClass("pause");
			}
			else
			{
				that.stopAutoScroll();
				a.removeClass("pause").addClass("start");
			}
		});
			 
		controls.eq(2).bind('click', function(event) {
			event.preventDefault();
			that.changeImage(that.options.animation, 'next');
		});
		
		// Initialize auto scrolling
		if (this.options.autoScroll == true)
		{
			this.startAutoScroll();
			controls.eq(1).removeClass("start").addClass("pause");
		}
		
		this.changeInfo();
	};
	
	// Initialize(prepare) the object
	dmSlider.prototype.shuffle = function(arr)
	{
		for(
	      var j, x, i = arr.length; i;
	      j = parseInt(Math.random() * i),
	      x = arr[--i], arr[i] = arr[j], arr[j] = x
	    );
	    return arr;
	};
	
	dmSlider.prototype.changeInfo = function()
	{
		var that = this;
		this.items.eq(this.current).stop().css({'display': 'block', 'opacity': 0}).animate({opacity: .9}, this.options.speed, function()
		{
			that.wait = false;
		});
	};
	
	dmSlider.prototype.setBackground = function()
	{
		// Set background of container to the previous image
		this.container.css('background-image', 'url('+this.images[this.prev]+')');
	};
	
	dmSlider.prototype.changeImage = function(anim, dir)
	{
		if (this.wait == true)
			return;

		this.wait = true;
		this.iterator = 0;
		this.prev = this.current;
		
		// Hide current info
		this.items.eq(this.current).css('display', 'none');
		
		// Find the next and prev image
		if (dir == 'next')
		{
			this.current += 1;
			this.current = (this.current >= this.imagesMax) ? 0 : this.current;
			this.direction = 1;
		}
		else
		{
			this.current -= 1;
			this.current = (this.current < 0) ? this.imagesMax - 1 : this.current;
			this.direction = 0;
			this.iterator = this.stripsNum - 1;
		}
		
		// Select animation
		switch (anim)
		{
			case 'fall':
				this.animFall();
				break;
				
			case 'fade':
				this.animFade();
				break;
				
			case 'fadeStrips':
				this.animFadeStrips();
				break;
			
			case 'fadeRandomStrips':
				this.animFadeRandomStrips();
				break;
				
			case 'curtain':
				this.animCurtain();
				break;
				
			case 'random':
				var animNum = Math.floor(Math.random() * 5);
				switch (animNum)
				{
					case 0:
						this.animFall();
						break;
					case 1:
						this.animFade();
						break;
					case 2:
						this.animFadeStrips();
						break;
					case 3:
						this.animFadeRandomStrips();
						break;
					case 4:
						this.animCurtain();
						break;
				}
				break;
		}
	};
	
	dmSlider.prototype.animFade = function()
	{
		this.setBackground();
		var fadeSpeed = this.options.speed * 2;
		var lastStrip = this.stripsNum - 1;
		for (var i = 0; i < lastStrip; ++i)
		{
			this.strips[i].css({'background-image': 'url('+this.images[this.current]+')', 'opacity': 0});
			this.strips[i].animate({opacity: 1}, fadeSpeed);
		}
		var that = this;
		this.strips[lastStrip].css({'background-image': 'url('+this.images[this.current]+')', 'opacity': 0});
		this.strips[lastStrip].animate({opacity: 1}, fadeSpeed, function()
		{
			that.changeInfo();
		});
	};
	
	dmSlider.prototype.animCurtain = function()
	{
		this.setBackground();
		this.iterator = 0;
		var that = this;
		this.interval = setInterval(function() {
			if (that.iterator == that.stripsNum)
			{
				clearInterval(that.interval);
				that.changeInfo();
				return false;
			}
			
			that.strips[that.iterator].css({'background-image': 'url('+that.images[that.current]+')', 'width': 0, 'opacity': 0});
			that.strips[that.iterator].animate({opacity: 1, width: that.stripW}, that.options.speed);
			
			++that.iterator;
		}, this.speed);
	};
	
	dmSlider.prototype.animFadeStrips = function()
	{
		this.setBackground();
		var that = this;
		this.interval = setInterval(function() {
			if ((that.direction == 1 && that.iterator == that.stripsNum) || (that.direction == 0 && that.iterator < 0))
			{
				clearInterval(that.interval);
				that.changeInfo();
				return false;
			}
			that.strips[that.iterator].css({'background-image': 'url('+that.images[that.current]+')', 'opacity': 0});
			that.strips[that.iterator].animate({opacity: 1}, that.options.speed);
			if (that.direction == 1)
				++that.iterator;
			else
				--that.iterator;
		}, this.speed);
	};
	
	dmSlider.prototype.animFadeRandomStrips = function()
	{
		this.setBackground();
		this.iterator = 0;
		this.stripsIdx = this.shuffle(this.stripsIdx);
		var that = this;
		
		this.interval = setInterval(function()
		{
			if (that.iterator == that.stripsNum)
			{
				clearInterval(that.interval);
				that.changeInfo();
				return false;
			}
			
			that.strips[that.stripsIdx[that.iterator]].css({'background-image': 'url('+that.images[that.current]+')', 'opacity': 0 });
			that.strips[that.stripsIdx[that.iterator]].animate({opacity: 1}, that.options.speed);
			
			++that.iterator;
		}, this.speed);
	};
	
	dmSlider.prototype.animFall = function()
	{
		this.setBackground();
		var that = this;
		
		this.interval = setInterval(function() {
			if ((that.direction == 1 && that.iterator == that.stripsNum) || (that.direction == 0 && that.iterator < 0))
			{
				clearInterval(that.interval);
				that.changeInfo();
				return false;
			}
			that.strips[that.iterator].css({'background-image': 'url('+that.images[that.current]+')', 'height': 0, 'opacity': 0});
			that.strips[that.iterator].animate({height: that.height, opacity: 1}, that.options.speed);
			if (that.direction == 1)
				++that.iterator;
			else
				--that.iterator;
		}, this.speed);
	};
	
	dmSlider.prototype.startAutoScroll = function()
	{
		var that = this;
		this.autoScrollInterval = setInterval(
			function() {
				if (that.stop == false)
					that.changeImage(that.options.animation, 'next');
			},
			this.options.autoScrollInterval
		);
	};
	
	dmSlider.prototype.stopAutoScroll = function()
	{
		clearInterval(this.autoScrollInterval);
	};
	
	$.fn.slideshow2 = function(options) {
		this.each(function()
		{
			var DmSlider = new dmSlider(this, options);
		});
	};
})(jQuery);
