front_idill/src/player/metadataplayer/Timeline.js
changeset 52 277c94533395
parent 47 4e1ee94d70b1
child 55 afd60399a7b5
--- a/front_idill/src/player/metadataplayer/Timeline.js	Mon Jul 23 10:52:41 2012 +0200
+++ b/front_idill/src/player/metadataplayer/Timeline.js	Mon Jul 23 16:59:35 2012 +0200
@@ -1,159 +1,166 @@
+/*
+* This file is part of the TraKERS\Front IDILL package.
+*
+* (c) IRI <http://www.iri.centrepompidou.fr/>
+*
+* For the full copyright and license information, please view the LICENSE
+* file that was distributed with this source code.
+*/
+
+/*
+ * Projet : TraKERS
+ * Module : Front IDILL
+ * Fichier : Timeline.js
+ * 
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ * 
+ * Fonctionnalités : Widget de la timeline du player incorporé dans le Front.
+ */
+
 /*
  The Timeline Widget fits right under the video
+ * Est appelé dans les fichiers créant les widgets du metadataplayer.
  */
 
 IriSP.Widgets.Timeline = function(player, config) {
-	
+    
     IriSP.Widgets.Widget.call(this, player, config);
-	this.bindPopcorn("timeupdate","onTimeupdate");
-	this.bindPopcorn("loadedmetadata","ready");
-	this.bindPopcorn("markersready","onMarkersReady");
-    //this.bindPopcorn("IriSP.PlayerWidget.MouseOver","onMouseover");
-    //this.bindPopcorn("IriSP.PlayerWidget.MouseOut","onMouseout");
-	this.timelineSelected = false;
-	this.markerShowTime = 200;
-	this.markerLastTime = 5000;
-	this.markerBigShown = false;
-	this.currentMarkerIdx = -1;
-	this.previousMarkerIdx = -1;
-	this.hideTimeout;
-	this.currentMode = "VIDEO";
-	this.paused = false
-	this.top_epsilon = 0;
-	this.imgDir = "player/img/";
-	this.markersDir = "pictos/small/";
-	this.player = player;
-	this.isCurrentlyInASearchByGesture = false;
-	this.mouseInteractions = false;
-	
-	//Id du marqueur enregistré.
-	this.currentMarkerId;
-	
-	this.gestures = ["fall", "jump", "circle", "screw", "bend", "arc", "knee-up", "right-angle", "wave", "no-motion", "contact"];
-	this.gesturesText = ["chute", "saut", "rotation", "rotation de groupe", "inclinaison", "port de bras", "levé de genou", "angle droit", "ondulation", "immobilité", "contact"];
-	
-	this.annotations = this.annotationsFilter(this.source.getAnnotations(), this.gestures, this.isGesture);
-	
-	// for(var a = 0 ; a < this.annotations.length ; a++)
-		// console.log("A : " + this.annotations[a].annotationType.contents.title);
+    this.bindPopcorn("timeupdate","onTimeupdate");
+    this.bindPopcorn("loadedmetadata","ready");
+    this.bindPopcorn("markersready","onMarkersReady");
+    this.timelineSelected = false;
+    this.markerShowTime = 200;
+    this.markerLastTime = 5000;
+    this.markerBigShown = false;
+    this.currentMarkerIdx = -1;
+    this.previousMarkerIdx = -1;
+    this.hideTimeout;
+    this.currentMode = "VIDEO";
+    this.paused = false
+    this.top_epsilon = 0;
+    this.imgDir = "player/img/";
+    this.markersDir = "pictos/small/";
+    this.player = player;
+    this.isCurrentlyInASearchByGesture = false;
+    this.mouseInteractions = false;
+    
+    //Id du marqueur enregistré.
+    this.currentMarkerId;
+    
+    //Gestures et noms par défaut.
+    this.gestures = ["fall", "jump", "circle", "screw", "bend", "arc", "knee-up", "right-angle", "wave", "no-motion", "contact"];
+    this.gesturesText = ["chute", "saut", "rotation", "rotation de groupe", "inclinaison", "port de bras", "levé de genou", "angle droit", "ondulation", "immobilité", "contact"];
+    
+	var _this = this;
+    this.annotations = this.source.getAnnotations().filter(function(annotation)
+	{
+		return _this.isGesture(annotation, null, _this.gestures);
+	});
 };
 
+/*
+ * Constructeur du Widget.
+*/
 IriSP.Widgets.Timeline.prototype = new IriSP.Widgets.Widget();
 
+/*
+ * Indique si l'annotation passée en paramètre référence une gesture utilisée dans ce Front.
+*/
 IriSP.Widgets.Timeline.prototype.isGesture = function(element, index, array)
 {
-	return ($.inArray(element.annotationType.contents.title, array) > -1);
+    return ($.inArray(element.annotationType.contents.title, array) > -1);
 }
 
 /*
  * Spécifie si on est en événements souris ou non.
+ * Est appelé dans le fichier :
+ * mosaic > fonction onMarkersReady.
 */
 IriSP.Widgets.Timeline.prototype.setMouseInteractions = function(mouseInteractions)
 {
-	this.mouseInteractions = mouseInteractions;
-	
-	if(mouseInteractions)
-	{
-		this.markersDir += 'MI/';
-	}
+    this.mouseInteractions = mouseInteractions;
+    
+    if(mouseInteractions)
+    {
+        this.markersDir += 'MI/';
+    }
 }
 
 /*
  * Spécifie la langue pour l'affichage des marqueurs.
+ * Est appelé dans le fichier :
+ * mosaic > fonction onMarkersReady.
 */
 IriSP.Widgets.Timeline.prototype.setLang = function(gesturesText)
 {
-	this.gesturesText = gesturesText;
+    this.gesturesText = gesturesText;
 }
 
-//Fonction associée à l'événement : les marqueurs sont prêts.
+/*
+ * Fonction associée à l'événement : les marqueurs sont prêts.
+ * Est appelé dans le fichier :
+ * mosaic > fonction onPlayerLoad.
+*/
 IriSP.Widgets.Timeline.prototype.onMarkersReady = function() {}
 
-//Fonction de filtrage de tableaux
-IriSP.Widgets.Timeline.prototype.annotationsFilter = function(annotations, gestures, fun /*, thisp*/)
-{
-	var len = annotations.length;
-	if (typeof fun != "function")
-		throw new TypeError();
-
-	var res = new Array();
-	var thisp = arguments[1];
-	for (var i = 0; i < len; i++)
-	{
-		if (i in annotations)
-		{
-			var val = annotations[i]; // in case fun mutates this
-			if (fun.call(thisp, val, i, gestures))
-			{
-				res.push(val);
-			}
-		}
-	}
-	return res;
-};
-
+/*
+ * Paramètres par défaut de la timeline.
+*/
 IriSP.Widgets.Timeline.prototype.defaults = {
     minimized_height : 114,//44,
     maximized_height : 114,
-	middle_height: 10,//4,
-	timelineBorderLength : 6,
+    middle_height: 10,//4,
+    timelineBorderLength : 6,
     minimize_timeout : 1500 // time before minimizing timeline after mouseout
 };
 
