  $.fn.slSlider = function( options ) {

		var settings = {
			autoStart			: false,
			bidirectional		: false, // utile seulement pour slide
			changeOnHover		: false,
			dragDrop			: false, // utile seulement pour slide
			effectDuration		: false, // false ou même options que pour les effets jQuery standards ('slow', 'fast', 200, ...). Ne fonctionne pas pour dragDrop
			elementsSelector	: 'img',
			linksToHtml			: '<li><a class="slcLinkTo" href="#">$i</a></li>', // $i est le numéro de l'image
			moveOnKeyPress		: false,
			nbElementsDisplayed	: 1,
			nextLinkHtml		: '<li class="slcNext"><a href="#">Suivant</a></li>',
			paginationHtml		: '<ul class="slcPagination" />',
			previousLinkHtml	: '<li class="slcPrevious"><a href="#">Précédent</a></li>',
			temporisation		: 3000,
			transition			: 'none', // 'none', 'slide' ou 'fade'
			vertical			: false // utile seulement pour slide
		};
	    
		return this.each(function() {
			// If options exist, lets merge them
			// with our default settings
			if ( options ) { 
				$.extend( settings, options );
			}
			
			var slider = $(this);
			
			// Ajout pagination
			var pagination = $(settings.paginationHtml);
			var previous = $(settings.previousLinkHtml);
			var next = $(settings.nextLinkHtml);
			
			previous.appendTo(pagination);
			next.appendTo(pagination);
			pagination.insertAfter(slider);
			
			// Initialisation des elements
			var elements = slider.find(settings.elementsSelector);
			var indexCurrent = 0;
			var currentElement = $(elements[indexCurrent]);
			
			// Ajout numeros
			if (settings.linksToHtml)
			{
				for (i = 0; i < elements.length; ++i)
				{
					var linkTo = $(settings.linksToHtml.replace('$i', i));
					linkTo.find('a').attr('href', '#' + i);
					linkTo.insertBefore(next);
					
					linkTo.find('a').bind((settings.changeOnHover ? 'mouseover' : 'click'), function () { goTo(parseFloat($(this).attr('href').split('#')[1])); clearInterval(timer); return false; });
				}
			}
			
			var autoStart = settings.autoStart;
			var timer;
			
			var currentlyMoving = false;
			
			slider.css({
				position	: 'relative',
				overflow	: 'hidden',
				height		: currentElement.height() * (settings.vertical ? settings.nbElementsDisplayed : 1),
				width		: currentElement.width() * (!settings.vertical ? settings.nbElementsDisplayed : 1)
			});
			
			elements.css( {
				position	: 'absolute',
				left		: 0,
				top			: 0
			});
			
			if (settings.transition == 'slide' && settings.bidirectional)
			{
				var offset = 0;
				if (settings.vertical)
				{
					elements.each(function () {
						$(this).css('top', offset);
						offset += $(this).height();
					});
				}
				else{
					elements.each(function () {
						$(this).css('left', offset);
						offset += $(this).width();
					});
				}
			}
			
			if (settings.moveOnKeyPress)
			{
				$($.merge($.merge([], slider), pagination)).keydown(function (event) {
					var keyPrevious = (settings.transition == 'slide' && settings.vertical) ? '38' : '37';
					var keyNext = (settings.transition == 'slide' && settings.vertical) ? '40' : '39';
					
					if (event.which == keyPrevious)
					{
						goToPrevious();
						clearInterval(timer);
					}
					else if (event.which == keyNext)
					{
						goToNext();
						clearInterval(timer);
					}
				});
			}
			
			if (settings.transition == 'slide' && settings.bidirectional && settings.dragDrop)
			{
			   	slider.bind('mousedown', function (event) {
					clearInterval(timer);
					
					if (!currentlyMoving)
					{
						currentlyMoving = true;
						
						var start = (settings.vertical) ? event.pageY : event.pageX;
						var element = $(this);
						
						var waitingForEffect = false;
						
						$('html').bind('mousemove', function (event) {
							if (!waitingForEffect)
							{
								waitingForEffect = true;
								effectTimer = setInterval(function() { waitingForEffect = false; clearInterval(effectTimer); }, 50);
								
								elements.each(function () {
									if (settings.vertical)
									{
										animateTo($(this), 0, event.pageY - start, 50, true);
									}
									else
									{
										animateTo($(this), 0, event.pageX - start, 50, true);
									}
								});
	
								start = settings.vertical ? event.pageY : event.pageX;
							}
						});
						
						$('html').bind('mouseup', function () {
							$('html').unbind('mouseup');
							$('html').unbind('mousemove');
							
							var tempTimer = setInterval(function () {
							
								clearInterval(tempTimer);
								
								var cssAttr = settings.vertical ? 'top' : 'left';
								var elementSize = (settings.vertical ? slider.height() : slider.width()) / settings.nbElementsDisplayed;
								var currentPosition = parseFloat(elements.first().css(cssAttr));
								
								if (currentPosition > 0)
								{
									indexCurrent = 0;
									currentElement = $(elements[indexCurrent]);
									
									elements.each(function () {
										animateTo($(this), -currentPosition, 0);
									});
								}
								else if (-currentPosition > (elements.length - settings.nbElementsDisplayed) * elementSize)
								{
									indexCurrent = elements.length - settings.nbElementsDisplayed;
									currentElement = $(elements[indexCurrent]);
									
									elements.each(function () {
										animateTo($(this), -currentPosition, -(elements.length - settings.nbElementsDisplayed) * elementSize);
									});
								}
								else
								{
									var positionToMove = currentPosition % elementSize;
									indexCurrent = (positionToMove - currentPosition) / elementSize;
									currentElement = $(elements[indexCurrent]);
									
									if (-positionToMove > elementSize / 2)
									{
										++indexCurrent;
										currentElement = $(elements[indexCurrent]);
									}
									
									elements.each(function () {
										animateTo($(this), -currentPosition, -(indexCurrent) * elementSize);
									});
								}
								
							}, 100);
						});
						
						
					}
					
					return false;
				});
			}
			
			next.bind('click', function() {
				goToNext();
				clearInterval(timer);
				
				return false;
			});
	
			previous.bind('click', function() {
				goToPrevious();
				clearInterval(timer);
				
				return false;
			});
			
			var goToNext = function () {
				goTo(indexCurrent == elements.length - settings.nbElementsDisplayed ? 0 : indexCurrent + 1);
			};
			
			var goToPrevious = function () {
				goTo(indexCurrent == 0 ? elements.length - settings.nbElementsDisplayed : indexCurrent - 1);
			};
			
			var goTo = function (index) {
				if (index == indexCurrent || currentlyMoving)
					return;
	
				currentlyMoving = true;

				var previousElement = currentElement;
				
				indexCurrent = index;
				
				if (index >= elements.length - settings.nbElementsDisplayed)
					indexCurrent = elements.length - settings.nbElementsDisplayed;
				
				currentElement = $(elements[indexCurrent]);
				
				runTransition(previousElement, currentElement);
			};
			
			var runTransition = function (previousElement, currentElement) {
				switch (settings.transition) {
					case 'fade':
						runFade(previousElement, currentElement);
						break;
					case 'slide':
						runSlide(previousElement, currentElement);
						break;
					default :
						runToggle(previousElement, currentElement);
				}
			};
			
			var runFade = function (previousElement, currentElement) {
				previousElement.fadeOut(settings.effectDuration);
				currentElement.fadeIn(settings.effectDuration, function() { currentlyMoving = false; });
			};
			
			var runSlide = function (previousElement, currentElement) {
				if (settings.bidirectional)
				{
					var indexDiff = elements.index(previousElement) - elements.index(currentElement);
					
					elements.each(function () {
						if (settings.vertical)
						{
							animateTo($(this), 0, indexDiff * previousElement.height());
						}
						else
						{
							animateTo($(this), 0, indexDiff * previousElement.width());
						}
					});
				}
				else
				{
					if (settings.vertical)
					{
						currentElement.css('top', previousElement.height()).show();
						$([previousElement, currentElement]).each(function () {
							this.animate({ top: '-=' + previousElement.height() }, settings.effectDuration, function() { $(previousElement).hide(); $([previousElement, currentElement]).css('top', 0); currentlyMoving = false; })
						});
					}
					else
					{
						currentElement.css('left', previousElement.width()).show();
						$([previousElement, currentElement]).each(function () {
							this.animate({ left: '-=' + previousElement.width() }, settings.effectDuration, function() { $(previousElement).hide(); $([previousElement, currentElement]).css('left', 0); currentlyMoving = false; })
						});
					}
				}
			};
			
			var runToggle = function (previousElement, currentElement) {
				if (!settings.effectDuration)
				{
					previousElement.hide(false);
					currentElement.show(false);
					currentlyMoving = false;
				}
				else
				{
					previousElement.hide(settings.effectDuration);
					currentElement.show(settings.effectDuration, function () { currentlyMoving = false; });
				}
			};
			
			var animateTo = function (element, from, to, duration, continueMoving) {
				var sizeToScroll = from + to;
				var operateur = '+=';
				
				if (!duration)
					duration = settings.effectDuration;
				
				if (sizeToScroll < 0)
				{
					operateur = '-=';
					sizeToScroll = sizeToScroll * -1;
				}
				
				if (settings.vertical)
				{
					element.animate({ top: operateur + sizeToScroll }, duration, function() { if (!continueMoving) currentlyMoving = false; });
				}
				else
				{
					element.animate({ left: operateur + sizeToScroll }, duration, function() { if (!continueMoving) currentlyMoving = false; });
				}
			};
			
			// Init
			if (settings.transition != 'slide' || !settings.bidirectional)
				elements.hide();
	
			currentElement.show();
			
			if (autoStart)
				timer = setInterval(function() { goToNext(); }, settings.temporisation);
		});

	};


