(function($) {
	var slides = [];
	var currentIndex = null;
	var timeout = null;
	var halted = false;
	
	var $selector = null;
	
	$.fn.tpSlideshow = function(settings, slideSettings) {

		if(!settings || !slideSettings) throw "tpSlideshow: Specify both settings and slide settings";

		var isIeLt9 = document.all ? true : false;
		
		var defaultSettings = {
			selector : true,
			selectorimgActive : null,
			selectorimgInactive : null,
			preload : 'single'
		};

		var defaultSlideSettings = {
			preloaded : false,
			fadeDuration : 1000,
			duration : 10000,
			image : null,
			link : null,
			target : '_self'
		};
		
		$.extend(defaultSettings, settings);
		settings = defaultSettings;
		
		for(i in slideSettings) {
			var s = slides[slides.length] = {};
			$.extend(s, defaultSlideSettings, slideSettings[i]);
		}
		
		var $target = this;
		
		init();
		
		function init() {
			if(settings.selector) {
				initSelector();
				bindSelectorEvents();
			}
			showSlide(0);			
		}
		
		function showSlide(index, timeout) {
			if(halted && timeout) {
				activateTimeout();
				return;
			}
			
			if(index > slides.length - 1) return; 
			var slide = slides[index];
			currentIndex = index;
			
			if(!slide.preloaded) {
				preload();
				return;
			}			
			
			$current = $target.children('img');
			
			$next = $('<img class="img_'+ index +'" src="'+ slide.image +'" />');
			$next.css({
				display: 'none',
				position: 'absolute',
				top: 0,
				left: 0
			});

			$target.append($next);
			
			if(slide.link) {
				$next.css({'cursor' : 'pointer'});
				$next.click(function(e) {
					var index = parseInt($(e.target).attr('class').substring(4));
					var slide = slides[index];
					if(slide.target == '_blank') {
						window.open(slide.link);
					} else {
						location.href = slide.link;
					}
				});
			}
			
			$target.outerHeight($next.outerHeight());
			
			if(slides.length > 1) {			
				$next.fadeIn(slide.fadeDuration, function() {
					$current.remove();
					$current = $next;
					if(settings.selector) {
						bindSelectorEvents();
						renderSelectorItems();
					}	
					activateTimeout();
				});
			} else {
				$next.css({
					display : 'block'
				});
			}
				
		}

		function activateTimeout() {
			clearTimeout(timeout);
			timeout = setTimeout(function() {
				showSlide((currentIndex + 1) % slides.length, true);
			}, slides[currentIndex].duration);
		}


		function preload() {
			var image = $('<img />')
				.load(function() { 
					slides[currentIndex].preloaded = true;
					showSlide(currentIndex);
				})
				.attr('src', slides[currentIndex].image);			
		}

		function initSelector() {
			$target.css({'position' : 'relative'});
			$target.append('<div id="slide_selector" />');
			$selector = $target.find('div:last');
		}
		
		function renderSelectorItems() {
			$selector.empty();
			for(i in slides) {
				var slide = slides[i];
				$selector.append('<img class="button_1'+ i +'" src="'+ (currentIndex == i ? settings.selectorimgActive : settings.selectorimgInactive) +'" />');
				$selector.find('img:last').click(function(e) {
					showSlide(parseInt($(e.target).attr('class').substring(8)));
				});
			}
		}
		
		function bindSelectorEvents() {
			$target.mouseenter(function() {
				halted = true;
				isIeLt9 ? $selector.show() : $selector.fadeIn('fast');
			});
		
			$target.mouseleave(function() {
				halted = false;
				isIeLt9 ? $selector.hide() : $selector.fadeOut('fast');
			});
		}
	};
})(jQuery);
