/**
 * Autor 	 : the LSI team
 * Creation date : 2011-05-09
 * Version 	 : 1.0
 * Description 	 : Images slideshow
 */


(function($) {

		// jQuery plugin definition
		$.fn.lsiSlideshow = function(params) {

			var wrapper = $(this);

			// merge the default value with custom params
			params = $.extend({
					delay            : 2000,
					speed            : 5000,
					interval         : 1000,
					childrenSelector : 'li',
					containerHeight  : null,
					effect           : 'fade',
					squareEffect     : "fade",
					squareOrder      : "random",
					squareSize       : 100,
					squareParallel   : 5
				}, params); 

			params.speed    = parseInt(params.speed, 10);
			params.delay    = parseInt(params.delay, 10);
			params.interval = parseInt(params.interval, 10);

			if (params.size) {
				if (params.size == "viewport") {
					params.containerWidth  = $(window).width();
					params.containerHeight = $(window).height();
					var wrapperResize = function() {
						wrapper.css({
								width  : $(window).width(),
								height : $(window).height()
							});
					};
					wrapperResize();
					$(window).resize(wrapperResize);
				} else {
					var matches = params.size.match(/(\d+)x(\d+)/);
					if (matches) {
						params.containerWidth  = matches[1];
						params.containerHeight = matches[2];
					}
				}
			}

			if (!params.containerHeight)
				params.containerHeight = $(this).outerHeight();

			if (!params.containerWidth)
				params.containerWidth = $(this).outerWidth();

			if (params.imgsize == "adapt") {
				
					
				
				var adapt = function() {
					
					
					wrapper.find('img').each(function(idx, img) {
						
							// get real image w/h 
							var img2 = new Image();
							img2.onload = function() {
										
								
								var iw = img2.width, ih = img2.height;
								delete img2;
								var ir = ih/iw;
								var ww = Math.round(wrapper.width());
								var wh = Math.round(wrapper.height());
								var wr = wh/ww;

								// margins
								var ml = 0;
								var mt = 0;
								
								iw = ww;
								ih = Math.round(ww * ir);

								if(ih < wh){
									ih = wh;
									iw = Math.round(ih / ir);
								}
							
								ml = Math.round((ww - iw)/2);

								mt = Math.round((wh - ih) / 2);
								

								$(img).css({
										width      : iw,
										height     : ih,
										marginLeft : ml,
										marginTop  : mt
									});

						
							};

							img2.src = img.src;
							
					});
				};
				
				adapt();
				$(window).resize(adapt);
			}

			if (!params.containerHeight)
				params.containerHeight = $(this).outerHeight();

			// Children (images) to animate
			var children = $(this).children(params.childrenSelector);
			var nbChildren = children.length;

			// No animation, not enought children
			if (nbChildren <= 1)
				return;

			// Current element index
			var currentIdx = 0;

			// Current and Previous element showed
			var currentEl = null;
			var previousEl = null;

			// Zindex is based on first child
			var baseZindex = $(children[0]).css('z-index');
			if (baseZindex == "auto")
				baseZindex = 0;

			// hide all elements (but the first)
			children.each(function(i, el) {$(el).css({
							opacity    : (i === 0 ? 1 : 0),
							position   : "absolute",
							top        : 0,
							left       : 0,
							zIndex     : baseZindex,
							visibility : "visible"
						});
				});

			var animate = function() {

				animationEffects[params.effect]();

			};

			currentEl = $(children[currentIdx]);

			setTimeout(animate, params.delay);

			var putPrevOnTop = function() {
				if (previousEl) {
					previousEl.css({
							zIndex : 0
						});
				}
				currentIdx = (currentIdx + 1) % nbChildren;
				previousEl = currentEl;
				currentEl = $(children[currentIdx]);

				if (previousEl)
					previousEl.css({zIndex : baseZindex + 2});

				currentEl.css({
						opacity : 1,
						zIndex  : baseZindex + 1,
						top     : 0
					});
			};

			var putCurrentOnTop = function() {

				if (previousEl) {
					previousEl.css({
							zIndex : 0
						});
				}
				currentIdx = (currentIdx + 1) % nbChildren;
				previousEl = currentEl;
				currentEl = $(children[currentIdx]);

				if (previousEl)
					previousEl.css({zIndex : baseZindex + 1});

				currentEl.css({
						opacity : 0,
						zIndex  : baseZindex + 2,
						top     : 0
					});
				
			};

			var animationEffects = {

				fade : function() {

					putCurrentOnTop();

					currentEl.animate({ 
							opacity : 1
						}, {
							duration : params.speed,
							complete : function() {
								setTimeout(animate, params.interval);
							}
						});

				},

				fadeAndSlide : function() {

					putCurrentOnTop();

					var heightDiff = currentEl.height() - params.containerHeight - 5;
					if (heightDiff < 0)
						heightDiff = 0;

					currentEl.animate({ 
							opacity : 1
						}, {
							duration : params.speed / 3
						}).
					animate({
							top   : -heightDiff
						}, {
							queue    : false,
							duration : params.speed / 1,
							complete : function() {
								setTimeout(animate, params.interval);
							}
						});

				},

				squared : function() {

					putPrevOnTop();

					var parallel = parseInt(params.squareParallel, 10);
					var squareSize = parseInt(params.squareSize, 10);
					var numSquaresW = Math.ceil(wrapper.width() / squareSize);
					var numSquaresH = Math.ceil(wrapper.height() / squareSize);
					var numSquares = Math.ceil(numSquaresW * numSquaresH);
					var squares =  [];
					var imgUrl = previousEl.find('img:first').attr("src");

					for (i = 0; i < numSquares; i++) {
						var square = $('<div></div>');
						squares.push(square);
						var offsets = {
							top : i%numSquaresH * squareSize,
							left : Math.floor(i/numSquaresH) * squareSize
						};
						square.css({
								position           : 'absolute',
								left               : offsets.left,
								top                : offsets.top,
								backgroundPosition : "-"+offsets.left+"px -"+offsets.top+"px",
								backgroundImage    : "url("+imgUrl+")",
								width              : squareSize + "px",
								height             : squareSize + "px",
								zIndex             : baseZindex + 3
							});
						wrapper.append(square);
					}

					previousEl.css({
							opacity:0
						});

					var squaresIdx = [];
					for (i = 0; i < numSquares; i++) {
						squaresIdx.push(i);
					}

					squaresIdx = squareOrders[params.squareOrder](squaresIdx);

					var currentSquare = 0;

					var hideNextSquare = function() {
						var square = squares[squaresIdx[currentSquare]];
						if (!square) return;

						squareEffects[params.squareEffect](square);

						currentSquare++;

						if (currentSquare < numSquares) {

							setTimeout(hideNextSquare, (params.speed / numSquares) * parallel);

						} else {

							// clean squares
							for (i = 0; i < numSquares; i++) {
								squares[i].remove();
								delete(squares[i]);
								delete(squares);
							}
							delete(squaresIdx);

							wrapper.find('.ui-effects-wrapper').remove();

							setTimeout(animate, params.interval);

						}
					};

					var startAnim = function() {
						var i;
						for (i = 0; i < parallel; i++) {
							hideNextSquare();
						}
					};

					startAnim();

				}

			};

			var squareEffects = {

				fade : function(square) {
					square.fadeOut();
				},

				slideUp : function(square) {
					square.animate({
							top     : 0,
							opacity : 0
						});
				},

				spreadOut : function(square) {
					square.animate({
							left    : Math.cos(Math.random()*360) * wrapper.width(),
							top     : Math.sin(Math.random()*360) * wrapper.height(),
							opacity : 0
						});
				},

				scaleAndPuff : function(square) {
						square.effect('scale', {percent:50}, 200).
						effect('puff', {percent:0});
				}

			};

			var squareOrders = {

				none : function(idxs) {
					return idxs;
				},

				random : function(idxs) {
					idxs.sort(function() {return (Math.round(Math.random())-0.5);});
					return idxs;
				}

			};

		};

	})(jQuery);



