/* 
	slideshow v2.1 - 28/10/2010
*/ 
(function($){
	$.fn.slideshow = function(options){
		if($(this).length === 0){ return;}
		var defaults = {
			'speed'		:	1000,
			'interval'		:	5000,
			'loading'		:	true,
			'play-pause'	:	true,
			'next-prev-buttons':	true,
			'image-buttons'	:	true,
			'random'		:	false,
			'pause-on-hover':	false,
			'dimensions'	:	{} // internal
		},
		holder = $(this).addClass('slideshow-container'),
		imageData = {
			image:{},
			length:0,
			loaded:0,
			position: 0
		},
		slideTimer = $(this).data('slideTimer',null),
		slide = function(opts,reversed,preventContinue,imageData,offset){
			var
				i, item,
				slidingImg,
				originalImg = false,
				rotation = false;
			if(imageData.loaded>0){
				if(reversed === true){
					for(i=(offset >= 0 ? offset : imageData.position); i>=0; i--){
						if(imageData.image['pos_'+i].loaded === true){
							if(imageData.image['pos_'+i].displayed === false){
								for(item in imageData.image){
									if(imageData.image[item].displayed === true){
										originalImg = imageData.image[item].image;
										imageData.image[item].displayed = false;
										//break;
									}
								}
								imageData.image['pos_'+i].displayed = true;
								slidingImg = imageData.image['pos_'+i].image;
								rotation = true;
								rotate(slidingImg,originalImg,opts,i,preventContinue,imageData);
								break;
							}
						}
					}
					if(rotation === false){
						for(i=imageData.length-1; i>=0; i--){
							if(imageData.image['pos_'+i].loaded === true){
								if(imageData.image['pos_'+i].displayed === false){
									for(item in imageData.image){
										if(imageData.image[item].displayed === true){
											originalImg = imageData.image[item].image;
											imageData.image[item].displayed = false;
											//break;
										}
									}
									imageData.image['pos_'+i].displayed = true;
									slidingImg = imageData.image['pos_'+i].image;
									rotate(slidingImg,originalImg,opts,i,preventContinue,imageData);
									break;
								}
							}
						}
					}
				}else{
					for(i=(offset >= 0 ? offset : imageData.position); i<imageData.length; i++){
						if(imageData.image['pos_'+i].loaded === true){
							if(imageData.image['pos_'+i].displayed === false){
								for(item in imageData.image){
									if(imageData.image[item].displayed === true){
										originalImg = imageData.image[item].image;
										imageData.image[item].displayed = false;
										//break;
									}
								}
								imageData.image['pos_'+i].displayed = true;
								slidingImg = imageData.image['pos_'+i].image;
								rotation = true;
								rotate(slidingImg,originalImg,opts,i,preventContinue,imageData);
								break;
							}
						}
					}
					if(rotation === false){
						for(i=0; i<imageData.length; i++){
							if(imageData.image['pos_'+i].loaded === true){
								if(imageData.image['pos_'+i].displayed === false){
									for(item in imageData.image){
										if(imageData.image[item].displayed === true){
											originalImg = imageData.image[item].image;
											imageData.image[item].displayed = false;
											//break;
										}
									}
									imageData.image['pos_'+i].displayed = true;
									slidingImg = imageData.image['pos_'+i].image;
									rotate(slidingImg,originalImg,opts,i,preventContinue,imageData);
									break;
								}
							}
						}
					}
				}
			}
		},
		pauseSlide = function(){
			clearTimeout($(this).data('slideTimer'));
		},
		rotate = function(slidingImg,originalImg,opts,i, preventContinue,imageData){
			clearTimeout($(slidingImg).parents('.slideshow-container:first').data('slideTimer'));
			if(originalImg !== false){
				originalImg.css('z-index',0);
			}
			imageData.position = i;
			fire_changeImg.apply($(this), [slidingImg,originalImg,i]);
			slidingImg.css('z-index',1).css({
				'opacity'	:	0,
				'left'		:	0
			}).animate({opacity:1},opts.speed, function(){
				if(originalImg !== false){
					originalImg.css('left','-10000px');
				}
				if(preventContinue !== true){
					$(this).parents('.slideshow-container:first').data('slideTimer', setTimeout(function(){
							slide(opts,null,null,imageData);
						}, opts.interval)
					);
				}
			});
		},
		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;
		},
		slideshow = function(opts){
			opts.dimensions = {width:$(holder).width(), height:$(holder).height(), orientation: ( $(holder).width()<$(holder).height() ? 'p' : 'l' ) };
			var
			i = 0,
			imageList = [],
			liInHolder = $('ul', holder),
			buttonHolder;
			if(opts.random === true){
				$('ul', holder).each(function(){
					var items = $(this).children();
					liInHolder = $(this).html(shuffle(items));
				});
			}
			$('li',liInHolder).each(function(){
				imageList.push($(this).text());
				imageData.image['pos_'+i] = {
					url: $(this).text(),
					loaded: false,
					displayed: false
				};
				i++;
			});
			imageData.length = i;
			$(holder).css({
				'overflow'	:	'hidden',
				'position'	:	'relative'
			}).html('')
			// BIND TRIGGERS
			.bind('playPause', function(evt, button){trigger_playPause.apply($(this), [button,opts]);})
			.bind('nextPrev', function(evt, button){trigger_nextPrev.apply($(this), [button,opts]);})
			.bind('jumpTo', function(evt, button){trigger_jumpTo.apply($(this), [button,opts]);})
			.bind('jumpToImg', function(evt, opts, pos){slide(opts, null,false,$(this).data('imageData'), pos);})
			.bind('slide', function(evt, opts, reversed,preventContinue,imageData){slide(opts, reversed,preventContinue,$(this).data('imageData'));})
			.bind('pauseSlide', function(){pauseSlide.call($(this));})
			// DATA
			.data('imageData',imageData);
			for(i=0; i<imageList.length; i++){
				holder.append(imageLoader(imageList[i],opts,imageData));
			}
			// BUTTON LAYOUT
			buttonHolder = $('<div />')
				.addClass('slideshow_buttons')
				.css({
					'z-index'	:	2,
					'position'	:	'absolute'
				});
			if(opts['play-pause'] !== false){
				buttonHolder.append(
					$('<div />')
						.addClass('slideshow_playpause')
						.append(
							$('<span />')
								.append('<span class="slideshow_icon"><span>'+(typeof(opts['play-pause']) != 'boolean' ? opts['play-pause'][0] : '||')+'</span></span><span class="slideshow_text">Pause</span>')
								.click(function(){
									$(this).parents('.slideshow-container:first').trigger('playPause', $(this));
								})
						)
				)
			}
			if(opts['next-prev-buttons'] !== false){
				buttonHolder.append(
					$('<div />')
						.addClass('slideshow_nextprev')
						.append(
							$('<span />')
								.addClass('slideshow_prev')
								.append('<span class="slideshow_icon"><span>'+(typeof(opts['next-prev-buttons']) != 'boolean' ? opts['next-prev-buttons'][0] : '&#x25C2;')+'</span></span><span class="slideshow_text">Previous</span>')
								.click(function(){
									$(this).parents('.slideshow-container:first').trigger('nextPrev', $(this));
								})
						)
						.append(
							$('<span />')
								.addClass('slideshow_next')
								.append('<span class="slideshow_icon"><span>'+(typeof(opts['next-prev-buttons']) != 'boolean' ? opts['next-prev-buttons'][1] : '&#x25B8;')+'</span></span><span class="slideshow_text">Next</span>')
								.click(function(){
									$(this).parents('.slideshow-container:first').trigger('nextPrev', $(this));
								})
						)
				)
			}
			if(opts['next-prev-buttons'] !== false||opts['play-pause'] !== false){
				holder
					.append(
						buttonHolder
							.animate({opacity:0}, 800)
					)
					.mouseenter(function(){
						$('.slideshow_buttons', this).stop().animate({opacity:0.6}, 250);
					})
					.mouseleave(function(){
						$('.slideshow_buttons', this).stop().animate({opacity:0}, 800);
					});
			}
			if(opts['image-buttons'] === true){
				holder.append(
					$('<div />')
						.addClass('slideshow_imagebuttons')
				);
				for(i=0;  i<imageList.length; i++){
					$('.slideshow_imagebuttons',holder)
						.append(
							$('<span />')
								.addClass('slideshow_imagebutton')
								.addClass('slideshow_jump_'+i)
								.attr('rel',i)
								.append('<span class="slideshow_icon"><span>'+i+'</span></span><span class="slideshow_text">Jump To Image '+i+'</span>')
								.click(function(){
									$(this).parents('.slideshow-container:first').trigger('jumpTo', $(this));
								})
						)
				}
			}
			if(opts['pause-on-hover'] === true){
				holder
					.mouseenter(function(){
						$(this).trigger('pauseSlide');
					})
					.mouseleave(function(){
						$(this).trigger('slide', opts);
					});
			}
		},
		imageLoader = function(srcAttr, opts,imageData){
			var img = new Image(),
			tempHolder = $('<div />')
				.addClass('loading')
				.css({
					'position'	:	'absolute',
					'left'		:	'-10000px',
					'top'		:	0,
					'display'	:	'block'
				});
			$(img)
				.load(function(){
					tempHolder.removeClass('loading').append($(this));
					var
						item,
						dimensions = {
							height: $(this).height(),
							width: $(this).width(),
							orientation: ( $(this).width()<$(this).height() ? 'p' : 'l' )
						},
						xScale= dimensions.width/opts.dimensions.width,
						yScale= dimensions.height/opts.dimensions.height;
					if(xScale>yScale) {
						$(this).width(dimensions.width * (1/yScale));
						$(this).height(dimensions.height * (1/yScale));
					} else {
						$(this).width(dimensions.width * (1/xScale));
						$(this).height(dimensions.height * (1/xScale));
					}
					if($(this).height() > opts.dimensions.height){
						$(this).css({'margin-top':
							0-(($(this).height() - opts.dimensions.height) / 2)
						});
					}
					if($(this).width() > opts.dimensions.width){
						$(this).css({'margin-left':
							0-(($(this).width() - opts.dimensions.width) / 2)
						});
					}
					for(item in imageData.image){
						if(imageData.image[item].url == srcAttr){
							imageData.image[item].loaded = true;
							imageData.image[item].image = $(tempHolder);
							break;
						}
					} 
					fire_loadImg.apply($(this), [srcAttr]);
					imageData.loaded++;
					if(imageData.loaded===1){
						slide(opts,null,null,imageData);
					}
				})
				.error(function(){
					
				})
				.attr('src',srcAttr);
			return tempHolder;
		},

		/* METHODS */
		fire_changeImg = function(slidingImg,originalImg,pos){
			$(slidingImg).parents('.slideshow-container').find('.slideshow_imagebuttons > span').removeClass('selected');
			$(slidingImg).parents('.slideshow-container').find('.slideshow_jump_'+pos).addClass('selected');
		},
		fire_loadImg = function(srcAttr){
			//console.log('loaded: '+srcAttr);
		},

		/* BUTTONS */
		trigger_playPause = function(button,opts){
			if($('.slideshow_text',button).text() == 'Pause'){
				$(this).trigger('pauseSlide');
				$('.slideshow_text',button).text('Play');
				$('.slideshow_icon span',button).html((typeof(opts['play-pause']) != 'boolean' ? opts['play-pause'][1] :'&#x25B6;'));
			}else{
				$('.slideshow_text',button).text('Pause');
				$('.slideshow_icon span',button).html((typeof(opts['play-pause']) != 'boolean' ? opts['play-pause'][0] : '||'));
				$(this).trigger('slide', opts);
			}
		},
		trigger_nextPrev = function(button,opts){
			if($('.slideshow_text',button).text() == 'Next'){
				$(this).trigger('slide', [opts, false, true]);
				$(this).trigger('pauseSlide');
				$('.slideshow_playpause .slideshow_text',this).text('Play');
				$('.slideshow_playpause .slideshow_icon span',this).html((typeof(opts['play-pause']) != 'boolean' ? opts['play-pause'][1] :'&#x25B6;'));
			}else{
				$(this).trigger('slide', [opts, true, true]);
				$(this).trigger('pauseSlide');
				$('.slideshow_playpause .slideshow_text',this).text('Play');
				$('.slideshow_playpause .slideshow_icon span',this).html((typeof(opts['play-pause']) != 'boolean' ? opts['play-pause'][1] :'&#x25B6;'));
			}
		},
		trigger_jumpTo = function(button,opts){
			// 
			$(this).trigger('pauseSlide');
			$(this).trigger('jumpToImg', [opts, parseInt($(button).attr('rel'), 10)]);
		};

		/* INIT */
		$(this).each(function(){
			$.extend(defaults, options);
			var sl = new slideshow(defaults);
		});
		return this;
	};
})(jQuery);

