;(function($) {
	$.fn.crossfade = function(options) {
		options = $.extend({
			stopOnHover: false,
			timeout: 3000,
			speed: 400 // 'normal'
		}, options);
		// We loop through the selected elements, in case the slideshow was called on more than one element e.g. `$('.foo, .bar').slideShow();`
		return this.each(function() {
			// Inside the setInterval() block, `this` references the window object instead of the slideshow container element, so we store it inside a var
			var $elem = $(this);
			var $controls;
			if(options.controls) {
				$controls = $(options.controls);
				if($controls.children('a').length == 0) {
					var controls_html = '';
					$elem.children().each(function(i) {
						controls_html += '<a href="#" pos="' + i + '"></a>';
					});
					$controls.html(controls_html);
					var $navs = $controls.children();
					$navs.eq(0).addClass('cur');
					
					$navs.click(function(e) {
						e.preventDefault();
						var $cur = $navs.filter('.cur');
						var $nav = $(this);
						if($nav.attr('pos') != $cur.attr('pos')) {
							var diff = $nav.attr('pos') - $cur.attr('pos');
							if(diff > 0) {
								$elem.children().filter(':lt(' + diff + ')').hide().appendTo($elem);								
							} else {
								$elem.children().filter(':lt(' + ($elem.children().size() + diff) + ')').hide().appendTo($elem);								
							}
							$elem.children().filter(':last').fadeIn(options.speed);							
							$cur.removeClass('cur');
							$nav.addClass('cur');
							$elem.data('nav', true);
						}
					});
				}
			}
			
			
			$elem.data('hover', false);
			$elem.hover(function(e) {
					$(this).data('hover', true);
				}, function(e) {
					$(this).data('hover', false);
				}
			)
			
			
			if(!$elem.data('init'))	{				
				$elem.children().eq(0).appendTo($elem).show();
				$elem.data('init', true);
			}
			
			// Iterate through the slides
			$elem.data('interval', setInterval(function() {				
				
				if($elem.data('nav')) {
					$elem.data('nav', false);
				} else if(options.stopOnHover && $elem.data('hover')) {
					// do nothing
				} else {				
					$elem.children().eq(0)
					// Hide the current slide and append it to the end of the image stack
					.hide()
					.appendTo($elem) // As of jQuery 1.3.2, .appendTo() returns the inserted element  
					// Fade in the next slide
					.fadeIn(options.speed);
					if($controls) {
						var $cur = $controls.children('.cur');
						var $next = $cur.next();
						if($next.length == 0) $next = $controls.children(':first');
						$cur.removeClass('cur');
						$next.addClass('cur');					
					}
				}
			}, options.timeout));
		});
	};
})(jQuery);
