(function($) {
	var methods = {
		init: function(options) {
				
			return this.each(function() {
				var $this = $(this);
				var data = $this.data('slideshow');
				var internal = {};
				options = $.extend({}, $.fn.slideshow.defaults, options);
				
				$this.data('slideshow', {
					target: $this,
					options: options,
					internal: {
						interval:	'',
						current: 0,
						previous: 0,
						index: ''
					}
				});
				var data = $this.data('slideshow');
				with(data) {
					var slides = $this.find(options.slides);
					
					slides.hide();
					slides.eq(0).show();
					
					if(options.autoPlay){
						internal.interval  = setInterval(function(){
							$this.slideshow('nextSlide', true);	
						}, options.autoPlay);
					}
					
					if(options.nextButton){
						var nextButton = $this.find(options.nextButton);
						nextButton.attr('href', 'javascript:void(0);');
						nextButton.click(function(){
							$this.slideshow('nextSlide');	
						});
						if(slides.length < 2) nextButton.hide();
					}
					
					if(options.prevButton){
						var prevButton = $this.find(options.prevButton);
						prevButton.attr('href', 'javascript:void(0);');
						prevButton.click(function(){
							$this.slideshow('prevSlide');	
						});
						if(slides.length < 2) prevButton.hide();
					}
					
					if(options.useNav){
						var navElements = $this.find(options.useNav);
						navElements.attr('href', 'javascript:void(0);');
						navElements.click(function(){
							internal.index = navElements.index(this);
							$this.slideshow('showSlide', internal.index);	
						});	
					}
				}
			});
		},
		
		nextSlide: function(autoPlaying) {
			return this.each(function() {
				var $this = $(this);
				var data = $this.data('slideshow');
				
				with(data) {
					var slides = $this.find(options.slides);
					var next = internal.current == slides.length - 1 ? 0 : internal.current + 1;
					if(autoPlaying){
						$this.slideshow('showSlide', next, {
							stopAutoPlay: false
						});
					} 
					else {
						$this.slideshow('showSlide', next);
					}
				}
			});
		},
		
		prevSlide: function() {
			return this.each(function() {
				var $this = $(this);
				var data = $this.data('slideshow');

				with(data) {
					var slides = $this.find(options.slides);
					var prev = internal.current ==  0 ? slides.length - 1 : internal.current - 1;
					$this.slideshow('showSlide', prev);
				}
			});
		},
		
		showSlide: function(index, methodOptions) {
			return this.each(function() {
				var $this = $(this);
				var data = $this.data('slideshow');
				with(data) {
					var slides = $this.find(options.slides);
					
					methodOptions = $.extend({}, {
						stopAutoPlay: options.stopAutoPlay,
						slideExit: options.slideExit,
						slideExitComplete: options.slideExitComplete,
						slideEnter: options.slideEnter,
						slideEnterComplete: options.slideEnterComplete
					}, methodOptions);
					
					if(options.preventCurrentNavigation) if(index==internal.current) return;
					internal.previous = internal.current;
					internal.current = index;
					if(methodOptions.stopAutoPlay) $this.slideshow('stopAutoPlay');
					
					switch(options.animationStyle){
					case 'fade':
						if(methodOptions.slideExit) methodOptions.slideExit();
						slides.eq(internal.previous).fadeOut('fast', function() {
							if(methodOptions.slideExitComplete) methodOptions.slideExitComplete();
							if(options.useNav){
								var navElements = $this.find(options.useNav);
								navElements.removeClass(options.activeNavClass);
								navElements.eq(index).addClass(options.activeNavClass);
							}
							slides.eq(internal.current).fadeIn(function(){
								if(methodOptions.slideEnterComplete) methodOptions.slideEnterComplete();
							});
							if(methodOptions.slideEnter) methodOptions.slideEnter();
						});					
						break;
					case 'crossfade':
						slides.css({
							'position': 'absolute'
						});
						if(methodOptions.slideExit) methodOptions.slideExit();
						if(methodOptions.slideEnter) methodOptions.slideEnter();
						slides.eq(internal.previous).fadeOut(function() {
							if(methodOptions.slideExitComplete) methodOptions.slideExitComplete();
							if(options.useNav){
								var navElements = $this.find(options.useNav);
								navElements.removeClass(options.activeNavClass);
								navElements.eq(index).addClass(options.activeNavClass);
							}							
						});	
						slides.eq(internal.current).fadeIn(function(){
								if(methodOptions.slideEnterComplete) methodOptions.slideEnterComplete();
							});				
						break;
					}
				}
			});
		},
		
		stopAutoPlay: function() {
			return this.each(function() {
				var $this = $(this);
				var data = $this.data('slideshow');
				with(data) {
					clearInterval(internal.interval);
				}
			});
		}
		
		
	};
	
	$.fn.slideshow = function(method) {
		if(methods[method]) return methods[method].apply( this, Array.prototype.slice.call(arguments, 1));
    else if(typeof method === 'object' || !method) return methods.init.apply(this, arguments);
    else $.error('Method ' +  method + ' does not exist on jQuery.slideshow');
	}

	$.fn.slideshow.defaults = {
		slides: $('div'),
		useNav: false, // specify selector string to enable navigation
		activeNavClass: 'active',
		preventCurrentNavigation: true,
		autoPlay: 5000, // false prevents autoplay
		stopAutoPlay: true,
		animationStyle: 'fade',
		nextButton: null,
		prevButton: null,
		slideExit: null,
		slideExitComplete: null,
		slideEnter: null, 
		slideEnterComplete: null
	};
})(jQuery);
