/**
* TransitionBox jQuery plugin
* @version : 1.10 iXoft 2011.03.15 powered by Kynes. First 'show' call Safari bug fixed. Positionning fixed again. 'easeOutSoftBounce' easing modified. 'flip' effects cosmetic bug fixed.
* @dependency: jQuery 1.4.2 or newer
* @usage : initializing
	var API = $('#myDiv').transitionBox({
		"width" : 600, // px
		"height" : 600, // px
		"duration" : 800, // microseconds
		"easing" : "linear", // string
		"effect" : "fade", // string
		"fadeOut" : true // convenient for images with different sizes
	});
* @usage : call
	// API.show('myPicture.jpg' [,'slideTop' [,'800' [,'easeInQuad' [,true [,function() {}]]]]]);
	API.show('myPicture.jpg','top',function() {
    	// Animation complete.
  	});
	// API.hide([,'zoom' [,'1200' [,'easeInQuad' [,true [,function() {}]]]]]);
  	API.hide('left',800,function() {
    	// Animation complete.
  	});
* @usage : alternate call
	API.image('myPicture.jpg').effect('top').show();
*/

/*
TERMS OF USE

Copyright © 2010-11 iXoft
All rights reserved.

This code is distributed as freeware, so it can be used for free but can not be sold.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/* principe général :
	1 div et 2 images sont créées dans l'élément sélectionné : imgMain (avec les caractéristiques de imageActuelle) et imgTemp (avec les caractéristiques de imageSuivante)
*/

/* principe des effets :
	1 - Temp est placé hors-champ
	2 - la nouvelle image (fichierImg) est chargée dans Temp
	3 - Temp est rendu invisible et placé au bon endroit suivant l'effet voulu
	4 - Animation de Temp et de Main
	5 - A la fin de l'animation :
			- Main est placé à la position et aux dimensions de Temp
			- l'image de Temp est transférée dans Main
			- Temp est masqué
*/

