
function RSPlug_Carrousel2 (idImgsContainer, speedCarrousel, speedAnimating, imgMargin, toNext, options){
	var options = options || {};
	this.stepPerSecond = 25;
	this.nbSteps = speedAnimating / 1000 * this.stepPerSecond;
	this.imgsContainer = typeof(idImgsContainer) == 'string' ? document.getElementById(idImgsContainer) : idImgsContainer;
	this.speedCarrousel = (!isNaN(speedCarrousel) && speedCarrousel > 0) ? speedCarrousel : 0;
	this.speedAnimating = parseFloat(speedAnimating / this.nbSteps);
	this.imgMargin = (null !== imgMargin && undefined !== imgMargin && !isNaN(imgMargin) && imgMargin > 0) ? imgMargin : 0;
	this.toNext = (null !== toNext && undefined !== toNext && toNext === false) ? false : true;
	this.useMotionIfAvailable = (null !== options.useMotionIfAvailable && undefined !== options.useMotionIfAvailable && options.useMotionIfAvailable === false) ? false : true;
	this.motionType = 'inOutCubic';
	this.allowLooping = true;
	this.onMiddleSlidingCallback = null;
	this.onAfterSlidingCallback = null;
	this.numbersContainer = null;
	this.slideElement = (null === options.slideElement || undefined === options.slideElement || typeof(options.slideElement) != 'string') ? 'li' : options.slideElement.toLowerCase();
	this.dlMode = (null === options.dlMode || undefined === options.dlMode) ? false : !!options.dlMode;
	this.dlNoLink = (null === options.dlNoLink || undefined === options.dlNoLink) ? false : !!options.dlNoLink;
	this.dlFollowLink = (null === options.dlFollowLink || undefined === options.dlFollowLink) ? false : !!options.dlFollowLink;
	this.animateLastImg = true;
	this.boolUseOpacity = (null !== options.boolUseOpacity && undefined !== options.boolUseOpacity && options.boolUseOpacity === false) ? false : true;
	this.defaultZIndex = (null !== options.defaultZIndex && undefined !== options.defaultZIndex && !isNaN(options.defaultZIndex) && options.defaultZIndex > 0) ? options.defaultZIndex : 2000;
	this.zIndexScale = (null !== options.zIndexScale && undefined !== options.zIndexScale && !isNaN(options.zIndexScale) && options.zIndexScale > 0) ? options.zIndexScale : 1;
	if (this.dlMode){
		this.slideElement = 'dd';
		this.setNumbers(options.liensContainer, 'active', 'ul', {nolink: !!this.dlNoLink});
	}
	this.animation = null;
	this.init();
}

RSPlug_Carrousel2.prototype.init = function (){
	this.animating = false;
	this.prepareNextTimeouts = [];
	this.currentImgIndex = 0;
	this.imgs = this.imgsContainer.getElementsByTagName(this.slideElement);
	this.nbImgs = this.imgs.length;
	this.imgs[0].style.display = 'block';
	for (var i=0; i<this.nbImgs; i++){
		if (i > 0){
			this.imgs[i].style.display = 'none';
		}
		this.imgs[i].style.position = 'absolute';
		this.imgs[i].style.zIndex = this.defaultZIndex;
	}
	if (null !== this.numbersContainer){
		this.setNumbers(this.numbersContainer, this.activeNumberClassName, this.formatNumber, {nolink: (this.dlMode && this.dlNoLink ? true : false)});
	}
	if (this.speedCarrousel > 0){
		this.prepareNext();
	}
};

RSPlug_Carrousel2.prototype.prepareNext = function (){
	if (!this.animating && this.prepareNextTimeouts.length == 0){
		var inst = this;
		this.prepareNextTimeouts.push(setTimeout(function(){ inst.slideToNext(); }, this.speedCarrousel));
	}
};

RSPlug_Carrousel2.prototype.clearPrepareNext = function (){
	if (this.prepareNextTimeouts.length > 0){
		while (this.prepareNextTimeouts.length > 0){
			clearTimeout(this.prepareNextTimeouts.pop());
		}
	}
};

RSPlug_Carrousel2.prototype.allowLooping = function (){
	this.allowLooping = true;
	return this;
};
RSPlug_Carrousel2.prototype.disallowLooping = function (){
	this.allowLooping = false;
	return this;
};

