;(function( $ ){
	
	var methods = {
	  	init: function(options) {
	  		return this.each(function(){
				var $this = $(this);
				var data = $this.data('sliders');
				var firstTime=false;
				var movements=new Array('lefttoright', 'righttoleft', 'toptobottom', 'bottomtotop',
						'lefttoptorightbottom', 'righttoptoleftbottom', 'leftbottomtorighttop', 'rightbottomtolefttop',
						'fade', 'special');
				if ( ! data ) {
					firstTime=true;
					data = {
						actual_slide:0,
						movement: 'lefttoright',
						random_movement: false,
						movements: movements,
						easing: 'swing',
						auto_play:true,
			  			time: 7000,
			  			animation_time: 300,
			  			controls: true,
			  			controls_numbers: true,
                                                controls_thumbs: false,
			  			controls_playpause: true,
			  			control_class: 'control',
						control_selected_class: 'selected',
						control_play_class: 'play',
						control_pause_class: 'pause',
						target : $this,
						paddingBottom:parseInt($this.css('padding-bottom'),10)+5,
						timeout: null,
						width: $this.width(),
						playing: true,
						pause_mouseover: true,
						infinite: true,
						nbSlides: 1
					};
				}
				$.extend(data, options);
				data.controls=data.controls && (data.controls_numbers || data.controls_playpause || data.controls_thumbs);
				if(!data.controls) {
					data.controls_numbers=data.controls_playpause=data.controls_thumbs=false;
				}
				
				if(data.random_movement) {
					if(!$.isArray(data.movements) || data.movements.length==0) {
						data.movements=movements;
					}
					data.movement=data.movements[Math.round(Math.random()*(data.movements.length-1))];
				}
				if(!$.inArray(data.movement, movements)) {
					data.movement='lefttoright';
				}
				var slides=$('.wrapper .slide', $this);
				var nbSlides=slides.length;
				data.nbSlides=nbSlides;
				$this.data('sliders', data);
				if(firstTime) {
					$this.addClass('slider');
					var slides=$('.wrapper .slide', $this);
					var nbSlides=slides.length;
					$('.wrapper', $this).width((data.width * nbSlides) +100);
					var wrapperHeight=0;
					//Le slider prend la hauteur de la première diapo rapidement pour ne pas casser la mise en page trop longtemps
					$this.animate({'height': ($(slides[0]).height()+data.paddingBottom) + 'px'}, data.animation_time, 'swing');
					if(data.controls) {
						var controls=$('.controls', $this);
						controls.append('<ul></ul>');
						var ul=$('ul', controls);
						var a;
					}
					if(data.controls && data.controls_playpause) {
						a=$('<a href="#" class="'+data.control_play_class+'"></a>')
							.attr('title','play')
							.css('display','none')
							.click(function(e){
								e.stopPropagation();
								var data=$this.data('sliders');
								data.auto_play=true;
								$this.data('sliders', data);
								$this.sliders('launch');
								return false;
								
							});
						ul.append($('<li></li>').append(a));
						a=$('<a href="#" class="'+data.control_pause_class+'"></a>')
							.attr('title','pause')
							.click(function(e){
								e.stopPropagation();
								var data=$this.data('sliders');
								data.auto_play=false;
								$this.data('sliders', data);
								$this.sliders('pause');
								return false;
							});
						ul.append($('<li></li>').append(a));
					}
                                        var button;
					for(var ind=0; ind<nbSlides; ind++) {
						wrapperHeight+=$(slides[ind]).height() + data.paddingBottom;
						if(data.controls && (data.controls_numbers || data.controls_thumbs)) {
                                                        if(data.controls_thumbs[ind])
								button = data.controls_thumbs[ind];
							else
								button = ind+1;
							a=$('<a href="#"><span class="survol"></span>'+button+'</a>')
								.attr('id', 'control'+ind)
								.attr('title',ind+1)
								.addClass(data.control_class)
								.click(function(e){
									e.stopPropagation();
									if($this.data('sliders').timeout) clearTimeout($this.data('sliders').timeout);
									$this.sliders('slide',$(this).attr('title')-1);
									return false;
								});
                                                                if ((ind % 2) == 1) styleControl = ' class="right"';
                                                                else styleControl = '';
							ul.append($('<li'+styleControl+'></li>').append(a));
						}
					}
					$('.wrapper', $this).height(wrapperHeight +100);
				}
				if(firstTime) {
					if(data.infinite) {
						if(nbSlides > 1) {
							var last_ind = slides.length-1;
							slides[last_ind+1] = $(slides[0]).clone(false, false);
							$('.wrapper', $this).append(slides[last_ind+1]);
							slides[-1] = $(slides[last_ind]).clone(false, false);
							$('.wrapper', $this).prepend(slides[-1]);
						}
					}
				}
				var begin = data.infinite && nbSlides > 1 ? -1 : 0;
				var end = data.infinite && nbSlides > 1 ? nbSlides+1 : nbSlides;
				for(var ind=begin; ind<end; ind++) {
					if(firstTime) {
						$(slides[ind])
						.attr('id', 'slide'+ind)
						.mouseover(function(e) {
							if ($this.data('sliders').pause_mouseover) {
								$this.sliders('pause');
							}
						})
						.mouseout(function(e){
							if($this.data('sliders').auto_play && $this.data('sliders').pause_mouseover) {
								$this.sliders('launch');
							}
						});
					}
					var left=0;
					var top=0;
					var css;
					switch(data.movement) {
						case 'lefttoright':
							left=(ind*data.width);
							break;
						case 'righttoleft':
							left=(nbSlides-1-ind)*data.width;
							break;
						case 'toptobottom':
							top=0;
							for(var ind2=begin; ind2<ind; ind2++) {
								top+=$(slides[ind2]).height() + data.paddingBottom;
							}
							break;
						case 'bottomtotop':
							top=0;
							for(var ind2=end; ind2>ind; ind2--) {
								top+=$(slides[ind2]).height() + data.paddingBottom;
							}
							break;
						case 'lefttoptorightbottom':
							left=(ind*data.width);
							top=0;
							for(var ind2=begin; ind2<ind; ind2++) {
								top+=$(slides[ind2]).height() + data.paddingBottom;
							}
							break;
						case 'righttoptoleftbottom':
							left=(nbSlides-1-ind)*data.width;
							top=0;
							for(var ind2=begin; ind2<ind; ind2++) {
								top+=$(slides[ind2]).height() + data.paddingBottom;
							}
							break;
						case 'leftbottomtorighttop':
							left=(ind*data.width);
							top=0;
							for(var ind2=end; ind2>ind; ind2--) {
								top+=$(slides[ind2]).height() + data.paddingBottom;
							}
							break;
						case 'rightbottomtolefttop':
							left=(nbSlides-1-ind)*data.width;
							top=0;
							for(var ind2=end; ind2>ind; ind2--) {
								top+=$(slides[ind2]).height() + data.paddingBottom;
							}
							break;
						case 'fade':
							if(ind!=data.actual_slide) {
								$(slides[ind]).hide();
							}
							break;
						case 'special':
							if(ind!=data.actual_slide) {
								$(slides[ind]).hide();
								top=100;
							}
							break;
	
					}
					css={'position': 'absolute', 'left': left+'px', 'top': top+'px'};
					if(data.movement!='fade' && data.movement!='special') css.display='block';
					$(slides[ind]).css(css);
					if((data.random_movement || (data.movement!='fade' && data.movement!='special')) && ind==data.actual_slide) {
						$('.wrapper', $this).css({'margin-left': -left+'px', 'margin-top': -top+'px'});
					}
				}
				if(firstTime && data.auto_play) {
					$this.sliders('slide',data.actual_slide);
				}
  			});
	  	},
	  	
	  	slide: function(i) {
  			return this.each(function(){
				var $this = $(this);
				var data = $this.data('sliders');
				if(i!=data.actual_slide) {
					if(data.controls && data.controls_numbers) {
						$('.controls #control'+data.actual_slide, $this).removeClass(data.control_selected_class);
					}
					if($('#slide'+i, $this).length==0) {
						i= 0;
					}
					
					if(data.random_movement) {
						$this.sliders('init');
						data = $this.data('sliders');
					}
					
					if(data.movement=='fade') {
						$('#slide'+data.actual_slide, $this).fadeOut(data.animation_time, data.easing, function(){
							$('#slide'+i, $this).fadeIn(data.animation_time, data.easing, function() {
								if(!data.random_movement) {
									$this.sliders('post_slide');
								}
							});
						});
						data.actual_slide=i;
					}
					if(data.movement=='special') {
						$('#slide'+data.actual_slide, $this).fadeOut(data.animation_time, 'swing', function(){
							$('#slide'+data.actual_slide, $this).css({left: 0, top: 100+'px'});
							$('#slide'+i, $this).css('opacity', 0);
							$('#slide'+i, $this).show();
							$('#slide'+i, $this).animate({opacity: 1}, {queue: false, duration: data.animation_time+300}, function() {
								if(!data.random_movement) {
									$this.sliders('post_slide');
								}
							});
							$('#slide'+i, $this).animate({left: 0, top: 0 }, data.animation_time, data.easing);
						});
						data.actual_slide=i;
					}
					if((data.movement!='fade' && data.movement!='special') || data.random_movement) {
						data.actual_slide=i;
						var left = -1 * parseInt($('#slide'+i, $this).css('left'), 10);
						var top = -1 * parseInt($('#slide'+i, $this).css('top'), 10);
						$('.wrapper', $this).animate({
							'margin-left': left+'px',
							'margin-top': top+'px'
							},
							data.animation_time,
							data.easing, 
							function() {
								$this.sliders('post_slide');
							}
						);
					}
	
					$this.animate({'height': ($('#slide'+data.actual_slide, $this).height() + data.paddingBottom) + 'px'}, data.animation_time, data.easing);
					
					$this.data('sliders', data);
  				}
				if(data.controls && data.controls_numbers) {
					$('.controls #control'+data.actual_slide, $this).addClass(data.control_selected_class);
				}
				if(data.playing)
					$this.sliders('launch');
			});
	  	},
		
		post_slide: function() {
			return this.each(function() {
				var $this = $(this);
				var data = $this.data('sliders');
				if(data.infinite) {
					if(data.actual_slide == -1 || data.actual_slide == data.nbSlides) {
						var oldpos = data.actual_slide;
						if(data.actual_slide == -1) data.actual_slide=data.nbSlides - 1;
						else data.actual_slide=0;
						if(data.movement=='special') {
							$('#slide'+oldpos, $this).css({
								'display': 'none',
								left: 0,
								top: 100+'px',
								'opacity': 0
							});
							$('#slide'+data.actual_slide, $this).css({
								'display': 'block',
								left: 0,
								top: 0,
								'opacity': 1
							});
							
						} else if(data.movement=='fade') {
							$('#slide'+oldpos, $this).css({
								'display': 'none',
								'opacity': 0
							});
							$('#slide'+data.actual_slide, $this).css({
								'display': 'block',
								'opacity': 1
							});
						}
						
						if((data.movement!='fade' && data.movement!='special') || data.random_movement) {
							var left = -1 * parseInt($('#slide'+data.actual_slide, $this).css('left'), 10);
							var top = -1 * parseInt($('#slide'+data.actual_slide, $this).css('top'), 10);
							$('.wrapper', $this).css({
								'margin-left': left+'px',
								'margin-top': top+'px'
							});
						}
						$this.data('sliders', data);
						if(data.controls && data.controls_numbers) {
							$('.controls #control'+data.actual_slide, $this).addClass(data.control_selected_class);
						}
					}
				}
			});
		},
		
		previous: function() {
		
			return this.each(function(){
				var $this = $(this);
				var data = $this.data('sliders');
				var i=data.actual_slide-1;
				var limit = data.infinite ? -1 : 0;
				if(i < limit) { 
					i=data.nbSlides - 1;
				}
				$this.sliders('slide',i);
			});
		},
		
		next: function() {
			return this.each(function(){
				var $this = $(this);
				var data = $this.data('sliders');
				var i=data.actual_slide+1;
				var limit = data.infinite ? data.nbSlides : data.nbSlides-1;
				if(i > limit) { 
					i=0;
				}
				$this.sliders('slide',i);
			});
		},
		
		pause:  function(id) {
			return this.each(function(){
				var $this = $(this);
				var data = $this.data('sliders');
				if(data.playing) {
					if(data.controls && data.controls_playpause) {
						$('.controls a.pause', $this).hide();
						$('.controls a.play', $this).show();
					}
					data.playing=false;
				}
				
				if(data.timeout) clearTimeout(data.timeout);
				$this.data('sliders', data);
			});
		},
		
		launch: function() {
			return this.each(function(){
				var $this = $(this);
				var data = $this.data('sliders');
				if(!data.playing) {
					if(data.controls && data.controls_playpause) {
						$('.controls a.play', $this).hide();
						$('.controls a.pause', $this).show();
					}
					data.playing=true;
				}
				
				if(data.timeout) clearTimeout(data.timeout);
				data.timeout=setTimeout(
					function() {
						$this.sliders('next');
					},
					data.time
				);
				$this.data('sliders', data);
			});
		},
                
                stop: function() {
                    return this.each(function(){
                            var $this = $(this);
                            var data = $this.data('sliders');
                            
                            if(data.timeout) clearTimeout(data.timeout);
                            
                            $this.data('sliders', null);
                    });
                }
	};
	
	$.fn.sliders = 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.sliders' );
		}  
	};
})( jQuery );