(function($) {
	// --------------------------------------------------------------------- API 
	function TransitionAPI(element,settings) {
		// -------------- vérification/correction de width et height
		var heightOK = true;
		if (isNaN(parseInt(settings.height,10)) || (parseInt(settings.height,10) != settings.height - 0)) {
			heightOK = false;
		}else{
			if (settings.height < 1) heightOK = false;
		}
		var widthOK = true;
		if (isNaN(parseInt(settings.width,10)) || (parseInt(settings.width,10) != settings.width - 0)) {
			widthOK = false;
		}else{
			if (settings.width < 1) widthOK = false;
		}
		if (!heightOK) {
			if (!widthOK) settings.width = 400; // defaults
			settings.height = settings.width;
		}
		if (!widthOK) {
			if (!heightOK) settings.height = 400; // defaults
			settings.width = settings.height;
		}
		
		// -------------- creation d'une DIV dans l'element passé (par sécurité, si l'élément passé est "bizarre")
		var transZone = $('<div style="position: relative; top: -100px; left: -70px; width: ' + settings.width + 'px; height: ' + settings.height + 'px; overflow: hidden;  z-index:1">').appendTo(element);
		// -------------- creation des images Main et Temp dans cette DIV
		var imgMain = $('<img src="" />').appendTo(transZone);
		// ------ ajustements padding et margin // 1.10
		var extraWidth = parseInt(imgMain.css('padding-left')) + parseInt(imgMain.css('padding-right')) + parseInt(imgMain.css('border-left-width')) + parseInt(imgMain.css('border-right-width')); // bordure et padding image
		var extraHeight = parseInt(imgMain.css('padding-top')) + parseInt(imgMain.css('padding-bottom')) + parseInt(imgMain.css('border-top-width')) + parseInt(imgMain.css('border-bottom-width')); // bordure et padding image
		// ------
		imgMain.css({'position': 'absolute', 'top': settings.height + 20 + 'px', 'left': 0, 'max-width': (settings.width - extraWidth) + 'px', 'max-height': (settings.height - extraHeight) + 'px', 'z-index':1}); // bug SAFARI si application directe des CSS lors de l'append !
		var imgTemp = $('<img src="" />').appendTo(transZone);
		imgTemp.css({'position': 'absolute', 'top': settings.height, 'left': 0, 'max-width': (settings.width - extraWidth) + 'px','max-height': (settings.height - extraHeight) + 'px', 'z-index':1}); // bug SAFARI si application directe des CSS lors de l'append !
		// -------------- init
		var etatVide = true; // avant le 1er appel ou après méthode clearCache()
		var imgActuelle = {'src': settings.image, 'top': 0, 'left': 0, 'width': 0, 'height': 0, 'bottom': 0, 'right': 0};
		if (settings.image != '' && Object.prototype.toString(settings.image) !== '[object String]') {
			imgMain.bind("load", function() {
				imgActuelle['width'] = parseInt(imgMain.width());
				imgActuelle['height'] = parseInt(imgMain.height());
				imgActuelle['top'] = Math.floor((settings.height - imgActuelle['height'])/2);
				imgActuelle['left'] = Math.floor((settings.width - imgActuelle['width'])/2);
				imgActuelle['bottom'] = imgActuelle['top'] + imgActuelle['height'];
				imgActuelle['right'] = imgActuelle['left'] + imgActuelle['width'];
				imgMain.css({"top": imgActuelle['top'] + 'px', "left": imgActuelle['left'] + 'px', "opacity": 1}); // placement au centre
				imgMain.unbind("load");
			}).attr('src',settings.image);
		}
		var imgSuivante = {'src': '', 'top': settings.height, 'left': 0, 'width': 0, 'height': 0};
		var marginSecu = 1; // distance supplémentaire (en px) de sécurité pour effet images
		var listeEffets = {'slidetop': true, 'slidebottom': true, 'slideleft': true, 'slideright': true, 'crosstop': true, 'crossbottom': true, 'crossleft': true, 'crossright': true, 'stretchtop': true, 'stretchbottom': true, 'stretchleft': true, 'stretchright': true, 'fliphorizontal': true, 'flipvertical': true, 'zoom': true, 'fade': true}; // 'fade' par defaut
		var listeEasings = {'linear': true, 'easeinquad': true, 'easeincubic': true, 'easeinoutcubic': true, 'easeoutcubic': true, 'easeoutbounce': true, 'easeoutsoftbounce': true}; // 'linear' par defaut
		var that = this; // copie de this pour appels fcns internes
		var thisthat = this; // copie de this pour appels fcns internes plus "profondes"
		
		// ------------------------------------- methodes
		this.show = function(fichierImg,effet,duree,easing,fonduDoux,callbackFnk) {
			if (imgTemp.is(':animated') || imgMain.is(':animated')) return this;
			
			// ------------------- vérification et formatage des paramètres
			fichierImg = this.getParamFichierImage(fichierImg);
			effet = this.getParamEffet(effet);
			duree = this.getParamDuration(duree);
			easing = this.getParamEasing(easing);
			fonduDoux = this.getParamFadeOut(fonduDoux);
			var opacite = (fonduDoux)? 0 : 1;
			callbackFnk = (typeof callbackFnk == 'function')? callbackFnk : $.noop;
			
			// ------------------ préparation
			this.prepareEffect();
			
			// ------------------ effet
			switch(effet) {
			case 'slidetop':
				imgTemp.bind("load", function() {
					that.prepareAnimate(fichierImg);
					// --------------------- effet
					that.placementTemp('bottom');
					if (etatVide) {
						that.hideMain(duree,fonduDoux);
					}else{
						imgMain.stop(true,false).animate({"top": -imgActuelle['height'] - marginSecu + 'px', "opacity": opacite}, duree, easing);
					}
 					// ---------------------
 					that.animeTemp(fichierImg,duree,easing,callbackFnk);
				}).attr('src',fichierImg);
				break;
			case 'slidebottom':
				imgTemp.bind("load", function() {
					that.prepareAnimate(fichierImg);
					// --------------------- effet
					that.placementTemp('top');
					if (etatVide) {
						that.hideMain(duree,fonduDoux);
					}else{
						imgMain.stop(true,false).animate({"top": settings.height + marginSecu + 'px', "opacity": opacite}, duree, easing);
					}
 					// ---------------------
 					that.animeTemp(fichierImg,duree,easing,callbackFnk);
				}).attr('src',fichierImg);
				break;
			case 'slideleft':
				imgTemp.bind("load", function() {
					that.prepareAnimate(fichierImg);
					// --------------------- effet
					that.placementTemp('right');
					if (etatVide) {
						that.hideMain(duree,fonduDoux);
					}else{
						imgMain.stop(true,false).animate({"left": -imgActuelle['width'] - marginSecu + 'px', "opacity": opacite}, duree, easing);
					}
 					// ---------------------
 					that.animeTemp(fichierImg,duree,easing,callbackFnk);
				}).attr('src',fichierImg);
				break;
			case 'slideright':
				imgTemp.bind("load", function() {
					that.prepareAnimate(fichierImg);
					// --------------------- effet
					that.placementTemp('left');
					if (etatVide) {
						that.hideMain(duree,fonduDoux);
					}else{
						imgMain.stop(true,false).animate({"left": settings.width + marginSecu + 'px', "opacity": opacite}, duree, easing);
					}
 					// ---------------------
 					that.animeTemp(fichierImg,duree,easing,callbackFnk);
				}).attr('src',fichierImg);
				break;
			case 'crosstop':
				imgTemp.bind("load", function() {
					that.prepareAnimate(fichierImg);
					// --------------------- effet
					that.placementTemp('bottom');
					if (etatVide) {
						that.hideMain(duree,fonduDoux);
					}else{
						imgMain.stop(true,false).animate({"top": settings.height + marginSecu + 'px', "opacity": opacite}, duree);
					}
 					// ---------------------
 					that.animeTemp(fichierImg,duree,easing,callbackFnk);
				}).attr('src',fichierImg);
				break;
			case 'crossbottom':
				imgTemp.bind("load", function() {
					that.prepareAnimate(fichierImg);
					// --------------------- effet
					that.placementTemp('top');
					if (etatVide) {
						that.hideMain(duree,fonduDoux);
					}else{
						imgMain.stop(true,false).animate({"top": -imgActuelle['height'] - marginSecu + 'px', "opacity": opacite}, duree);
					}
 					// ---------------------
 					that.animeTemp(fichierImg,duree,easing,callbackFnk);
				}).attr('src',fichierImg);
				break;
			case 'crossleft':
				imgTemp.bind("load", function() {
					that.prepareAnimate(fichierImg);
					// --------------------- effet
					that.placementTemp('right');
					if (etatVide) {
						that.hideMain(duree,fonduDoux);
					}else{
						imgMain.stop(true,false).animate({"left": settings.width + marginSecu + 'px', "opacity": opacite}, duree);
					}
 					// ---------------------
 					that.animeTemp(fichierImg,duree,easing,callbackFnk);
				}).attr('src',fichierImg);
				break;
			case 'crossright':
				imgTemp.bind("load", function() {
					that.prepareAnimate(fichierImg);
					// --------------------- effet
					that.placementTemp('left');
					if (etatVide) {
						that.hideMain(duree,fonduDoux);
					}else{
						imgMain.stop(true,false).animate({"left": -imgActuelle['width'] - marginSecu + 'px', "opacity": opacite}, duree);
					}
 					// ---------------------
 					that.animeTemp(fichierImg,duree,easing,callbackFnk);
				}).attr('src',fichierImg);
				break;
			case 'stretchtop':
				imgTemp.bind("load", function() {
					that.prepareAnimate(fichierImg);
					// --------------------- effet
					that.placementTemp('bottom');
					imgTemp.css({"width": imgSuivante['width'] + 'px', "height": 0}); // special pour cet effet
					if (etatVide) {
						that.hideMain(duree,fonduDoux);
					}else{
						imgMain.stop(true,false).animate({"top": imgActuelle['top'] + 'px', "left": imgActuelle['left'] + 'px', "width": imgActuelle['width'] + 'px', "height": 0, "opacity": opacite}, duree, easing);
					}
 					// ---------------------
 					that.animeTemp(fichierImg,duree,easing,callbackFnk);
				}).attr('src',fichierImg);
				break;
			case 'stretchbottom':
				imgTemp.bind("load", function() {
					that.prepareAnimate(fichierImg);
					// --------------------- effet
					that.placementTemp('top',true);
					imgTemp.css({"width": imgSuivante['width'] + 'px', "height": 0}); // special pour cet effet
					if (etatVide) {
						that.hideMain(duree,fonduDoux);
					}else{
						imgMain.stop(true,false).animate({"top": imgActuelle['bottom'] + 'px', "height": 0, "width": imgActuelle['width'] + 'px', "opacity": opacite}, duree, easing);
					}
 					// ---------------------
 					that.animeTemp(fichierImg,duree,easing,callbackFnk);
				}).attr('src',fichierImg);
				break;
			case 'stretchleft':
				imgTemp.bind("load", function() {
					that.prepareAnimate(fichierImg);
					// --------------------- effet
					that.placementTemp('right');
					imgTemp.css({"width": 0, "height": imgSuivante['height'] + 'px'}); // special pour cet effet
					if (etatVide) {
						that.hideMain(duree,fonduDoux);
					}else{
						imgMain.stop(true,false).animate({"left": imgActuelle['left'] + 'px', "width": 0, "height": imgActuelle['height'] + 'px', "opacity": opacite}, duree, easing);
					}
 					// ---------------------
 					that.animeTemp(fichierImg,duree,easing,callbackFnk);
				}).attr('src',fichierImg);
				break;
			case 'stretchright':
				imgTemp.bind("load", function() {
					that.prepareAnimate(fichierImg);
					// --------------------- effet
					that.placementTemp('left',true);
					imgTemp.css({"width": 0, "height": imgSuivante['height'] + 'px'}); // special pour cet effet
					if (etatVide) {
						that.hideMain(duree,fonduDoux);
					}else{
						imgMain.stop(true,false).animate({"left": imgActuelle['right'] + 'px', "width": 0, "height": imgActuelle['height'] + 'px', "opacity": opacite}, duree, easing);
					}
 					// ---------------------
 					that.animeTemp(fichierImg,duree,easing,callbackFnk);
				}).attr('src',fichierImg);
				break;
			case 'flipvertical':
				imgTemp.bind("load", function() {
					that.prepareAnimate(fichierImg);
					// --------------------- effet (procedure speciale pour cet effet) // 1.10
					imgTemp.css({"top": Math.floor(settings.height /2) + 'px', "left": Math.floor((settings.width - imgSuivante['width'])/2) + 'px', "width": imgSuivante['width'] + 'px', "height": 0, "opacity": 0}); // placement au centre pour effet
					if (etatVide) {
						that.hideMain(duree,fonduDoux);
						imgTemp.stop(true,false).animate({"top": imgSuivante['top'] + 'px', "left": imgSuivante['left'] + 'px', "width": imgSuivante['width'] + 'px', "height": imgSuivante['height'] + 'px', "opacity": 1}, duree, easing, function() {
						// ---------------------
							thisthat.endEffect(fichierImg);
							callbackFnk.call(this);
						});
					}else{
						imgMain.stop(true,false).animate({"top": Math.floor(settings.height /2) + 'px', "left": imgActuelle['left'] + 'px', "width": imgActuelle['width'] + 'px', "height": 0, "opacity": opacite}, duree, function() {
							imgTemp.stop(true,false).animate({"top": imgSuivante['top'] + 'px', "left": imgSuivante['left'] + 'px', "width": imgSuivante['width'] + 'px', "height": imgSuivante['height'] + 'px', "opacity": 1}, duree, easing, function() {
						// ---------------------
								thisthat.endEffect(fichierImg);
								callbackFnk.call(this);
							});
						});
					}
					imgTemp.unbind("load");
				}).attr('src',fichierImg);
				break;
			case 'fliphorizontal':
				imgTemp.bind("load", function() {
					that.prepareAnimate(fichierImg);
					// --------------------- effet (procedure speciale pour cet effet) // 1.10
					imgTemp.css({"top": Math.floor((settings.height - imgSuivante['height'])/2) + 'px', "left": Math.floor(settings.width /2) + 'px', "width": 0, "height": imgSuivante['height'] + 'px', "opacity": 0}); // placement au centre pour effet
					if (etatVide) {
						that.hideMain(duree,fonduDoux);
						imgTemp.stop(true,false).animate({"top": imgSuivante['top'] + 'px', "left": imgSuivante['left'] + 'px', "width": imgSuivante['width'] + 'px', "height": imgSuivante['height'] + 'px', "opacity": 1}, duree, easing, function() {
 					// ---------------------
							thisthat.endEffect(fichierImg);
							callbackFnk.call(this);
						});
					}else{
						imgMain.stop(true,false).animate({"top": imgActuelle['top'] + 'px', "left": Math.floor(settings.width /2) + 'px', "width": 0, "height": imgActuelle['height'] + 'px', "opacity": opacite}, duree, function() {
							imgTemp.stop(true,false).animate({"top": imgSuivante['top'] + 'px', "left": imgSuivante['left'] + 'px', "width": imgSuivante['width'] + 'px', "height": imgSuivante['height'] + 'px', "opacity": 1}, duree, easing, function() {
						// ---------------------
								thisthat.endEffect(fichierImg);
								callbackFnk.call(this);
							});
						});
					}
					imgTemp.unbind("load");
				}).attr('src',fichierImg);
				break;
			case 'zoom':
				imgTemp.bind("load", function() {
					that.prepareAnimate(fichierImg);
					// --------------------- effet (procedure speciale pour cet effet)
					imgTemp.css({"top": Math.floor(settings.height /2) + 'px', "left": Math.floor(settings.width /2) + 'px', "width": 0, "height": 0, "opacity": 0}); // placement au centre pour effet
					if (etatVide) that.hideMain(duree,fonduDoux);
					imgMain.stop(true,false).animate({"opacity": 0}, duree * 1.2, easing);
					imgTemp.stop(true,false).animate({"top": imgSuivante['top'] + 'px', "left": imgSuivante['left'] + 'px', "width": imgSuivante['width'] + 'px', "height": imgSuivante['height'] + 'px', "opacity": 1}, duree, easing, function() {
 					// ---------------------
						thisthat.endEffect(fichierImg);
						callbackFnk.call(this);
 					});
					imgTemp.unbind("load");
				}).attr('src',fichierImg);
				break;
			default: // fade
				imgTemp.bind("load", function() {
					that.prepareAnimate(fichierImg);
					// --------------------- effet
					imgTemp.css({"top": imgSuivante['top'] + 'px', "left": imgSuivante['left'] + 'px', "opacity": 0}); // placement au centre
					if (etatVide) {
						that.hideMain(duree,fonduDoux);
					}else{
						imgMain.stop(true,false).animate({"opacity": 0}, duree);
					}
 					// ---------------------
					imgTemp.stop(true,false).animate({"opacity": 1}, duree, easing, function() {
						thisthat.endEffect(fichierImg);
						callbackFnk.call(this);
 					});
					imgTemp.unbind("load");
				}).attr('src',fichierImg);
				break;
			}
			settings.image = fichierImg;
			return this;
		}
		
		this.hide = function(effet,duree,easing,fonduDoux,callbackFnk) {
			if (imgTemp.is(':animated') || imgMain.is(':animated')) return this;
			
			// ---------- vérification et formatage des paramètres
			effet = this.getParamEffet(effet);
			duree = this.getParamDuration(duree);
			easing = this.getParamEasing(easing);
			fonduDoux = this.getParamFadeOut(fonduDoux);
			var opacite = (fonduDoux)? 0 : 1;
			callbackFnk = (typeof callbackFnk == 'function') ? callbackFnk : $.noop;
			
			// ------------------ préparation
			this.prepareEffect();
			
			// --------------- effet
			if (effet == 'slidetop' || effet == 'crossbottom') {
				imgMain.stop(true,false).animate({"top": -imgActuelle['height'] - marginSecu + 'px', "opacity": opacite}, duree, easing, function() {
					that.clearMain();
					callbackFnk.call(this);
				});
  			}else if (effet == 'slidebottom' || effet == 'crosstop') {
				imgMain.stop(true,false).animate({"top": settings.height + marginSecu + 'px', "opacity": opacite}, duree, easing, function() {
					that.clearMain();
					callbackFnk.call(this);
				});
  			}else if (effet == 'slideleft' || effet == 'crossright') {
				imgMain.stop(true,false).animate({"left": -settings.width - marginSecu + 'px', "opacity": opacite}, duree, easing, function() {
					that.clearMain();
					callbackFnk.call(this);
				});
  			}else if (effet == 'slideright' || effet == 'crossleft') {
				imgMain.stop(true,false).animate({"left": settings.width + marginSecu + 'px', "opacity": opacite}, duree, easing, function() {
					that.clearMain();
					callbackFnk.call(this);
				});
  			}else if (effet == 'stretchtop') {
				imgMain.stop(true,false).animate({"height": 0, "width": imgActuelle['width'] + 'px', "opacity": opacite}, duree, easing, function() {
					that.clearMain();
					callbackFnk.call(this);
				});
  			}else if (effet == 'stretchbottom') {
				imgMain.stop(true,false).animate({"top": Math.min(settings.height,imgActuelle['height'] * 1.1), "height": 0, "width": imgActuelle['width'] + 'px', "opacity": opacite}, duree, easing, function() {
					that.clearMain();
					callbackFnk.call(this);
				});
  			}else if (effet == 'stretchleft') {
				imgMain.stop(true,false).animate({"width": 0, "height": imgActuelle['height'] + 'px', "opacity": opacite}, duree, easing, function() {
					that.clearMain();
					callbackFnk.call(this);
				});
  			}else if (effet == 'stretchright') {
				imgMain.stop(true,false).animate({"left": Math.min(settings.width,imgActuelle['right'] * 1.1) + 'px', "width": 0, "height": imgActuelle['height'] + 'px', "opacity": opacite}, duree, easing, function() {
					that.clearMain();
					callbackFnk.call(this);
				});
  			}else if (effet == 'flipvertical') {
  				imgMain.stop(true,false).animate({"top": Math.floor(settings.height /2) + 'px', "left": imgActuelle['left'] + 'px', "width": imgActuelle['width'] + 'px', "height": 0, "opacity": opacite}, duree, easing, function() {
					that.clearMain();
					callbackFnk.call(this);
				});
  			}else if (effet == 'fliphorizontal') {
				imgMain.stop(true,false).animate({"top": imgActuelle['top'] + 'px', "left": Math.floor(settings.width /2) + 'px', "width": 0, "height": imgActuelle['height'] + 'px', "opacity": opacite}, duree, easing, function() {
					that.clearMain();
					callbackFnk.call(this);
				});
  			}else if (effet == 'zoom') {
				imgMain.stop(true,false).animate({"top": Math.floor(settings.height /2) + 'px', "left": Math.floor(settings.width /2) + 'px', "width": 0, "height": 0, "opacity": opacite}, duree, easing, function() {
					that.clearMain();
					callbackFnk.call(this);
				});
  			}else{ // fade
				imgMain.stop(true,false).animate({"opacity": 0}, duree, easing, function() {
					that.clearMain();
					callbackFnk.call(this);
				});
			}
			
			// --------------- vidage
			this.clearCache();
			return this;
		}
		
		// ------------------------------------------------------------------- METHODES PUBLIQUES (getters et setters)
		
		this.clearCache = function() { // ----------------- setter pour appels ultérieurs
			etatVide = true;
			return this;
		}
		
		this.image = function(fichierImg) { // image de l'element 'main'
			if (fichierImg == undefined) { // ------------- getter
				return imgMain.attr('src'); // string
			}else{ // ------------------------------------- setter
				settings.image = this.getParamFichierImage(fichierImg);
				return this;
			}
		}
		
		this.effect = function(effet) {
			if (effet == undefined) { // ------------- getter
				return settings.effect; // string
			}else{ // -------------------------------- setter
				settings.effect = this.getParamEffet(effet);
				return this;
			}
		}
		
		this.duration = function(duree) {
			if (duree == undefined) { // ------------- getter
				return settings.duration; // integer
			}else{ // -------------------------------- setter
				settings.duration = this.getParamDuration(duree);
				return this;
			}
		}
		
		this.easing = function(easing) {
			if (easing == undefined) { // ------------- getter
				return settings.easing; // string
			}else{ // -------------------------------- setter
				settings.easing = this.getParamEasing(easing);
				return this;
			}
		}
		
		this.fadeOut = function(fonduDoux) {
			if (fonduDoux == undefined) { // ------------- getter
				return settings.fadeOut; // integer
			}else{ // ------------------------------------ setter
				settings.fadeOut = this.getParamFadeOut(fonduDoux);
				return this;
			}
		}
		
		this.getConf = function() { // ----------------- getter
			return settings; // config as JS object
		}
		
		this.getImage = function() { // ---------------- getter
			return imgMain; // image as jQuery object
		}
		
		this.getRoot = function() { // ----------------- getter
			return transZone; // div as jQuery object
		}
		
		// ------------------------------------------------------------------- METHODES INTERNES
		
		// -------------------------------------------- preparation effet pour fcn show()
		this.prepareEffect = function() {
			imgTemp.attr('src','');
			imgActuelle['src'] = imgMain.attr('src');
			if (imgActuelle['src'] != '') {
				imgActuelle['top'] = parseInt(imgMain.css('top'));
				imgActuelle['left'] = parseInt(imgMain.css('left'));
				imgActuelle['width'] = parseInt(imgMain.width());
				imgActuelle['height'] = parseInt(imgMain.height());
				imgActuelle['bottom'] = imgActuelle['top'] + imgActuelle['height'];
				imgActuelle['right'] = imgActuelle['left'] + imgActuelle['width'];
			}else{ // necessité de remettre bien tout à zéro (sinon bug dans certains cas)
				imgActuelle['top'] = 0;
				imgActuelle['left'] = 0;
				imgActuelle['width'] = 0;
				imgActuelle['height'] = 0;
				imgActuelle['bottom'] = 0;
				imgActuelle['right'] = 0;
			}
			// placement Temp hors champ, mais *visible* pour futur calcul taille image
			imgTemp.css({"top": settings.height + 20 + 'px', "left": 0, "opacity": 1});
		}
		
		// -------------------------------------------- preparation apres load juste avant animate pour fcn show()
		this.prepareAnimate = function(fichierImage) {
			imgTemp.css({"width": 'auto', "height": 'auto'}); // reset à la taille nominale
			
			imgSuivante['src'] = fichierImage;
			imgSuivante['width'] = imgTemp.width();
			imgSuivante['height'] = imgTemp.height();
			imgSuivante['top'] = Math.floor((settings.height - (imgSuivante['height'] + extraHeight))/2); // 1.10
			imgSuivante['left'] = Math.floor((settings.width - (imgSuivante['width'] + extraWidth))/2); // 1.10
		}
		
		// -------------------------------------------- effacement de Main si etatVide = true pour fcn show()
		this.hideMain = function(duree,fondu) {
			var dureeEffacement = (fondu)? duree : 50;
			imgMain.stop(true,false).animate({"opacity": 0}, dureeEffacement);
			etatVide = false;
		}
		
		// -------------------------------------------- placement de Temp (invisible) pour effet
		this.placementTemp = function(where,zeroSize) {
			// position depart : si pas d'image actuelle (1er appel ou apres un vidage de cache) -> bord zone, sinon -> bord de l'image actuelle
			// si zeroSize, la largeur ou la hauteur de l'image Temp n'est pas comprise dans le placement
			if (zeroSize == undefined) zeroSize = false; // defaut
			
			switch(where) {
			case 'bottom': // placement en bas
				var depart = (imgActuelle['bottom'] == 0 || etatVide)? settings.height : imgActuelle['bottom'];
				imgTemp.css({"top": depart + 'px', "left": imgSuivante['left'] + 'px', "opacity": 0});
				break;
			case 'left': // placement a gauche
				var tailleActuelle = (zeroSize)? 0 : imgSuivante['width'];
				var depart = (imgActuelle['left'] == 0 || etatVide)? -tailleActuelle - marginSecu : imgActuelle['left'] - tailleActuelle;
				imgTemp.css({"top": imgSuivante['top'] + 'px', "left": depart + 'px', "opacity": 0});
				break;
			case 'right': // placement a droite
				var depart = (imgActuelle['right'] == 0 || etatVide)? settings.width : imgActuelle['right'];
				imgTemp.css({"top": imgSuivante['top'] + 'px', "left": depart + 'px', "opacity": 0});
				break;
			default: // top : placement en haut
				var tailleActuelle = (zeroSize)? 0 : imgSuivante['height'];
				var depart = (imgActuelle['top'] == 0 || etatVide)? -tailleActuelle - marginSecu : imgActuelle['top'] - tailleActuelle;
				imgTemp.css({"top": depart + 'px', "left": imgSuivante['left'] + 'px', "opacity": 0});
			}
		}
			
		// -------------------------------------------- animation de Temp
		this.animeTemp = function(fichierImg,duree,easing,callbackFnk) {
			imgTemp.stop(true,false).animate({"top": imgSuivante['top'] + 'px', "left": imgSuivante['left'] + 'px', "width": imgSuivante['width'] + 'px', "height": imgSuivante['height'] + 'px', "opacity": 1}, duree, easing, function() {
				that.endEffect(fichierImg);
				callbackFnk.call(this);
 			});
			imgTemp.unbind("load");
		}
		
		this.endEffect = function(fichierImg) {
			imgMain.stop(true,false).attr('src',fichierImg).css({"top": imgSuivante['top'] + 'px', "left": imgSuivante['left'] + 'px', "width": imgSuivante['width'] + 'px', "height": imgSuivante['height'] + 'px', "opacity": 1}); // maj Main
			imgTemp.css({"top": settings.height + 20 + 'px', "left": 0, "opacity": 0});
		}
		
		// -------------------------------------------- pour fcn hide()
		this.clearMain = function() {
			imgMain.attr('src','');
			settings.image = '';
		}
		
		// -------------------------------------------- erreurs
		this.displayError = function(errorStr) { // non utilise
			throw new Error('Error in TransitionBox: ' + errorStr,'');
		}
		
		// -------------------------------------------- test des parametres
		this.getParamFichierImage = function(param) { // '' par defaut
			if (param == undefined) {
				param = settings.image;
			}else if (Object.prototype.toString.call(param) !== '[object String]'){
				param = '';
			}
			return param;
		}
		
		this.getParamEffet = function(param) { // 'fade' par defaut
			if (param == undefined) {
				param = settings.effect;
			}else if (Object.prototype.toString.call(param) !== '[object String]'){
				param = 'fade';
			}else if (param == ''){
				param = 'fade';
			}else{
				param = param.toLowerCase();
				if (!listeEffets.hasOwnProperty(param)) param = 'fade';
			}
			return param;
		}
		
		this.getParamEasing = function(param) { // 'linear' par defaut
			if (param == undefined) {
				param = settings.easing;
			}else if (Object.prototype.toString.call(param) !== '[object String]'){
				param = 'linear';
			}else if (param == ''){
				param = 'linear';
			}else{
				param = param.toLowerCase();
				if (!listeEasings.hasOwnProperty(param)) param = 'linear';
			}
			return param;
		}
		
		this.getParamDuration = function(param) { // 600 par defaut
			if (param == undefined) {
				param = settings.duration;
			}else if (isNaN(parseInt(param,10)) || (parseInt(param,10) != param - 0)) {
				param = 600;
			}else{
				param = Math.min(10000,Math.max(1,parseInt(param))); // entre 1 microsecondes et 10 secondes
			}
			return parseInt(param);
		}
		
		this.getParamFadeOut = function(param) { // true par defaut
			if (param == undefined) {
				param = settings.fadeOut;
			}else if (param !== false) {
				param = true;
			}
			return param;
		}
		
		this.getParamApi = function(param) { // true par defaut
			if (param == undefined) {
				param = settings.api;
			}else if (param !== false) {
				param = true;
			}
			return param;
		}
	}

	// -------------------------------------------- easings

	jQuery.easing['easeinquad'] = function (x, t, b, c, d) { // Robert Penner
		return c*(t/=d)*t + b;
	}
	jQuery.easing['easeincubic'] = function (x, t, b, c, d) { // Robert Penner
		return c*(t/=d)*t*t + b;
	}

	jQuery.easing['easeinoutcubic'] = function (x, t, b, c, d) { // Robert Penner
		if ((t/=d/2) < 1) return c/2*t*t*t + b;
		return c/2*((t-=2)*t*t + 2) + b;
	}
	
	jQuery.easing['easeoutcubic'] = function (x, t, b, c, d) { // Robert Penner
		return c*((t=t/d-1)*t*t + 1) + b;
	}
	
	jQuery.easing['easeoutbounce'] = function (x, t, b, c, d) { // Robert Penner
		if ((t/=d) < (1/2.75)) {
			return c*(7.5625*t*t) + b;
		} else if (t < (2/2.75)) {
			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
		} else if (t < (2.5/2.75)) {
			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
		} else {
			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
		}
	}
	
	jQuery.easing['easeoutsoftbounce'] = function (x, t, b, c, d) { // iXoft (2nd version : 1.10)
		if (x < 0.6) {
			return 2.7777 * x*x;
		} else if (x < 0.8) {
			return 4.84 + (x * -11.2) + (x * x * 8);
		} else if (x < 0.92) {
			return 9.1776 + (x * -19.1108) + (x * x * 11.1109);
		} else {
			return 12.499 + (x * -23.9979) + (x * x * 12.4989);
		}
	}

	$.fn.transitionBox = function(options) {
		// ------------------- paramétrage
		var defaults = {
			"width" : 0, // pixels
			"height" : 0, // pixels
			"duration" : 600, // microseconds
			"effect" : "fade", // string
			"easing" : "linear",
			"fadeOut" : true,
			"image" : '', // image file resource (string)
			"api" : true // renvoit l'API par defaut plutot que l'objet jQuery
		}
		var settings = $.extend(true,{}, defaults, options); // merge des options passées et des réglages defaults avec 'true' pour récursivité en profondeur (inutile dans ce cas car il n'y a qu'un niveau)
	
		// ------------------- traitement et retour
		var APItb = new TransitionAPI(this,settings);
		return (settings.api)? APItb : this;
	};
})(jQuery);

/*
 * TERMS OF USE - EASING EQUATIONS
 * 
 * Open source under the BSD License. 
 * 
 * Copyright © 2001 Robert Penner
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 * 
 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
 * 
 * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  OF THE POSSIBILITY OF SUCH DAMAGE.
*/