RSPlug_Carrousel2.prototype.setNumbers = function (container, activeClassName, format, options){
	var options = options || {};
	if (typeof(container) == 'string'){
		container = document.getElementById(container);
	}
	if (container){
		container.style.zIndex = this.defaultZIndex + (this.zIndexScale *5); 
		this.numbersContainer = container;
		this.activeNumberClassName = activeClassName;
		this.activeNumber = null;
		this.formatNumber = format;
		if (this.dlMode){
			var dts = this.imgsContainer.getElementsByTagName('dt');
			if (dts.length == this.nbImgs){
				var ul = document.createElement('ul');
				for (var i=0; i<this.nbImgs; i++){
					var li = document.createElement('li');
					if (this.dlFollowLink){
						li.innerHTML = dts[i].innerHTML;
					} else { 
						li.appendChild(this._createNumberLink(i, dts[i].innerHTML, options));
					}
					ul.appendChild(li);
				}
				this.numbersContainer.appendChild(ul);
			}
		} 
		else if (format == 'ul'){
			var ul = document.createElement('ul');
			for (var i=0; i<this.nbImgs; i++){
				var li = document.createElement('li');
				li.appendChild(this._createNumberLink(i, i+1, options));
				ul.appendChild(li);
			}
			this.numbersContainer.appendChild(ul);
		} 
		else if (format == 'a'){
			for (var i=0; i<this.nbImgs; i++){
				this.numbersContainer.appendChild(this._createNumberLink(i, i+1, options));
			}
		} 
		this.setActiveNumber(0);
	}
	return this;
};
RSPlug_Carrousel2.prototype._createNumberLink = function (index, html, options){
	var inst = this;
	if (options.nolink){
		var link = document.createElement('span');
	} else {
		var link = document.createElement('a');
		link.href = '#slide' + (index+1);
	}
	if (this.slideElement == 'img' && options.isThumbs == true){
		link.appendChild(this.imgs[index].cloneNode(true));
	} else {
		link.innerHTML = html;
	}
	link.onclick = function(){
		inst.slideTo(index);
		return false;
	};
	return link;
};

RSPlug_Carrousel2.prototype.setActiveNumber = function (index){
	if (null !== this.activeNumber){
		this.activeNumber.className = '';
	}
	if (this.formatNumber == 'ul'){
		var numbers = this.numbersContainer.getElementsByTagName('li');
		if (numbers[index]){
			this.activeNumber = numbers[index];
			this.activeNumber.className = this.activeNumberClassName;
		}
	}
	else if (this.formatNumber == 'a'){
		var numbers = this.numbersContainer.getElementsByTagName('a');
		if (numbers[index]){
			this.activeNumber = numbers[index];
			this.activeNumber.className = this.activeNumberClassName;
		}
	}
	return this;
};

RSPlug_Carrousel2.prototype.setAnimation = function (animation){
	switch (animation.toLowerCase()){
		case 'ttb':
		case 'btt':
		case 'ltr':
		case 'rtl':
		case 'fadding':
			this.animation = animation.toLowerCase();
			break;
	}
	return this;
};

RSPlug_Carrousel2.prototype.setAnimateLastImg = function (animate){
	this.animateLastImg = !!animate;
	return this;
};

RSPlug_Carrousel2.prototype.useOpacity = function (useOpacity){
	this.boolUseOpacity = !!useOpacity;
	return this;
};

RSPlug_Carrousel2.prototype.setDefaultZIndex = function (zindex){
	if (!isNaN(parseInt(zindex))){
		this.defaultZIndex = parseInt(zindex);
	}
	return this;
};

RSPlug_Carrousel2.prototype.canSlideToPrevious = function (imgIndex){
	if (null === imgIndex || undefined === imgIndex){
		imgIndex = this.currentImgIndex;
	}
	return (this.allowLooping || (imgIndex -1 >= 0));
};
RSPlug_Carrousel2.prototype.canSlideToNext = function (imgIndex){
	if (null === imgIndex || undefined === imgIndex){
		imgIndex = this.currentImgIndex;
	}
	return (this.allowLooping || (imgIndex +1 < this.nbImgs));
};

RSPlug_Carrousel2.prototype.slideToPrevious = function (){
	if (!this.canSlideToPrevious()){
		return this;
	}
	var imgIndex = (this.currentImgIndex -1 >= 0) ? this.currentImgIndex -1 : this.nbImgs -1;
	this.slideTo(imgIndex, false);
	return this;
};
RSPlug_Carrousel2.prototype.slideToNext = function (){
	if (!this.canSlideToNext()){
		return this;
	}
	var imgIndex = (this.currentImgIndex +1 < this.nbImgs) ? this.currentImgIndex +1 : 0;
	this.slideTo(imgIndex, true);
	return this;
};