+/*
+ * Fonction appelée pour dessiner la timeline.
+*/
 IriSP.Widgets.Timeline.prototype.draw = function() {
     this.$timeline = IriSP.jQuery('<div>')
         .addClass("Ldt-Timeline")
         .css(this.calculateTimelineCss(this.minimized_height));
-	this.$timelineMiddle = IriSP.jQuery('<div>')
-		.addClass("Ldt-TimelineMiddle")
+    this.$timelineMiddle = IriSP.jQuery('<div>')
+        .addClass("Ldt-TimelineMiddle")
         .css(this.calculateTimelineMiddleCss(this.minimized_height, this.middle_height));
-	
-	/*this.$timelineContainer = IriSP.jQuery('<div>')
-        .addClass("Ldt-TimelineContainer");
-	this.$timelineContainer.append(this.$timeline);
-	this.$timelineContainer.append(this.$timelineMiddle);*/
-	
-	
+    
+    //On l'ajoute au widget.
     this.$.append(this.$timeline);
     this.$.append(this.$timelineMiddle);
-	
+    
     var _this = this;
     
+    //On définit le slider.
     this.$timeline.slider({
         range: "min",
         value: 0,
         min: 0,
         max: this.source.getDuration().milliseconds,
         slide: function(event, ui) {
-			if(_this.player.popcorn)
-			{
-				_this.player.popcorn.currentTime(Math.floor(ui.value/1000));
-				_this.player.popcorn.trigger("IriSP.Mediafragment.setHashToTime");
-			}
-			
-			// console.log("manual " + _this.previousMarkerIdx);
-			//On supprime le marqueur précédemment affiché si c'est le cas.
-			if(_this.previousMarkerIdx > -1)
-			{
-				// /!\ var annotations = _this.source.getAnnotations();
-				
-				// console.log("EXT hide idx " + _this.previousMarkerIdx);
-				// /!\ var previousMarker = IriSP.jQuery("#" + annotations[_this.previousMarkerIdx].id.replace(":", "_"));
-				var previousMarker = IriSP.jQuery("#" + _this.annotations[_this.previousMarkerIdx].id.replace(":", "_"));
-				_this.hideMarkerBig(previousMarker);
-				// console.log("EXT hide " + _this.previousMarkerIdx);
-			}
+            if(_this.player.popcorn)
+            {
+                _this.player.popcorn.currentTime(Math.floor(ui.value/1000));
+                _this.player.popcorn.trigger("IriSP.Mediafragment.setHashToTime");
+            }
+            
+            //On supprime le marqueur précédemment affiché.
+            if(_this.previousMarkerIdx > -1)
+            {
+                var previousMarker = IriSP.jQuery("#" + _this.annotations[_this.previousMarkerIdx].id.replace(":", "_"));
+                _this.hideMarkerBig(previousMarker);
+            }
         }
     });
-	
+    
     this.$handle = this.$timeline.find('.ui-slider-handle');
     
     this.$handle.css(this.calculateHandleCss(this.minimized_height));
-	
-    this.$
-        .mouseover(this.functionWrapper("onMouseover"))
-        .mouseout(this.functionWrapper("onMouseout"));
-		IriSP.jQuery('body').keypress(function(evt) {_this.keyPress(evt)});
+    
+    //On wrapp mouseover et mouse out.
+    this.$.mouseover(this.functionWrapper("onMouseover")).mouseout(this.functionWrapper("onMouseout"));
+    //On bind keypress.
+    IriSP.jQuery('body').keypress(function(evt) {_this.keyPress(evt)});
     
     this.maximized = false;
     this.timeoutId = false;
@@ -163,856 +170,818 @@
  * Starts playing the video when it's ready.
 */
 IriSP.Widgets.Timeline.prototype.ready = function() {
-	this.player.popcorn.play();
-	this.player.popcorn.mute();
-	this.processMarkers();
+    this.player.popcorn.play();
+    this.player.popcorn.mute();
+    this.processMarkers();
 }
 
 /*
- * Scale a value from [A, B] to [C, D].
+ * Met à l'échelle une valeur de [A, B] vers [C, D].
+ * Est appelé dans les fichiers :
+ * pointers > fonction pointersTimelineSelection.
+ * search > fonction searchFilter.
+ * Timeline > fonctions processMarkers, onTimeupdate et timeDisplayUpdater.
 */
 IriSP.Widgets.Timeline.prototype.scaleIntervals = function(A, B, C, D, val) {
-	if(C == D)
-	{
-		return C;
-	}	
-	if(B != A)
-	{
-		return D / (B - A) * (val - A);
-	}
-	else
-	{
-		//If A and B have the same sign.
-		if(A * B > 0)
-		{
-			//If they are positive.
-			if(A > 0)
-			{
-				return (D - C)/2;
-			}
-			else
-			{
-				return (C - D)/2;
-			}
-		}
-		else
-		{
-			return (C + D)/2;
-		}
-	}
+    if(C == D)
+    {
+        return C;
+    }    
+    if(B != A)
+    {
+        return D / (B - A) * (val - A);
+    }
+    else
+    {
+        //Si A et B ont le même signe.
+        if(A * B > 0)
+        {
+            //S'ils sont positifs.
+            if(A > 0)
+            {
+                return (D - C)/2;
+            }
+            else
+            {
+                return (C - D)/2;
+            }
+        }
+        else
+        {
+            return (C + D)/2;
+        }
+    }
 }
 
 /*
- * Process the markers.
+ * On calcule les marqueurs.
+ * Est appelé dans le fichier :
+ * Timeline > fonction ready.
 */
 IriSP.Widgets.Timeline.prototype.processMarkers = function() {
-	var _this = this;
-	var markers = "";
-	var timelineMiddleTop = this.$timelineMiddle.position().top;
-	
-	for(var i = 0 ; i < this.annotations.length ; i++)
-	{
-		markers += "<div class='Ldt-Marker' id='" + this.annotations[i].id.replace(":", "_") + "'></div>";
-	}
-	
-	this.$.append(markers);
-	var markerHeight = IriSP.jQuery(".Ldt-Marker").height();
-	IriSP.jQuery(".Ldt-Marker").css("z-align", "150");
-	
-	for(var i = 0 ; i < this.annotations.length ; i++)
-	{
-		IriSP.jQuery("#" + this.annotations[i].id.replace(":", "_")).css(
-		{
-			top: timelineMiddleTop + "px",
-			left: Math.floor(+this.scaleIntervals(0, this.source.getDuration().getSeconds(), 0, this.$timeline.width(), this.annotations[i].begin/1000) + this.$timeline.position().left) + "px",
-			"margin-top": (-_this.$timeline.height()/2 - markerHeight/2) - this.top_epsilon + "px"
-		});
-	}
-	
-	//On lance l'événement pour dire à popcorn que les marqueurs sont utilisables.
-	// this.player.popcorn.trigger(IriSP.Widgets.Timeline.onMarkersReady);
-	this.player.popcorn.trigger("markersready");
-	//console.log('markers processed');
+    var _this = this;
+    var markers = "";
+    //On calcule la position en Y de la timeline.
+    var timelineMiddleTop = this.$timelineMiddle.position().top;
+    
+    //Pour toutes les annotations, on crée les marqueurs.
+    for(var i = 0 ; i < this.annotations.length ; i++)
+    {
+        markers += "<div class='Ldt-Marker' id='" + this.annotations[i].id.replace(":", "_") + "'></div>";
+    }
+    
+    //On les ajoute.
+    this.$.append(markers);
+    var markerHeight = IriSP.jQuery(".Ldt-Marker").height();
+    IriSP.jQuery(".Ldt-Marker").css("z-align", "150");
+    
+    //Pour toutes les annotations.
+    for(var i = 0 ; i < this.annotations.length ; i++)
+    {
+        //On les place sur la timeline.
+        IriSP.jQuery("#" + this.annotations[i].id.replace(":", "_")).css(
+        {
+            top: timelineMiddleTop + "px",
+            left: Math.floor(+this.scaleIntervals(0, this.source.getDuration().getSeconds(), 0, this.$timeline.width(), this.annotations[i].begin/1000) + this.$timeline.position().left) + "px",
+            "margin-top": (-_this.$timeline.height()/2 - markerHeight/2) - this.top_epsilon + "px"
+        });
+    }
+    
+    //On lance l'événement pour dire à popcorn que les marqueurs sont utilisables.
+    this.player.popcorn.trigger("markersready");
 }
 
 /*
- * Fonction de recherche par gesures.
+ * Fonction de recherche par gestures.
+ * Est appelé dans les fichiers :
+ * mosaic > fonctions onMouseUp, manageControlEvents et onMarkersReady.
+ * curvesDetector > fonction updateDists.
 */
 IriSP.Widgets.Timeline.prototype.searchByGesture = function(typeName)
 {
-	if(typeName != '' || typeName != undefined)
-	{
-		if(_.include(this.gestures, typeName))
-		{
-			this.currentMode = "SEARCH";
-			this.hideMarkersSearch(typeName);
-			this.isCurrentlyInASearchByGesture = true;
-		}
-	}
+    //Si le type existe.
+    if(typeName != '' || typeName != undefined)
+    {
+        if(_.include(this.gestures, typeName))
+        {
+            //On entre en mode recherche et on affiche les marqueurs sélectionnés.
+            this.currentMode = "SEARCH";
+            this.hideMarkersSearch(typeName);
+            this.isCurrentlyInASearchByGesture = true;
+        }
+    }
 }
 
 /*
  * Fonction de suppression de recherche par gesures.
+ * Est appelé dans le fichier :
+ * pointers > checkIfPointerIsOnSearchNotification et removeSearchNotificationIfOnIt.
 */
 IriSP.Widgets.Timeline.prototype.removeSearchByGesture = function()
 {
-	this.hideMarkersSearch();
-	this.isCurrentlyInASearchByGesture = false;
+    this.hideMarkersSearch();
+    this.isCurrentlyInASearchByGesture = false;
+}
+
+/*
+ * Place le curseur sur la timeline en fonction de la touche pressée.
+ * Est appelé dans le fichier :
+*/
+IriSP.Widgets.Timeline.prototype.keyPress = function(e) {
+    var key = this.whichKey(e.which);
+    var time = 0;
+    
+    //Entre 0 et 10, on met à jour la position du curseur dans la video.
+    if(key > -1 && key < 11)
+    {
+        time = this.source.getDuration().getSeconds()/10*key;
+        this.$timeline.slider("value",time);
+        this.player.popcorn.currentTime(time);
+        
+        //On supprime le marqueur précédemment affiché.
+        if(this.previousMarkerIdx > -1)
+        {
+            var previousMarker = IriSP.jQuery("#" + this.annotations[this.previousMarkerIdx].id.replace(":", "_"));
+            this.hideMarkerBig(previousMarker);
+        }
+    }
+    
+    //p ou P pour mettre en pause.
+    if(key == 21)
+    {
+        if(!this.paused)
+        {
+            this.paused = true;
+            this.player.popcorn.pause();
+        }
+        else
+        {
+            this.paused = false;
+            this.player.popcorn.play();
+        }
+    }
 }
 
 /*
- * Place the cursor on the timeline depending on the keytyped.
+ * Donne une clé correspondante à une touche donnée.
+ * Est appelé dans le fichier :
+ * Timeline > fonction keyPress.
+*/
+IriSP.Widgets.Timeline.prototype.whichKey = function(code) {
+    var key;
+    
+    if(code > 47 && code < 58)
+    {
+        return (code - 48);
+    }
+    
+    if(code == 115 || code == 83)
+    {
+        return 11;
+    }
+    
+    //p ou P pour mettre la vidéo en pause.
+    if(code == 112 || code == 80)
+    {
+        return 21;
+    }
+    
+    switch(code)
+    {
+        case 224:
+            key = 0;
+        break;
+        case 38:
+            key = 1;
+        break;
+        case 233:
+            key = 2;
+        break;
+        case 34:
+            key = 3;
+        break;
+        case 39:
+            key = 4;
+        break;
+        case 40:
+            key = 5;
+        break;
+        case 45:
+            key = 6;
+        break;
+        case 232:
+            key = 7;
+        break;
+        case 95:
+            key = 8;
+        break;
+        case 231:
+            key = 9;
+        break;
+        default:
+            key = -1;
+    }
+    
+    return key;
+}
+
+/*
+ * Fonction de sélection de la timeline.
+ * Est appelé dans le fichier :
+ * pointers > fonction pointersTimelineSelection.
 */
-IriSP.Widgets.Timeline.prototype.keyPress = function(e) {
-	var key = this.whichKey(e.which);
-	var time = 0;
-	
-	// console.log($(this));
-	
-	if(key > -1 && key < 11)
-	{
-		time = this.source.getDuration().getSeconds()/10*key;
-		this.$timeline.slider("value",time);
-		this.player.popcorn.currentTime(time);
-		
-		//On supprime le marqueur précédemment affiché si c'est le cas.
-		if(this.previousMarkerIdx > -1)
-		{
-			// console.log("EXT hide idx " + this.previousMarkerIdx);
-			var previousMarker = IriSP.jQuery("#" + this.annotations[this.previousMarkerIdx].id.replace(":", "_"));
-			this.hideMarkerBig(previousMarker);
-			// console.log("EXT hide " + this.previousMarkerIdx);
-		}
-	}
-	
-	if(key == 11)
-	{
-		if(!this.timelineSelected)
-		{
-			this.currentMode = "TIMELINE";
-			this.selectTimeline();
-		}
-		else
-		{
-			this.currentMode = "VIDEO";
-			this.deselectTimeline();
-		}
-	}
-	
-	if(key == 12)
-	{
-		this.hideMarkersSearch();
-	}
-	
-	if(key == 13)
-	{
-		var gesturesStr = '';
-		for(var i = 0 ; i < this.gestures.length ; i++)
-		{
-			gesturesStr += this.gestures[i] + ", ";
-		}
-		gesturesStr = gesturesStr.substr(0, gesturesStr.length - 2);
-		
-		var typeName = prompt("Please enter a type name among (" + gesturesStr + ").", "");
-		
-		if(typeName != '' || typeName != undefined)
-		{
-			if(_.include(this.gestures, typeName))
-			{
-				this.currentMode = "SEARCH";
-				this.hideMarkersSearch(typeName);
-			}
-		}
-	}
-	
-	if(key == 21)
-	{
-		// console.log(this);
-		if(!this.paused)
-		{
-			this.paused = true;
-			this.player.popcorn.pause();
-		}
-		else
-		{
-			this.paused = false;
-			this.player.popcorn.play();
-		}
-	}
+IriSP.Widgets.Timeline.prototype.selectTimeline = function() {
+    //On crée les bordures.
+    this.timelineSelected = true;
+    this.$timelineBorderUp = "<div class='TL_Borders' id='TL_BorderUp'></div>";
+    this.$timelineBorderDown = "<div class='TL_Borders' id='TL_BorderDown'></div>";
+    this.$timelineBorderLeft = "<div class='TL_Borders' id='TL_BorderLeft'></div>";
+    this.$timelineBorderRight = "<div class='TL_Borders' id='TL_BorderRight'></div>";
+    //Les flèches verticales aussi.
+    this.$arrowUp = "<div class='TL_Arrows' id='TL_ArrowUp'></div>";
+    this.$arrowDown = "<div class='TL_Arrows' id='TL_ArrowDown'></div>";
+    //On les ajoute.
+    this.$.append(this.$timelineBorderUp + this.$timelineBorderDown + this.$timelineBorderLeft + this.$timelineBorderRight + this.$arrowUp + this.$arrowDown);
+    //On calcule la position en Y de la timeline.
+    var timelineTop = IriSP.jQuery("#LdtPlayer").position().top + IriSP.jQuery("#LdtPlayer").height();
+    //On met les styles à jour.
+    IriSP.jQuery("#TL_BorderUp").css(
+    {
+        "margin-top": -this.$timeline.height() - this.top_epsilon,
+        left: this.$timeline.position().left,
+        width: this.$timeline.width(),
+        height: this.timelineBorderLength
+    });
+    IriSP.jQuery("#TL_BorderDown").css(
+    {
+        "margin-top": -this.timelineBorderLength - 2 - this.top_epsilon,
+        left: this.$timeline.position().left,
+        width: this.$timeline.width(),
+        height: this.timelineBorderLength
+    });
+    IriSP.jQuery("#TL_BorderLeft").css(
+    {
+        "margin-top": -this.$timeline.height() - this.top_epsilon,
+        left: this.$timeline.position().left,
+        width: this.timelineBorderLength,
+        height: this.$timeline.height()
+    });
+    IriSP.jQuery("#TL_BorderRight").css(
+    {
+        "margin-top": -this.$timeline.height() - this.top_epsilon,
+        left: +this.$timeline.position().left + this.$timeline.width() - this.timelineBorderLength - 2,
+        width: this.timelineBorderLength,
+        height: this.$timeline.height()
+    });
+    
+    IriSP.jQuery("#TL_ArrowUp").css(
+    {
+        "background-image": "url(" + this.imgDir + "arrow_up.png)",
+        "margin-top": -this.$timeline.height() - IriSP.jQuery("#TL_ArrowUp").height() - this.top_epsilon,
+        left: this.$timeline.position().left - IriSP.jQuery("#TL_ArrowUp").width()/2,
+    });
+    IriSP.jQuery("#TL_ArrowDown").css(
+    {
+        "background-image": "url(" + this.imgDir + "arrow_down.png)",
+        "margin-top": -this.timelineBorderLength + this.timelineBorderLength - this.top_epsilon,
+        left: this.$timeline.position().left - IriSP.jQuery("#TL_ArrowUp").width()/2,
+    });
+    
+    IriSP.jQuery(".Ldt-Timeline .ui-slider-range").css("background-image", "url(" + this.imgDir + "past_timeline.png)");
+}
+
+/*
+ * Déselectionne la timeline.
+ * Est appelé dans le fichier :
+ * playerControl > fonction exitTimeline.
+*/
+IriSP.Widgets.Timeline.prototype.deselectTimeline = function() {
+    //On supprime les éléments qui faisaient que la timeline était sélectionnée.
+    this.timelineSelected = false;
+    IriSP.jQuery(".TL_Borders").remove();
+    IriSP.jQuery(".TL_Arrows").remove();
+    IriSP.jQuery(".Ldt-Timeline .ui-slider-range").css("background-image", "url(" + this.imgDir + "selected_timeline.png)");
 }
 
 /*
- * Find the key corresponding to a given code.
+ * Se met à jour durant la lecture d'une video.
+ * Est appelé dans le fichier :
+ * Timeline
 */
-IriSP.Widgets.Timeline.prototype.whichKey = function(code) {
-	var key;
-	
-	console.log(code);
-	
-	if(code > 47 && code < 58)
-	{
-		return (code - 48);
-	}
-	
-	if(code == 115 || code == 83)
-	{
-		return 11;
-	}
-	
-	//m ou M pour quitter une recherche.
-	if(code == 109 || code == 77)
-	{
-		return 12;
-	}
-	
-	//p ou P pour mettre la vidéo en pause.
-	if(code == 112 || code == 80)
-	{
-		return 21;
-	}
-	
-	//n ou N pour une recherche par type.
-	if(code == 110 || code == 78)
-	{
-		return 13;
-	}
-	
-	switch(code)
-	{
-		case 224:
-			key = 0;
-		break;
-		case 38:
-			key = 1;
-		break;
-		case 233:
-			key = 2;
-		break;
-		case 34:
-			key = 3;
-		break;
-		case 39:
-			key = 4;
-		break;
-		case 40:
-			key = 5;
-		break;
-		case 45:
-			key = 6;
-		break;
-		case 232:
-			key = 7;
-		break;
-		case 95:
-			key = 8;
-		break;
-		case 231:
-			key = 9;
-		break;
-		default:
-			key = -1;
-	}
-	
-	return key;
+IriSP.Widgets.Timeline.prototype.onTimeupdate = function() {
+    //On récupère la position du curseur en secondes.
+    var _time = this.player.popcorn.currentTime();
+    //Position des flèches au cas où la timeline serait sélectionnée.
+    var arrowLeft = Math.floor(+this.scaleIntervals(0, this.source.getDuration().getSeconds(), 0, this.$timeline.width(), _time) + this.$timeline.position().left) - IriSP.jQuery("#TL_ArrowUp").width()/2 + "px";
+    //On met à jour la position du slider en ms.
+    this.$timeline.slider("value",_time*1000);
+    //On affiche les flèches si la timeline est sélectionnée.
+    IriSP.jQuery(".TL_Arrows").css("display", "block");
+    IriSP.jQuery("#TL_ArrowUp").css("left", arrowLeft);
+    IriSP.jQuery("#TL_ArrowDown").css("left", arrowLeft);
+    
+    //Si on a une distance de 500 ms à un marqueur, on l'affiche.
+    var nearestMarkerIdx = 0;
+    for(var i = 0 ; i < this.annotations.length ; i++)
+    {
+        //S'il existe des marqueurs dans l'intervalle de temps actuel (ici 500ms).
+        if(Math.abs(_time*1000 - this.annotations[i].begin.milliseconds) <= 250)
+        {
+            //On sélectionne le plus proche marqueur (dans les cas où il en existe plusieurs dans l'intervalle des 1s) ou bien le premier marqueur.
+            if(Math.abs(_time*1000 - this.annotations[i].begin.milliseconds) < Math.abs(_time*1000 - this.annotations[nearestMarkerIdx].begin.milliseconds) || i == nearestMarkerIdx)
+            {
+                //Si le prochain marqueur se situe après le curseur de lecture, on passe donc au marqueur le plus proche.
+                if(_time*1000 < this.annotations[i].begin.milliseconds)
+                {
+                    nearestMarkerIdx = i;
+                    //S'il y a un changement de marqueur (marqueur actuel différent du précédent).
+                    if(nearestMarkerIdx != this.previousMarkerIdx)
+                    {
+                        var currentMarker = IriSP.jQuery("#" + this.annotations[nearestMarkerIdx].id.replace(":", "_"));
+                        //S'il existe un marqueur précédent, on le cache.
+                        if(this.previousMarkerIdx > -1)
+                        {
+                            var previousMarker = IriSP.jQuery("#" + this.annotations[this.previousMarkerIdx].id.replace(":", "_"));
+                            this.hideMarkerBig(previousMarker);
+                        }
+                        
+                        this.showMarkerBig(currentMarker, this.annotations[nearestMarkerIdx].annotationType.contents.title);
+                        //Mise à jour du marqueur précédent s'il y a un changement.
+                        this.previousMarkerIdx = nearestMarkerIdx;
+                    }
+                }
+            }
+            this.currentMarkerIdx = nearestMarkerIdx;
+        }
+    }
 }
 
-IriSP.Widgets.Timeline.prototype.selectTimeline = function() {
-	this.timelineSelected = true;
-	this.$timelineBorderUp = "<div class='TL_Borders' id='TL_BorderUp'></div>";
-	this.$timelineBorderDown = "<div class='TL_Borders' id='TL_BorderDown'></div>";
-	this.$timelineBorderLeft = "<div class='TL_Borders' id='TL_BorderLeft'></div>";
-	this.$timelineBorderRight = "<div class='TL_Borders' id='TL_BorderRight'></div>";
-	
-	this.$arrowUp = "<div class='TL_Arrows' id='TL_ArrowUp'></div>";
-	this.$arrowDown = "<div class='TL_Arrows' id='TL_ArrowDown'></div>";
-	
-	this.$.append(this.$timelineBorderUp + this.$timelineBorderDown + this.$timelineBorderLeft + this.$timelineBorderRight + this.$arrowUp + this.$arrowDown);
-	
-	var timelineTop = IriSP.jQuery("#LdtPlayer").position().top + IriSP.jQuery("#LdtPlayer").height();
-	
-	IriSP.jQuery("#TL_BorderUp").css(
-	{
-		"margin-top": -this.$timeline.height() - this.top_epsilon,
-		left: this.$timeline.position().left,
-		width: this.$timeline.width(),
-		height: this.timelineBorderLength
-	});
-	IriSP.jQuery("#TL_BorderDown").css(
-	{
-		"margin-top": -this.timelineBorderLength - 2 - this.top_epsilon,
-		left: this.$timeline.position().left,
-		width: this.$timeline.width(),
-		height: this.timelineBorderLength
-	});
-	IriSP.jQuery("#TL_BorderLeft").css(
-	{
-		"margin-top": -this.$timeline.height() - this.top_epsilon,
-		left: this.$timeline.position().left,
-		width: this.timelineBorderLength,
-		height: this.$timeline.height()
-	});
-	IriSP.jQuery("#TL_BorderRight").css(
-	{
-		"margin-top": -this.$timeline.height() - this.top_epsilon,
-		left: +this.$timeline.position().left + this.$timeline.width() - this.timelineBorderLength - 2,
-		width: this.timelineBorderLength,
-		height: this.$timeline.height()
-	});
-	
-	IriSP.jQuery("#TL_ArrowUp").css(
-	{
-		"background-image": "url(" + this.imgDir + "arrow_up.png)",
-		"margin-top": -this.$timeline.height() - IriSP.jQuery("#TL_ArrowUp").height() - this.top_epsilon,
-		left: this.$timeline.position().left - IriSP.jQuery("#TL_ArrowUp").width()/2,
-	});
-	IriSP.jQuery("#TL_ArrowDown").css(
-	{
-		"background-image": "url(" + this.imgDir + "arrow_down.png)",
-		"margin-top": -this.timelineBorderLength + this.timelineBorderLength - this.top_epsilon,
-		left: this.$timeline.position().left - IriSP.jQuery("#TL_ArrowUp").width()/2,
-	});
-	
-	IriSP.jQuery(".Ldt-Timeline .ui-slider-range").css("background-image", "url(" + this.imgDir + "past_timeline.png)");
-}
-
-IriSP.Widgets.Timeline.prototype.deselectTimeline = function() {
-	this.timelineSelected = false;
-	IriSP.jQuery(".TL_Borders").remove();
-	IriSP.jQuery(".TL_Arrows").remove();
-	IriSP.jQuery(".Ldt-Timeline .ui-slider-range").css("background-image", "url(" + this.imgDir + "selected_timeline.png)");
+/*
+ * Met à jour l'affichage régulièrement.
+ * Est appelé dans le fichier :
+ * Timeline
+*/
+IriSP.Widgets.Timeline.prototype.timeDisplayUpdater = function() {
+    //On récupère la position du curseur en secondes.
+    var _time = this.player.popcorn.currentTime();
+    //Position des flèches au cas où la timeline serait sélectionnée.
+    var arrowLeft = Math.floor(+this.scaleIntervals(0, this.source.getDuration().getSeconds(), 0, this.$timeline.width(), _time) + this.$timeline.position().left) -
+    this.$timeline.slider("value",_time*1000);
+    //On affiche les flèches si la timeline est sélectionnée.
+    IriSP.jQuery(".TL_Arrows").css("display", "block");
+    IriSP.jQuery("#TL_ArrowUp").css("left", arrowLeft);
+    IriSP.jQuery("#TL_ArrowDown").css("left", arrowLeft);
 }
 
-IriSP.Widgets.Timeline.prototype.onTimeupdate = function() {
-    var _time = this.player.popcorn.currentTime();
-	var arrowLeft = Math.floor(+this.scaleIntervals(0, this.source.getDuration().getSeconds(), 0, this.$timeline.width(), _time) + this.$timeline.position().left) - IriSP.jQuery("#TL_ArrowUp").width()/2 + "px";
-	
-    this.$timeline.slider("value",_time*1000);
-	IriSP.jQuery(".TL_Arrows").css("display", "block");
-	IriSP.jQuery("#TL_ArrowUp").css("left", arrowLeft);
-	IriSP.jQuery("#TL_ArrowDown").css("left", arrowLeft);
-	// this.player.popcorn.trigger("IriSP.Arrow.updatePosition",{widget: this.type, time: 1000 * _time});
-	//Si on a une distance de 500 ms à un marqueur, on l'affiche.
-	var nearestMarkerIdx = 0;
-	for(var i = 0 ; i < this.annotations.length ; i++)
-	{
-		//S'il existe des marqueurs dans l'intervalle de temps actuel (ici 500ms).
-		if(Math.abs(_time*1000 - this.annotations[i].begin.milliseconds) <= 250)
-		{
-			// console.log("1) i = " + i + " " + Math.abs(_time*1000 - annotations[i].begin.milliseconds));
-			
-			//On sélectionne le plus proche marqueur (dans les cas où il en existe plusieurs dans l'intervalle des 1s) ou bien le premier marqueur.
-			if(Math.abs(_time*1000 - this.annotations[i].begin.milliseconds) < Math.abs(_time*1000 - this.annotations[nearestMarkerIdx].begin.milliseconds) || i == nearestMarkerIdx)
-			{
-				// console.log("2) " + Math.abs(_time*1000 - annotations[i].begin.milliseconds) + " < " + Math.abs(_time*1000 - annotations[nearestMarkerIdx].begin.milliseconds));
-				//Si le prochain marqueur se situe après le curseur de lecture, on passe donc au marqueur le plus proche.
-				if(_time*1000 < this.annotations[i].begin.milliseconds)
-				{
-					// console.log("3) " + _time*1000 + " < " + annotations[i].begin.milliseconds);
-					// console.log("4) " + "nearest = " + i);
-					nearestMarkerIdx = i;
-					// console.log("5a0) before");
-					//S'il y a un changement de marqueur (marqueur actuel différent du précédent).
-					if(nearestMarkerIdx != this.previousMarkerIdx)
-					{
-						var currentMarker = IriSP.jQuery("#" + this.annotations[nearestMarkerIdx].id.replace(":", "_"));
-						//S'il existe un marqueur précédent, on le cache.
-						if(this.previousMarkerIdx > -1)
-						{
-							// console.log("hide idx " + this.previousMarkerIdx);
-							var previousMarker = IriSP.jQuery("#" + this.annotations[this.previousMarkerIdx].id.replace(":", "_"));
-							this.hideMarkerBig(previousMarker);
-							// console.log("5a) hide " + this.previousMarkerIdx);
-						}
-						
-						// console.log("5b) show " + nearestMarkerIdx);
-						this.showMarkerBig(currentMarker, this.annotations[nearestMarkerIdx].annotationType.contents.title);
-						//Mise à jour du marqueur précédent s'il y a un changement.
-						this.previousMarkerIdx = nearestMarkerIdx;
-						// console.log("MAJ : " + this.previousMarkerIdx);
-					}
-				}
-			}
-			// nearestMarker = (Math.abs(_time*1000 - annotations[i].begin.milliseconds) < Math.abs(_time*1000 - annotations[nearestMarker].begin.milliseconds) && annotations[i].begin.milliseconds >= annotations[nearestMarker].begin.milliseconds && annotations[i].begin.milliseconds >= _time*1000) ? i : nearestMarker;
-			this.currentMarkerIdx = nearestMarkerIdx;
-			// this.showMarkerBig(IriSP.jQuery("#" + annotations[i].id.replace(":", "_")), annotations[i].annotationType.contents.title);
-		}
-	}
-}
-
-IriSP.Widgets.Timeline.prototype.timeDisplayUpdater = function() {
-    var _time = this.player.popcorn.currentTime();
-	var arrowLeft = Math.floor(+this.scaleIntervals(0, this.source.getDuration().getSeconds(), 0, this.$timeline.width(), _time) + this.$timeline.position().left) -
-    this.$timeline.slider("value",_time*1000);
-	
-	IriSP.jQuery(".TL_Arrows").css("display", "block");
-	IriSP.jQuery("#TL_ArrowUp").css("left", arrowLeft);
-	IriSP.jQuery("#TL_ArrowDown").css("left", arrowLeft);
-    // this.player.popcorn.trigger("IriSP.Arrow.updatePosition",{widget: this.type, time: 1000 * _time});
-}
-
+/*
+ * Fonction appelée quand la souris est au dessus de la timeline.
+*/
 IriSP.Widgets.Timeline.prototype.onMouseover = function() {}
 
+/*
+ * Fonction appelée quand la souris est hors de la timeline.
+*/
 IriSP.Widgets.Timeline.prototype.onMouseout = function() {}
 
+/*
+ * Fonction appelée pour modifier la hauteur de la timeline.
+*/
 IriSP.Widgets.Timeline.prototype.animateToHeight = function(_height) {}
 
+/*
+ * Calcule le css de la timeline.
+ * Est appelé dans le fichier :
+ * Timeline > fonction draw.
+*/
 IriSP.Widgets.Timeline.prototype.calculateTimelineCss = function(_size) {
-	var middleWidth = this.player.config.gui.width;
+    //Longueur du player.
+    var middleWidth = this.player.config.gui.width;
+    //On met à jour la marge, les coordonnées et positions de la timeline.
     return {
-		position: "absolute",
-		top: "0px",
-		left: "0px",
-		width: middleWidth + "px",
+        position: "absolute",
+        top: "0px",
+        left: "0px",
+        width: middleWidth + "px",
         height: _size + "px",
         "margin-top": (-this.minimized_height - this.top_epsilon) + "px",
-		"z-align": "50"
+        "z-align": "50"
     };
 }
 
+/*
+ * Calcule le css de la barre grise de milieu de la timeline.
+ * Est appelé dans le fichier :
+ * Timeline > fonction draw.
+*/
 IriSP.Widgets.Timeline.prototype.calculateTimelineMiddleCss = function(_size, _middleSize) {
-	var middleWidth = this.player.config.gui.width;
+    //Longueur du player.
+    var middleWidth = this.player.config.gui.width;
+    //On met à jour la marge, les coordonnées et positions de la barre grise de milieu de la timeline.
     return {
-		position: "absolute",
-		top: "0px",
-		left: "0px",
-		width: middleWidth + "px",
+        position: "absolute",
+        top: "0px",
+        left: "0px",
+        width: middleWidth + "px",
         height: _middleSize + "px",
         "margin-top": (-this.minimized_height/2 - _middleSize/2 - this.top_epsilon) + "px",
-		"z-align": "100"
+        "z-align": "100"
     };
 }
 
+/*
+ * Calcule le css de la portion de la timeline qui a déjà été lue.
+ * Est appelé dans le fichier :
+ * Timeline > fonction draw.
+*/
 IriSP.Widgets.Timeline.prototype.calculateHandleCss = function(_size) {
     return {
-		position: "absolute",
-		top: "0px",
-		left: "0px",
+        position: "absolute",
+        top: "0px",
+        left: "0px",
         height: (2 + _size) + "px",
         width: (2 + _size) + "px",
         "margin-left": -Math.ceil(2 + _size / 2) + "px",
-		"z-align": "60"
+        "z-align": "60"
     }
 }
 
+/*
+ * Affiche les marqueurs lorsqu'ils sont affichés au passage du curseur.
+ * Est appelé dans le fichier :
+ * Timeline > fonction onTimeupdate.
+*/
 IriSP.Widgets.Timeline.prototype.showMarkerBig = function(marker, type) {
-	// console.log("avant");
-	if(this.markerBigShown)
-	{
-		return;
-	}
-	// console.log("apres");
-	
-	clearTimeout(this.hideTimeout);
-	
-	var _this = this;
-	
-	var markerTop, markerLeft;
-	
-	if(marker.position() == null)
-	{
-		markerTop = 0;
-		markerLeft = 0;
-	}
-	else
-	{
-		markerTop = marker.position().top;
-		markerLeft = marker.position().left;
-	}
-	
-	var markerWidth = marker.width(), markerHeight = marker.height();
-	
-	this.markerBigShown = true;
-	var markerBig = "<div class='TL_MarkersBig' id='MB_Text'>" + this.gesturesText[IriSP.jQuery.inArray(type, this.gestures)] + "<div class='TL_MarkersBig' id='MB_Spike'></div></div><div class='TL_MarkersBig' id='MB_Pic'></div>";
-	this.$.append(markerBig);
-	
-	var markerBigText = IriSP.jQuery("#MB_Text");
-	var markerBigSpike = IriSP.jQuery("#MB_Spike");
-	var markerBigPic = IriSP.jQuery("#MB_Pic");
-	
-	var markerBigTextWidth = markerBigText.outerWidth(), markerBigTextHeight = markerBigText.outerHeight();
-	var markerBigSpikeWidth = markerBigSpike.width(), markerBigSpikeHeight = markerBigSpike.height();
-	var markerBigPicWidth = markerBigPic.width(), markerBigPicHeight = markerBigPic.height();
-	var markerBigPicTop = +parseFloat(marker.css("margin-top")) + markerHeight, markerBigPicLeft = (markerLeft - markerBigPicWidth/2 + markerWidth/2);
-	var markerBigTextTop = (parseFloat(marker.css("margin-top")) - markerBigTextHeight - markerBigSpikeHeight), markerBigTextLeft = (markerLeft - (markerBigTextWidth - markerBigSpikeWidth)/2);
-	var markerBigSpikeLeft = ((markerBigTextWidth - markerBigSpikeWidth)/2);
-	
-	marker.css("background-image", "url(" + this.imgDir + "selected_marker.png)");
-	IriSP.jQuery("#MB_Text").css(
-	{
-		top: markerBigTextTop,
-		left: markerBigTextLeft
-	});
-	IriSP.jQuery("#MB_Spike").css(
-	{
-		left: markerBigSpikeLeft
-	});
-	IriSP.jQuery("#MB_Pic").css(
-	{
-		"background-image": "url(" + this.markersDir + type + ".png)",
-		top: markerBigPicTop,
-		left: markerBigPicLeft,
-		"z-index": "400"
-	});
-	
-	IriSP.jQuery(".TL_MarkersBig").fadeTo(this.markerShowTime, "1");
-	
-	//On rajoute un timeout pour supprimer le marqueur après un certain temps.
-	this.hideTimeout = setTimeout(function()
-	{
-		_this.hideMarkerBig(marker);
-	}, this.markerLastTime);
+    //Si le marqueur est déjà affiché, on part.
+    if(this.markerBigShown)
+    {
+        return;
+    }
+    
+    //On annule le masquage du pointeur.
+    clearTimeout(this.hideTimeout);
+    
+    var _this = this;
+    //On met à jour la position du marqueur.
+    var markerTop, markerLeft;
+    
+    if(marker.position() == null)
+    {
+        markerTop = 0;
+        markerLeft = 0;
+    }
+    else
+    {
+        markerTop = marker.position().top;
+        markerLeft = marker.position().left;
+    }
+    //Ses dimensions aussi.
+    var markerWidth = marker.width(), markerHeight = marker.height();
+    //On spécifie qu'il est affiché.
+    this.markerBigShown = true;
+    //On le crée.
+    var markerBig = "<div class='TL_MarkersBig' id='MB_Text'>" + this.gesturesText[IriSP.jQuery.inArray(type, this.gestures)] + "<div class='TL_MarkersBig' id='MB_Spike'></div></div><div class='TL_MarkersBig' id='MB_Pic'></div>";
+    //On l'ajoute.
+    this.$.append(markerBig);
+    //On forme ses éléments.
+    var markerBigText = IriSP.jQuery("#MB_Text");
+    var markerBigSpike = IriSP.jQuery("#MB_Spike");
+    var markerBigPic = IriSP.jQuery("#MB_Pic");
+    //On spécifie leurs coordonnées et dimensions.
+    var markerBigTextWidth = markerBigText.outerWidth(), markerBigTextHeight = markerBigText.outerHeight();
+    var markerBigSpikeWidth = markerBigSpike.width(), markerBigSpikeHeight = markerBigSpike.height();
+    var markerBigPicWidth = markerBigPic.width(), markerBigPicHeight = markerBigPic.height();
+    var markerBigPicTop = +parseFloat(marker.css("margin-top")) + markerHeight, markerBigPicLeft = (markerLeft - markerBigPicWidth/2 + markerWidth/2);
+    var markerBigTextTop = (parseFloat(marker.css("margin-top")) - markerBigTextHeight - markerBigSpikeHeight), markerBigTextLeft = (markerLeft - (markerBigTextWidth - markerBigSpikeWidth)/2);
+    var markerBigSpikeLeft = ((markerBigTextWidth - markerBigSpikeWidth)/2);
+    //On va chercher les images correspondantes.
+    marker.css("background-image", "url(" + this.imgDir + "selected_marker.png)");
+    //On met à jour leur apparence.
+    IriSP.jQuery("#MB_Text").css(
+    {
+        top: markerBigTextTop,
+        left: markerBigTextLeft
+    });
+    IriSP.jQuery("#MB_Spike").css(
+    {
+        left: markerBigSpikeLeft
+    });
+    IriSP.jQuery("#MB_Pic").css(
+    {
+        "background-image": "url(" + this.markersDir + type + ".png)",
+        top: markerBigPicTop,
+        left: markerBigPicLeft,
+        "z-index": "400"
+    });
+    //On l'affiche.
+    IriSP.jQuery(".TL_MarkersBig").fadeTo(this.markerShowTime, "1");
+    
+    //On rajoute un timeout pour supprimer le marqueur après un certain temps.
+    this.hideTimeout = setTimeout(function()
+    {
+        _this.hideMarkerBig(marker);
+    }, this.markerLastTime);
 }
 
+/*
+ * Cache un marqueur.
+ * Est appelé dans le fichier :
+ * Timeline > fonctions draw, keyPress, onTimeupdate et showMarkerBig.
+*/
 IriSP.Widgets.Timeline.prototype.hideMarkerBig = function(marker) {
-	if(!this.markerBigShown)
-	{
-		return;
-	}
-	
-	this.currentMarker = -1;
-	this.markerBigShown = false;
-	marker.css("background-image", "url(" + this.imgDir + "marker.png)");
-	
-	IriSP.jQuery(".TL_MarkersBig").fadeOut(this.markerShowTime).remove();
+    //S'il n'est pas affiché, on part.
+    if(!this.markerBigShown)
+    {
+        return;
+    }
+    
+    //On lui remet son apparence initiale.
+    this.currentMarker = -1;
+    this.markerBigShown = false;
+    marker.css("background-image", "url(" + this.imgDir + "marker.png)");
+    //On efface ce qui était affiché du marqueur.
+    IriSP.jQuery(".TL_MarkersBig").fadeOut(this.markerShowTime).remove();
 }
 
 /*
  * Affiche le bas des marqueurs correspondants à la recherche.
+ * Est appelé dans le fichier :
+ * Timeline > fonction hideMarkersSearch.
 */
 IriSP.Widgets.Timeline.prototype.showMarkersSearchByType = function(type) {
-	//Si on est en mode SEARCH.
-	if(this.currentMode != "SEARCH")
-	{
-		return;
-	}
-	
-	var _this = this;
-	
-	//On récupère les annotations.
-	var markersSearch = "", markersPicSearch = "";
-	//Pour chaque annotation, on ajoute un double.
-	for(var i = 0 ; i < this.annotations.length ; i++)
-	{
-		//Si elle correspond à la recherche.
-		if(this.annotations[i].annotationType.contents.title == type)
-		{
-			//On récupère le marqueur associé à l'annotation.
-			var markerId = this.annotations[i].id.replace(":", "_");
-			
-			markersSearch += "<div class='search_Marker' id='search_Marker_" + markerId + "'></div>";
-			markersPicSearch += "<div class='search_MBPic' id='search_Pic_" + markerId + "'></div>";
-		}
-	}
-	
-	this.$.append(markersSearch + markersPicSearch);
-	
-	//On place chaque double.
-	for(var i = 0 ; i < this.annotations.length ; i++)
-	{
-		//Si elle correspond à la recherche.
-		if(this.annotations[i].annotationType.contents.title == type)
-		{
-			var markerId = this.annotations[i].id.replace(":", "_"), marker = IriSP.jQuery("#" + markerId);
-			var markerTop = marker.position().top, markerLeft = marker.position().left, markerWidth = marker.width(), markerHeight = marker.height();
-			var markerBigPicWidth = parseFloat(IriSP.jQuery(".search_MBPic").css("width")), markerBigPicHeight = parseFloat(IriSP.jQuery(".search_MBPic").css("height")), markerBigPicTop = +parseFloat(marker.css("margin-top")) + markerHeight, markerBigPicLeft = (markerLeft - markerBigPicWidth/2 + markerWidth/2);
-
-			// console.log(markerLeft + " - " + IriSP.jQuery(".search_MBPic").css("width") + " " + markerBigPicWidth + "/2 " + markerWidth + "/2");
-			
-			IriSP.jQuery("#search_Pic_" + markerId).css(
-			{
-				position: "absolute",
-				"background-image": "url(" + this.markersDir + type + ".png)",
-				top: markerBigPicTop,
-				left: markerBigPicLeft,
-				"z-index": "300"
-			}).fadeTo(this.markerShowTime, "1");
-			
-			IriSP.jQuery("#search_Marker_" + markerId).css(
-			{
-				position: "absolute",
-				top: _this.$timelineMiddle.position().top - _this.top_epsilon,
-				"margin-top": (-_this.$timeline.height()/2 - markerHeight/2),
-				"background-image": "url(" + this.imgDir + "selected_marker.png)",
-				//top: markerTop,
-				left: markerLeft,
-				"z-index": "300"
-			}).fadeTo(this.markerShowTime, "1");
-		}
-	}
+    //Si on est en mode SEARCH.
+    if(this.currentMode != "SEARCH")
+    {
+        return;
+    }
+    
+    var _this = this;
+    
+    //On récupère les annotations.
+    var markersSearch = "", markersPicSearch = "";
+    //Pour chaque annotation, on ajoute un double.
+    for(var i = 0 ; i < this.annotations.length ; i++)
+    {
+        //Si elle correspond à la recherche.
+        if(this.annotations[i].annotationType.contents.title == type)
+        {
+            //On récupère le marqueur associé à l'annotation.
+            var markerId = this.annotations[i].id.replace(":", "_");
+            
+            markersSearch += "<div class='search_Marker' id='search_Marker_" + markerId + "'></div>";
+            markersPicSearch += "<div class='search_MBPic' id='search_Pic_" + markerId + "'></div>";
+        }
+    }
+    
+    this.$.append(markersSearch + markersPicSearch);
+    
+    //On place chaque double.
+    for(var i = 0 ; i < this.annotations.length ; i++)
+    {
+        //Si elle correspond à la recherche.
+        if(this.annotations[i].annotationType.contents.title == type)
+        {
+            //On calcule les coordonnées et dimensions du marqueur.
+            var markerId = this.annotations[i].id.replace(":", "_"), marker = IriSP.jQuery("#" + markerId);
+            var markerTop = marker.position().top, markerLeft = marker.position().left, markerWidth = marker.width(), markerHeight = marker.height();
+            var markerBigPicWidth = parseFloat(IriSP.jQuery(".search_MBPic").css("width")), markerBigPicHeight = parseFloat(IriSP.jQuery(".search_MBPic").css("height")), markerBigPicTop = +parseFloat(marker.css("margin-top")) + markerHeight, markerBigPicLeft = (markerLeft - markerBigPicWidth/2 + markerWidth/2);
+            //On calcule son apparence et on le fait apparaître.
+            IriSP.jQuery("#search_Pic_" + markerId).css(
+            {
+                position: "absolute",
+                "background-image": "url(" + this.markersDir + type + ".png)",
+                top: markerBigPicTop,
+                left: markerBigPicLeft,
+                "z-index": "300"
+            }).fadeTo(this.markerShowTime, "1");
+            
+            IriSP.jQuery("#search_Marker_" + markerId).css(
+            {
+                position: "absolute",
+                top: _this.$timelineMiddle.position().top - _this.top_epsilon,
+                "margin-top": (-_this.$timeline.height()/2 - markerHeight/2),
+                "background-image": "url(" + this.imgDir + "selected_marker.png)",
+                left: markerLeft,
+                "z-index": "300"
+            }).fadeTo(this.markerShowTime, "1");
+        }
+    }
 }
 
 /*
  * Enlever une recherche faite précédemment.
+ * Est appelé dans le fichier :
+ * Timeline > fonctions searchByGesture et removeSearchByGesture.
 */
 IriSP.Widgets.Timeline.prototype.hideMarkersSearch = function(type) {
-	//Si on est en mode SEARCH.
-	if(this.currentMode != "SEARCH")
-	{
-		return;
-	}
-	
-	// console.log('(0)');
-	
-	var _this = this;
-	
-	IriSP.jQuery(".search_MBPic").fadeOut(this.markerShowTime, function()
-	{
-		IriSP.jQuery("div").remove(".search_MBPic");
-	});
-	IriSP.jQuery(".search_Marker").fadeOut(this.markerShowTime, function()
-	{
-		IriSP.jQuery("div").remove(".search_Marker");
-		
-		if(type == undefined)
-		{
-			_this.currentMode = "VIDEO";
-		}
-		else
-		{
-			// console.log('(1)');
-			// console.log(_this.currentMode);
-			_this.showMarkersSearchByType(type);
-			return;
-		}
-	});
-	
-	if(IriSP.jQuery(".search_Marker").length == 0 && type != undefined)
-	{
-		// console.log('(2)');
-		this.showMarkersSearchByType(type);
-		
-		if(!_.include(this.gestures, type))
-		{
-			// this.notifySearch1Gesture(type, "none");
-		}
-		else
-		{
-			// _this.notifySearch1Gesture(type, "valid");
-		}
-		// console.log(this.currentMode);
-	}
+    //Si on est en mode SEARCH.
+    if(this.currentMode != "SEARCH")
+    {
+        return;
+    }
+    
+    var _this = this;
+    
+    //On efface tous les marqueurs affichés.
+    IriSP.jQuery(".search_MBPic").fadeOut(this.markerShowTime, function()
+    {
+        IriSP.jQuery("div").remove(".search_MBPic");
+    });
+    IriSP.jQuery(".search_Marker").fadeOut(this.markerShowTime, function()
+    {
+        IriSP.jQuery("div").remove(".search_Marker");
+        
+        //Si le type est définit, c'est qu'on souhaite remplacer cette recherche par une autre.
+        if(type == undefined)
+        {
+            _this.currentMode = "VIDEO";
+        }
+        else
+        {
+            _this.showMarkersSearchByType(type);
+            return;
+        }
+    });
+    
+    //Si à la base il n'y avait pas de marqueurs affichés, on crée une nouvelle recherche si le type est définit.
+    if(IriSP.jQuery(".search_Marker").length == 0 && type != undefined)
+    {
+        this.showMarkersSearchByType(type);
+    }
 }
 
+/*
+ * Libère le player.
+ * Est appelé dans les fichiers :
+ * neighbours > fonction moveToNeighbour.
+ * zoomInteractions > fonction unzoom.
+*/
 IriSP.Widgets.Timeline.prototype.freePlayer = function()
 {
-	IriSP.jQuery('body').unbind('keypress');
-	IriSP.jQuery('.notifications').remove();
+    IriSP.jQuery('body').unbind('keypress');
+    IriSP.jQuery('.notifications').remove();
 }
 
 /*
  * Va au marqueur suivant/précédant lors d'un swipe right/left dans une lecture simple.
  * Prend comme argument le fait qu'il s'agisse d'un swipe left ou non (en prenant en condition toujours vraie 
  * que la fonction est appelée si et seulement si il y a swipe et que l'utilisateur ne tente pas d'aller vers un voisin.
+ * Est appelé dans le fichier :
+ * mosaic > fonction manageControlEvents.
 */
 IriSP.Widgets.Timeline.prototype.switchToMarker = function(isSwipeLeft, searchedGesture)
 {
-	console.log((isSwipeLeft == true) ? 'SWIPE LEFT' : 'SWIPE RIGHT');
-	
-	//On prend le temps actuel du curseur en ms.
-	var currentCursorPosition = this.player.popcorn.currentTime() * 1000;
-	//Position visée.
-	var targetCursorPosition = currentCursorPosition;
-	//Distance minimum de l'annotation par rapport au curseur et son index, ainsi que l'index - 1 pour le cas du swipe right.
-	var minDistance = this.source.getDuration().milliseconds, minIdx = 0, mindIdx_1 = 0;
+    console.log((isSwipeLeft == true) ? 'SWIPE LEFT' : 'SWIPE RIGHT');
+    
+    //On prend le temps actuel du curseur en ms.
+    var currentCursorPosition = this.player.popcorn.currentTime() * 1000;
+    //Position visée.
+    var targetCursorPosition = currentCursorPosition;
+    //Distance minimum de l'annotation par rapport au curseur et son index, ainsi que l'index - 1 pour le cas du swipe right.
+    var minDistance = this.source.getDuration().milliseconds, minIdx = 0, mindIdx_1 = 0;
 	
-	//Si il y a au moins 1 annotation.
-	if(this.annotations && this.annotations.length > 0)
-	{
-		if(isSwipeLeft)
-		{
-			//Pour toutes les annotations, on prend celle qui est la plus proche et supérieure à la position.
-			for(var i = 0 ; i < this.annotations.length ; i++)
-			{
-				// console.log('curr : ' + currentCursorPosition + ' ann : ' + this.annotations[i].begin);
-				if(currentCursorPosition < this.annotations[i].begin && minDistance > Math.abs(currentCursorPosition - this.annotations[i].begin))
-				{
-					if(searchedGesture != '')
-					{
-						if(this.annotations[i].annotationType.contents.title != searchedGesture)
-						{
-							continue;
-						}
-					}
-					
-					minDistance = (currentCursorPosition - this.annotations[i].begin);
-					minIdx = i;
-				}
-			}
-		}
-		else
-		{
-			//Pour toutes les annotations, on prend celle qui est la plus proche et inférieure à la position.
-			for(var i = 0 ; i < this.annotations.length ; i++)
-			{
-				if(currentCursorPosition > this.annotations[i].begin && minDistance > Math.abs(currentCursorPosition - this.annotations[i].begin))
-				{
-					if(searchedGesture != '')
-					{
-						if(this.annotations[i].annotationType.contents.title != searchedGesture)
-						{
-							continue;
-						}
-					}
-					
-					minDistance = (currentCursorPosition - this.annotations[i].begin);
-					minIdx = i;
-				}
-			}
-		}
-		
-		targetCursorPosition = this.annotations[minIdx].begin;
-		
-		if(this.annotations[minIdx].begin > 1000)
-		{
-			targetCursorPosition -= 1000;
-		}
-	}
+	//Condition de sélection du marqueur selon le type de swipe.
+	var swipeCondition = (isSwipeLeft ? (currentCursorPosition < this.annotations[i].begin && minDistance > Math.abs(currentCursorPosition - this.annotations[i].begin)) : (currentCursorPosition > this.annotations[i].begin && minDistance > Math.abs(currentCursorPosition - this.annotations[i].begin)));
 	
-	this.player.popcorn.currentTime(targetCursorPosition / 1000);
-}
-
-/*
- * Indique s'il y a des marqueurs devant le curseur (pour une recherche)
-*/
-IriSP.Widgets.Timeline.prototype.isAMarkerAhead = function(searchedGesture)
-{
-	if(searchedGesture == '')
-	{
-		return true;
-	}
-	
-	//On prend le temps actuel du curseur en ms.
-	var currentCursorPosition = this.player.popcorn.currentTime() * 1000;
-	//Position visée.
-	var targetCursorPosition = currentCursorPosition;
-	//Distance minimum de l'annotation par rapport au curseur et son index, ainsi que l'index - 1 pour le cas du swipe right.
-	var minDistance = this.source.getDuration().milliseconds, minIdx = 0, mindIdx_1 = 0;
-	
-	//Si il y a au moins 1 annotation.
-	if(this.annotations && this.annotations.length > 0)
-	{
+    //Si il y a au moins 1 annotation.
+    if(this.annotations && this.annotations.length > 0)
+    {
 		//Pour toutes les annotations, on prend celle qui est la plus proche et supérieure à la position.
 		for(var i = 0 ; i < this.annotations.length ; i++)
 		{
-			// console.log('curr : ' + currentCursorPosition + ' ann : ' + this.annotations[i].begin);
-			if(this.annotations[i].annotationType.contents.title == searchedGesture && currentCursorPosition < this.annotations[i].begin)
+			if(swipeCondition)
 			{
-				return true;
-			}
-		}
-	}
-		
-		return false;
-}
-
-/*
- * Indique, après un swipe, si on est au dernier marqueur d'un type recherché dans la vidéo.
-*/
-IriSP.Widgets.Timeline.prototype.switchToMarker2 = function(isSwipeLeft, searchedGesture)
-{
-	/*if(isSwipeLeft)
-	{
-		//Pour toutes les annotations, on prend celle qui est la plus proche et supérieure à la position.
-		for(var i = 0 ; i < this.annotations.length ; i++)
-		{
-			// console.log('curr : ' + currentCursorPosition + ' ann : ' + this.annotations[i].begin);
-			if(currentCursorPosition < this.annotations[i].begin && minDistance > Math.abs(currentCursorPosition - this.annotations[i].begin))
-			{
+				//Si on recherche une gesture.
 				if(searchedGesture != '')
 				{
+					//Si l'annotation actuelle ne correspond pas à la gesture recherchée, on passe.
 					if(this.annotations[i].annotationType.contents.title != searchedGesture)
 					{
 						continue;
 					}
 				}
 				
+				//On calcule la plus petite distance entre le marqueur marqueur actuel et les autres.
 				minDistance = (currentCursorPosition - this.annotations[i].begin);
 				minIdx = i;
 			}
 		}
-	}
-	else
-	{
-		//Pour toutes les annotations, on prend celle qui est la plus proche et inférieure à la position.
-		for(var i = 0 ; i < this.annotations.length ; i++)
-		{
-			if(currentCursorPosition > this.annotations[i].begin && minDistance > Math.abs(currentCursorPosition - this.annotations[i].begin))
-			{
-				if(searchedGesture != '')
-				{
-					if(this.annotations[i].annotationType.contents.title != searchedGesture)
-					{
-						continue;
-					}
-				}
-				
-				minDistance = (currentCursorPosition - this.annotations[i].begin);
-				minIdx = i;
-			}
-		}
-	}*/
+        
+        //On obtient la position du plus proche marqueur.
+        targetCursorPosition = this.annotations[minIdx].begin;
+        
+        //Si le marqueur est situé minimum à 1s du début de la video, on place la position cible à 1s avant celle du marqueur recherché.
+        if(this.annotations[minIdx].begin > 1000)
+        {
+            targetCursorPosition -= 1000;
+        }
+    }
+    
+    //On place le marqueur au niveau de la position cible.
+    this.player.popcorn.currentTime(targetCursorPosition / 1000);
+}
+
+/*
+ * Indique s'il y a des marqueurs devant le curseur (pour une recherche).
+ * Est appelé dans le fichier :
+ * mosaic > fonction manageControlEvents.
+*/
+IriSP.Widgets.Timeline.prototype.isAMarkerAhead = function(searchedGesture)
+{
+    if(searchedGesture == '')
+    {
+        return true;
+    }
+    
+    //On prend le temps actuel du curseur en ms.
+    var currentCursorPosition = this.player.popcorn.currentTime() * 1000;
+    //Position visée.
+    var targetCursorPosition = currentCursorPosition;
+    //Distance minimum de l'annotation par rapport au curseur et son index, ainsi que l'index - 1 pour le cas du swipe right.
+    var minDistance = this.source.getDuration().milliseconds, minIdx = 0, mindIdx_1 = 0;
+    
+    //Si il y a au moins 1 annotation.
+    if(this.annotations && this.annotations.length > 0)
+    {
+        //Pour toutes les annotations, on prend celle qui est la plus proche et supérieure à la position.
+        for(var i = 0 ; i < this.annotations.length ; i++)
+        {
+            if(this.annotations[i].annotationType.contents.title == searchedGesture && currentCursorPosition < this.annotations[i].begin)
+            {
+                return true;
+            }
+        }
+    }
+    
+    //Si elle n'a pas été trouvée on renvoie faux.
+    return false;
 }
 
 /*
  * Quand on entre dans la vidéo après un filtrage, on va au premier marqueur correspondant à la recherche (à l'exception d'une recherche infructueuse).
+ * Est appelé dans les fichiers :
+ * mosaic > fonctions onMouseUp et onMarkersReady.
+ * curvesDetector > fonction updateDists.
 */
 IriSP.Widgets.Timeline.prototype.goToFirstSearchedMarker = function(gesture)
 {
-	if(_.include(this.gestures, gesture))
-	{
-		if(this.annotations && this.annotations.length > 0)
-		{
-			var minIdx = 0, minPosition = this.source.getDuration().milliseconds, targetCursorPosition = 0;
-			
-			//On parcourt les annotations, pour chaque correspondant à la gesture recherchée, on trouve celle qui se trouve à la position minimum.
-			for(var i = 0 ; i < this.annotations.length ; i++)
-			{
-				//Si le marker n'est pas du type recherché, on passe.
-				if(this.annotations[i].annotationType.contents.title != gesture)
-				{
-					continue;
-				}
-				else if(minPosition > this.annotations[i].begin)
-				{
-					minPosition = this.annotations[i].begin;
-					minIdx = i;
-				}
-			}
-			
-			targetCursorPosition = this.annotations[minIdx].begin;
-			
-			console.log('pos : ' + targetCursorPosition);
-			
-			if(this.annotations[minIdx].begin > 1000)
-			{
-				targetCursorPosition -= 1000;
-			}
-			
-			this.player.popcorn.currentTime(targetCursorPosition / 1000);
-		}
-	}
+    if(_.include(this.gestures, gesture))
+    {
+        if(this.annotations && this.annotations.length > 0)
+        {
+            var minIdx = 0, minPosition = this.source.getDuration().milliseconds, targetCursorPosition = 0;
+            
+            //On parcourt les annotations, pour chaque correspondant à la gesture recherchée, on trouve celle qui se trouve à la position minimum.
+            for(var i = 0 ; i < this.annotations.length ; i++)
+            {
+                //Si le marker n'est pas du type recherché, on passe.
+                if(this.annotations[i].annotationType.contents.title != gesture)
+                {
+                    continue;
+                }
+                else if(minPosition > this.annotations[i].begin)
+                {
+                    minPosition = this.annotations[i].begin;
+                    minIdx = i;
+                }
+            }
+            
+            targetCursorPosition = this.annotations[minIdx].begin;
+            
+            //Si le marqueur est situé minimum à 1s du début de la video, on place la position cible à 1s avant celle du marqueur recherché.
+            if(this.annotations[minIdx].begin > 1000)
+            {
+                targetCursorPosition -= 1000;
+            }
+            
+            //On place le marqueur au niveau de la position cible.
+            this.player.popcorn.currentTime(targetCursorPosition / 1000);
+        }
+    }
 }
 
 /*
  * Renvoie vrai si il y a au moins une gesture de notre recherche dans les marqueurs de la video.
+ * Est appelé dans les fichiers :
+ * mosaic > fonctions onMouseUp et onMarkersReady.
+ * curvesDetector > fonction updateDists.
 */
 IriSP.Widgets.Timeline.prototype.atLeastOneSearchMarker = function(gesture)
 {
-	if(_.include(this.gestures, gesture))
-	{
-		if(this.annotations && this.annotations.length > 0)
-		{
-			//On parcourt les annotations, pour chaque correspondant à la gesture recherchée, on trouve celle qui se trouve à la position minimum.
-			for(var i = 0 ; i < this.annotations.length ; i++)
-			{
-				//Si le marker est reconnu, c'est bon.
-				if(this.annotations[i].annotationType.contents.title == gesture)
-				{
-					return true;
-				}
-			}
-			
-			return false;
-		}
-	}
+    if(_.include(this.gestures, gesture))
+    {
+        if(this.annotations && this.annotations.length > 0)
+        {
+            //On parcourt les annotations, pour chaque correspondant à la gesture recherchée, on trouve celle qui se trouve à la position minimum.
+            for(var i = 0 ; i < this.annotations.length ; i++)
+            {
+                //Si le marker est reconnu, c'est bon.
+                if(this.annotations[i].annotationType.contents.title == gesture)
+                {
+                    return true;
+                }
+            }
+            
+            return false;
+        }
+    }
 }
\ No newline at end of file