(function($){
	
	var methods = {
		stop: function() {
			return this.each(function() {
				var target = $(this);
				var timer = target.data('timer');
				if ((typeof timer != 'undefined') && (timer != null)) {
					timer.stop();
				}
			});
		},
		init: function(options) {
			var is_mobile = isMobileClient(navigator.userAgent);
			var settings = {delay: 10000, speed: 500, swipeTarget: '.controls'};
			if (typeof options === 'number') {
				$.extend(settings, {delay: options});
			} else {
				if (options) {
					$.extend(settings, options);
				}
			}
			
			// CSS Transtion support
			var body = document.body || document.documentElement;
			var style = body.style;
			var hasCSSTransitionsSupport = style.WebkitTransition !== undefined || style.MozTransition !== undefined || style.OTransition !== undefined || style.transition !== undefined;
			
			return this.each(function() {
				// private vars
				var target = $(this);
				var currentPos = 0;				
				var guide = $('.guide', target);
				var	container = $('.items-container', target);
				var items = $('.item', target);
				var len = items.length;
				target.data('timer', null);
				target.data('isAnimated', false);
				
				$('.item', container).each(function(index) {
					$(this).data('index', index);
				});
				
				// private functions
				function selectItem(i) {
					$('a', guide).removeClass('selected');
					$('a:eq(' + i + ')', guide).addClass('selected');
				}
				
				function gotoItem(pos) {
					var items;
					var width = 0;
					
					var slideshowWidth = 0;
					$('.item', container).each(function() {
						slideshowWidth += $(this).width();
					});
					
					if (currentPos < pos) {
						pos = pos % len;
						if (pos < currentPos) {
							pos += len;
						}
						
						items = $('.item', container).filter(function() {
							var index = $(this).data('index');
							if (index < currentPos) {
								index += len;
							}
							return (currentPos <= index) && (index < pos);
						}).each(function() {
							width += $(this).width();
						});
						
						container.move({x: -width}, settings.speed, function() {
							currentPos = pos % len;
							selectItem(currentPos);
							
							if ($.browser.msie) {
								$('.items', container).append(items.clone(true));
								items.remove();
								container.move({x: width});
							} else {
								items.move({x: slideshowWidth});
							}

							target.data('isAnimated', false);

							if (typeof settings.complete == 'function') {
								settings.complete(currentPos);
							}
						});
					} else
					if (pos < currentPos) {
						pos = pos % len;
						if (pos > currentPos) {
							pos -= len;
						}
						
						items = $('.item', container).filter(function() {
							var index = $(this).data('index');
							if (index > currentPos) {
								index -= len;
							}
							return (pos <= index) && (index < currentPos);
						}).each(function() {
							width += $(this).width();
						});
						
						if ($.browser.msie) {
							$('.items', container).prepend(items.clone(true));
							items.remove();
							container.move({x: -width});
						} else {
							items.move({x: -slideshowWidth});
						}
						
						container.move({x: width}, settings.speed, function() {
							currentPos = pos % len;
							if (currentPos < 0) {
								currentPos += len;
							}
							selectItem(currentPos);
							
							target.data('isAnimated', false);
							
							if (typeof settings.complete == 'function') {
								settings.complete(currentPos);
							}
						});

						if (typeof settings.complete == 'function') {
							settings.complete(currentPos);
						}
					} else {
						target.data('isAnimated', false);
					}
				}
				
				// begin
				var focused = true;
				$(window).focus(function() {focused = true;});
				$(window).blur(function() {focused = false;});
				
				$('.guide a', target).click(function() {
					this.blur();
					if (target.data('isAnimated')) {
						return false;
					}
					
					var timer = target.data('timer');
					if ((typeof timer != 'undefined') && (timer != null)) {
						timer.stop();
					}
					
					target.data('isAnimated', true);

					var pos = $('.guide a', target).index(this);
					gotoItem(pos);
					
					return false;
				});
				
				// start carousel
				if (len > 1)  {
					target.data(
						'timer',
						$.timer(settings.delay, function() {
							if (!focused && is_mobile == false) {
								return;
							}
							gotoItem(currentPos + 1);
						})
					);
					
					var swipeOptions = {
						threshold: 50,
						triggerOnTouchEnd: true,
						swipeLeft: function() {
							if (target.data('isAnimated')) {
								return;
							}
							var timer = target.data('timer');
							target.data('isAnimated', true);
							if ((typeof timer != 'undefined') && (timer != null)) {
								timer.stop();
							}
							gotoItem(currentPos + 1);
						},
						swipeRight: function() {
							if (target.data('isAnimated')) {
								return;
							}
							var timer = target.data('timer');
							target.data('isAnimated', true);
							if ((typeof timer != 'undefined') && (timer != null)) {
								timer.stop();
							}
							gotoItem(currentPos - 1);
						}
					}
					$(settings.swipeTarget, target).swipe( swipeOptions );
				}
			});
		}
	}
	
	$.fn.slideshow = function(method) {
		if (methods[method]) {
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		} else
		if (typeof method === 'number' || typeof method === 'object' || !method) {
			return methods.init.apply(this, arguments);
		} else {
			$.error('Method ' +  method + ' does not exist on jQuery.slideshow');
		}
		return false;
	}
	
})(jQuery);