RSPlug_Carrousel2.prototype.onAfterSliding = function (callback){
	if (typeof(callback) == 'function'){
		this.onAfterSlidingCallback = callback;
	}
	return this;
};

RSPlug_Carrousel2.prototype.onMiddleSliding = function (callback){
	if (typeof(callback) == 'function'){
		this.onMiddleSlidingCallback = callback;
	}
	return this;
};

RSPlug_Carrousel2.prototype.fadeTo = function (imgIndex){
	if (this.animating){
		return false;
	}
	this.clearPrepareNext();
	if (this.currentImgIndex == imgIndex){ // Inutile de déplacer
		this.prepareNext();
		return this;
	}
	this.animating = true;
	
	var inst = this;
	
	if ('undefined' != typeof(RSPlug_Misc)){
		var motionAvailable = !!(RSPlug_Misc.Motion);
	} else {
		var motionAvailable = false;
	}
	if (this.useMotionIfAvailable && motionAvailable){ // Si RSPlug_Misc est chargé, on utilise la lib Motion
		var CarrouselMotion = new RSPlug_Misc.Motion(
				function(opacity){ 
					inst.setOpacity(inst.imgs[imgIndex], opacity); 
				}, 
				this.motionType, 0, 100, 
				(this.speedAnimating * this.nbSteps)
			);
		if (null !== this.numbersContainer){
			CarrouselMotion.addListener('middle', function(){ inst.setActiveNumber(imgIndex); });
		}
		if ('function' == typeof(this.onMiddleSlidingCallback)){
			CarrouselMotion.addListener('middle', function(){ inst.onMiddleSlidingCallback.call(inst, imgIndex); });
		}

		if (null !== this.endMove && typeof(this.endMove) == 'function'){
			CarrouselMotion.addListener('finish', function(){ inst.endMove(new_index, inst); });
		}
		CarrouselMotion.addListener('start', function(){
				inst.imgs[imgIndex].style.zIndex = inst.defaultZIndex + (inst.zIndexScale *2);
				inst.imgs[inst.currentImgIndex].style.zIndex = inst.defaultZIndex + inst.zIndexScale;
				inst.imgs[imgIndex].style.display = 'block'; 
			});
		CarrouselMotion.addListener('finish', function(){ 
				inst.setOpacity(inst.imgs[inst.currentImgIndex], 100);
				inst.imgs[inst.currentImgIndex].style.display = 'none'; 
				inst.imgs[inst.currentImgIndex].style.zIndex = inst.defaultZIndex;
				
				inst.currentImgIndex = imgIndex;
				inst.animating = false; 
				if (inst.speedCarrousel > 0){
					inst.prepareNext();
				}
				if ('function' == typeof(inst.onAfterSlidingCallback)){
					inst.onAfterSlidingCallback.apply(inst);
				}
			});
		CarrouselMotion.start();
	}
	else {
		for (var i=0; i<=this.nbSteps; i++){
			var delai = this.speedAnimating *i;
			var opacity = (i *100 /this.nbSteps);
			/**/
			this.imgs[imgIndex].style.zIndex = this.defaultZIndex + (this.zIndexScale *2);
			this.imgs[this.currentImgIndex].style.zIndex = this.defaultZIndex + this.zIndexScale;
			/**/
			this.doFade(this.imgs[imgIndex], opacity, delai);
			if (i == 0){
				setTimeout(function(){ inst.imgs[imgIndex].style.display = 'block'; }, delai, opacity);
			}
		}
		if (null !== this.numbersContainer){
			// On calcule le 50%
			var delai50 = this.speedAnimating *(this.nbSteps /2);
			setTimeout(function(){ inst.setActiveNumber(imgIndex); }, delai50);
		}
		if (typeof(this.onMiddleSlidingCallback) == 'function'){
			// On calcule le 50%
			var delai50 = this.speedAnimating *(this.nbSteps /2);
			setTimeout(function(){ inst.onMiddleSlidingCallback.call(inst, imgIndex); }, delai50);
		}
		setTimeout(function(){ 
			inst.setOpacity(inst.imgs[inst.currentImgIndex], 100);
			inst.imgs[inst.currentImgIndex].style.display = 'none'; 
			inst.imgs[inst.currentImgIndex].style.zIndex = inst.defaultZIndex; 
			
			inst.currentImgIndex = imgIndex;
			inst.animating = false; 
			if (inst.speedCarrousel > 0){
				inst.prepareNext();
			}
			if (typeof(inst.onAfterSlidingCallback) == 'function'){
				inst.onAfterSlidingCallback.apply(inst);
			}
		}, delai);
	}
	return this;
};

RSPlug_Carrousel2.prototype.slideTo = function (imgIndex, toNext){
	if (this.animating){
		return false;
	}
	this.clearPrepareNext();
	if (this.currentImgIndex == imgIndex){ // Inutile de déplacer
		this.prepareNext();
		return this;
	}
	this.animating = true;
	
	if (undefined === toNext || null === toNext){
		toNext = (imgIndex > this.currentImgIndex);
	} else {
		toNext = !!toNext;
	}
	if (this.animation == 'fadding'){
		this.animating = false;
		return this.fadeTo(imgIndex);
	}
	/* gestion étrange de l'animation... */
	switch (this.animation){
		case 'btt':
		case 'rtl': toNext = true; break;
		case 'ttb':
		case 'ltr': toNext = !toNext; break;
	}
	/**/

	if (this.animation == 'ttb' || this.animation == 'btt'){
		var longueurDeplacement = (this.imgs[this.currentImgIndex].offsetHeight || this.imgsContainer.offsetHeight || this.imgsContainer.parentNode.offsetHeight);
	} else {
		var longueurDeplacement = (this.imgs[this.currentImgIndex].offsetWidth || this.imgsContainer.offsetWidth || this.imgsContainer.parentNode.offsetWidth);
	}
	longueurDeplacement += this.imgMargin; // On ajoute une marge entre chaque image
	
	var inst = this;
	
	if ('undefined' != typeof(RSPlug_Misc)){
		var motionAvailable = !!(RSPlug_Misc.Motion);
	} else {
		var motionAvailable = false;
	}
	if (this.useMotionIfAvailable && motionAvailable){ // Si RSPlug_Misc est chargé, on utilise la lib Motion
		var axis = (this.animation == 'ttb' || this.animation == 'btt') ? 'y' : 'x';
		var end = 0;
		if ((toNext && this.toNext) || (!toNext && !this.toNext)){
			var sens = -1;
			var start = longueurDeplacement;
		} else {
			var sens = 1;
			var start = -longueurDeplacement;
		}
		
		var CarrouselMotion = new RSPlug_Misc.Motion(
			function(pos, start, end){ 
				if (axis == 'x'){
					inst.imgs[imgIndex].style.left = pos +'px';
				} else {
					inst.imgs[imgIndex].style.top = pos +'px';
				}
				if (inst.boolUseOpacity){
					inst.setOpacity(inst.imgs[imgIndex], ((pos - start) * 100 / (end - start)));
				}

				if (inst.animateLastImg){
					if (axis == 'x'){
						inst.imgs[inst.currentImgIndex].style.left = (pos + (longueurDeplacement*sens)) +'px';
					} else {
						inst.imgs[inst.currentImgIndex].style.top = (pos + (longueurDeplacement*sens)) +'px';
					}
				}
			}, 
			this.motionType, start, end, 
			(this.speedAnimating * this.nbSteps)
		);
		
		if (null !== this.numbersContainer){
			CarrouselMotion.addListener('middle', function(){ inst.setActiveNumber(imgIndex); });
		}
		if ('function' == typeof(this.onMiddleSlidingCallback)){
			CarrouselMotion.addListener('middle', function(){ inst.onMiddleSlidingCallback.call(inst, imgIndex); });
		}

		if (null !== this.endMove && typeof(this.endMove) == 'function'){
			CarrouselMotion.addListener('finish', function(){ inst.endMove(new_index, inst); });
		}
		CarrouselMotion.addListener('start', function(){
				inst.imgs[imgIndex].style.zIndex = inst.defaultZIndex + (inst.zIndexScale *2);
				inst.imgs[inst.currentImgIndex].style.zIndex = inst.defaultZIndex + inst.zIndexScale;
				inst.imgs[imgIndex].style.display = 'block'; 
			});
		CarrouselMotion.addListener('finish', function(){ 
				inst.setOpacity(inst.imgs[inst.currentImgIndex], 100);
				inst.imgs[inst.currentImgIndex].style.display = 'none'; 
				inst.imgs[inst.currentImgIndex].style.zIndex = inst.defaultZIndex;
				
				inst.currentImgIndex = imgIndex;
				inst.animating = false; 
				if (inst.speedCarrousel > 0){
					inst.prepareNext();
				}
				if ('function' == typeof(inst.onAfterSlidingCallback)){
					inst.onAfterSlidingCallback.apply(inst);
				}
			});
		CarrouselMotion.start();
	}
	else {
		var step = longueurDeplacement / this.nbSteps;
		
		var opacity = null;
		for (var i=0; i<=this.nbSteps; i++){
			var delai = this.speedAnimating *i;
			if (this.boolUseOpacity){
				opacity = (i *100 /this.nbSteps);
			}
			this.imgs[imgIndex].style.zIndex = this.defaultZIndex + (this.zIndexScale *2);
			this.imgs[this.currentImgIndex].style.zIndex = this.defaultZIndex + this.zIndexScale;
			if ((toNext && this.toNext) || (!toNext && !this.toNext)){
				if (this.animation == 'ttb' || this.animation == 'btt'){
					this.doSlide(this.imgs[imgIndex], 0, (i *-1 * step +longueurDeplacement), delai, opacity);
					if (this.animateLastImg){
						this.doSlide(this.imgs[this.currentImgIndex], 0, (i *-1 * step), delai);
					}
				} else {
					this.doSlide(this.imgs[imgIndex], (i *-1 * step +longueurDeplacement), 0, delai, opacity);
					if (this.animateLastImg){
						this.doSlide(this.imgs[this.currentImgIndex], (i *-1 * step), 0, delai);
					}
				}
			} else {		
				if (this.animation == 'ttb' || this.animation == 'btt'){
					this.doSlide(this.imgs[imgIndex], 0, (i * step -longueurDeplacement), delai, opacity);		
					if (this.animateLastImg){
						this.doSlide(this.imgs[this.currentImgIndex], 0, (i * step), delai);
					}
				} else {
					this.doSlide(this.imgs[imgIndex], (i * step -longueurDeplacement), 0, delai, opacity);		
					if (this.animateLastImg){
						this.doSlide(this.imgs[this.currentImgIndex], (i * step), 0, delai);
					}
				}
			}
			if (i == 0){
				setTimeout(function(){ inst.imgs[imgIndex].style.display = 'block'; }, delai, opacity);
			}
		}
		if (null !== this.numbersContainer){
			// On calcule le 50%
			var delai50 = this.speedAnimating *(this.nbSteps /2);
			setTimeout(function(){ inst.setActiveNumber(imgIndex); }, delai50);
		}
		if (typeof(this.onMiddleSlidingCallback) == 'function'){
			// On calcule le 50%
			var delai50 = this.speedAnimating *(this.nbSteps /2);
			setTimeout(function(){ inst.onMiddleSlidingCallback.call(inst, imgIndex); }, delai50);
		}
		setTimeout(function(){ 
			inst.doSlide(inst.imgs[imgIndex], 0, 0, 0, 100);
			inst.setOpacity(inst.imgs[inst.currentImgIndex], 100);
			inst.imgs[inst.currentImgIndex].style.display = 'none'; 
			inst.imgs[inst.currentImgIndex].style.zIndex = inst.defaultZIndex; 
			
			inst.currentImgIndex = imgIndex;
			inst.animating = false; 
			if (inst.speedCarrousel > 0){
				inst.prepareNext();
			}
			if (typeof(inst.onAfterSlidingCallback) == 'function'){
				inst.onAfterSlidingCallback.apply(inst);
			}
		}, delai);
	}
	
	return this;
};

RSPlug_Carrousel2.prototype.setOpacity = function (obj, opacity){
	if (obj && obj.style){
		opacity = parseInt(opacity);
		obj.style.opacity = (opacity / 100);
		obj.style.MozOpacity = (opacity / 100);
		obj.style.KhtmlOpacity = (opacity / 100);
		if (navigator.userAgent.toLowerCase().indexOf('msie') >= 0){
			obj.style.filter = 'alpha(opacity=' + opacity + ')';
		}	
	}
};

RSPlug_Carrousel2.prototype.doFade = function (obj, opacity, delai){
	var inst = this;
	setTimeout(function(){ 
		inst.setOpacity(obj, opacity); 
	}, delai);
};

RSPlug_Carrousel2.prototype.doSlide = function (obj, left, top, delai, opacity){
	var inst = this;
	setTimeout(function(){ 
		if (obj && obj.style){ 
			obj.style.left = left +'px'; 
			obj.style.top = top +'px'; 
			if (null !== opacity){ 
				inst.setOpacity(obj, opacity); 
			} 
		} 
	}, delai);
};

