Front IDILL:
authorbastiena
Fri, 29 Jun 2012 16:16:24 +0200
changeset 44 8393d3473b98
parent 43 cefce0845ac5
child 45 0e29ae4568a0
Front IDILL: Updated, mosaic spreaded into several files, new pictures and pictograms
.hgignore
front_idill/src/communication/js/client.js
front_idill/src/config.json
front_idill/src/img/background.bak.png
front_idill/src/img/cursors/bottom_blue.png
front_idill/src/img/cursors/bottom_gray.png
front_idill/src/img/cursors/left_blue.png
front_idill/src/img/cursors/left_gray.png
front_idill/src/img/cursors/pointer.png
front_idill/src/img/cursors/pointer2.png
front_idill/src/img/cursors/right_blue.png
front_idill/src/img/cursors/right_gray.png
front_idill/src/img/cursors/selector_anim.gif
front_idill/src/img/cursors/selector_anim_2.gif
front_idill/src/img/cursors/selector_blue.png
front_idill/src/img/cursors/selector_gray.png
front_idill/src/img/cursors/top_blue.png
front_idill/src/img/cursors/top_gray.png
front_idill/src/img/pointer.png
front_idill/src/img/pointer2.png
front_idill/src/index.html
front_idill/src/mosaic/css/mosaic.less
front_idill/src/mosaic/js/mosaic.js
front_idill/src/mosaic/js/neighbours.js
front_idill/src/mosaic/js/notifications.js
front_idill/src/mosaic/js/playerControl.js
front_idill/src/mosaic/js/pointers.js
front_idill/src/mosaic/js/search.js
front_idill/src/mosaic/js/zoomInteractions.js
front_idill/src/pictos/big/hover/grand-jete.png
front_idill/src/pictos/big/hover/knee-up.png
front_idill/src/pictos/big/hover/no-motion.png
front_idill/src/pictos/big/hover/up-down.png
front_idill/src/pictos/big/normal/grand-jete.png
front_idill/src/pictos/big/normal/knee-up.png
front_idill/src/pictos/big/normal/no-motion.png
front_idill/src/pictos/big/normal/right-angle.png
front_idill/src/pictos/big/normal/up-down.png
front_idill/src/pictos/big/valid/grand-jete.png
front_idill/src/pictos/big/valid/knee-up.png
front_idill/src/pictos/big/valid/no-motion.png
front_idill/src/pictos/big/valid/right-angle.png
front_idill/src/pictos/big/valid/up-down.png
front_idill/src/pictos/help/arret.png
front_idill/src/pictos/help/bend.png
front_idill/src/pictos/help/breakdance.png
front_idill/src/pictos/help/chute.png
front_idill/src/pictos/help/contact.png
front_idill/src/pictos/help/controles.png
front_idill/src/pictos/help/deplacer.png
front_idill/src/pictos/help/grandjete.png
front_idill/src/pictos/help/group_spin.png
front_idill/src/pictos/help/hello.png
front_idill/src/pictos/help/img bak/arc.png
front_idill/src/pictos/help/img bak/bend.png
front_idill/src/pictos/help/img bak/circle.png
front_idill/src/pictos/help/img bak/contact.png
front_idill/src/pictos/help/img bak/controles big.png
front_idill/src/pictos/help/img bak/fall.png
front_idill/src/pictos/help/img bak/grand_jete.png
front_idill/src/pictos/help/img bak/hello.png
front_idill/src/pictos/help/img bak/jump.png
front_idill/src/pictos/help/img bak/knee_up.png
front_idill/src/pictos/help/img bak/no_motion.png
front_idill/src/pictos/help/img bak/recherche big.png
front_idill/src/pictos/help/img bak/right_angle.png
front_idill/src/pictos/help/img bak/rythme.png
front_idill/src/pictos/help/img bak/screw.png
front_idill/src/pictos/help/img bak/selection.png
front_idill/src/pictos/help/img bak/slow.png
front_idill/src/pictos/help/img bak/up_down.png
front_idill/src/pictos/help/img bak/wave.png
front_idill/src/pictos/help/img bak/wheel.png
front_idill/src/pictos/help/jump.png
front_idill/src/pictos/help/knee_up.png
front_idill/src/pictos/help/mosaique_horizontal.png
front_idill/src/pictos/help/mosaique_vertical.png
front_idill/src/pictos/help/move_down.png
front_idill/src/pictos/help/move_left.png
front_idill/src/pictos/help/move_right.png
front_idill/src/pictos/help/move_up.png
front_idill/src/pictos/help/port_de_bras.png
front_idill/src/pictos/help/precedent.png
front_idill/src/pictos/help/recherche.png
front_idill/src/pictos/help/rythme.png
front_idill/src/pictos/help/selection.png
front_idill/src/pictos/help/slow.png
front_idill/src/pictos/help/spin.png
front_idill/src/pictos/help/suivant.png
front_idill/src/pictos/help/up_down.png
front_idill/src/pictos/help/volant.png
front_idill/src/pictos/help/wave.png
front_idill/src/pictos/notifications/deplacer.png
front_idill/src/pictos/notifications/move_down.png
front_idill/src/pictos/notifications/move_left.png
front_idill/src/pictos/notifications/move_right.png
front_idill/src/pictos/notifications/move_up.png
front_idill/src/pictos/notifications/swipe_left.png
front_idill/src/pictos/notifications/swipe_right.png
front_idill/src/pictos/notifications/unzoom_horizontal.png
front_idill/src/pictos/notifications/unzoom_vertical.png
front_idill/src/pictos/small/arc.png
front_idill/src/pictos/small/hello.png
front_idill/src/pictos/small/no-motion.png
front_idill/src/pictos/small/port_de_bras.png
front_idill/src/pictos/small/rythme.png
front_idill/src/pictos/small/slow.png
front_idill/src/pictos/small/wave.png
front_idill/src/player/json/local_videos.json
front_idill/src/player/metadataplayer/LdtPlayer-core.js
front_idill/src/player/metadataplayer/Timeline.css
front_idill/src/player/metadataplayer/Timeline.js
front_idill/src/search/js/curve.js
front_idill/src/search/js/searchCanvas.js
--- a/.hgignore	Fri Jun 29 15:46:34 2012 +0200
+++ b/.hgignore	Fri Jun 29 16:16:24 2012 +0200
@@ -74,6 +74,9 @@
 front_idill/src/player/TODO player 02-05-12.txt
 middleware.zip
 middleware/dist/wampserver2.2e.exe
+front_idill/src/communication/js/client.js.bak
+front_idill/src/mosaic/js/mosaic.js.bak
+front_idill/src/player/videos/*.mp4
 syntax: regexp
 middleware/extern/.*/(bin|obj)
 middleware/src/bin/Debug/*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/front_idill/src/communication/js/client.js	Fri Jun 29 16:16:24 2012 +0200
@@ -0,0 +1,287 @@
+/*
+ * Un client est défini par une socket, qui permettra de recevoir les données du server websocket du Middleware.
+ * On accède aussi à la mosaïque.
+*/
+function client(host, port, _mosaic)
+{
+	this.socket;
+	this.mosaic = _mosaic;
+	
+	this.pointerLeft = false;
+	this.pointerRight = false;
+	this.timePointers = 100;
+	this.pointerLeftTimeout;
+	this.pointerRightTimeout;
+	this.isLeftHanded = false;
+	
+	this.createWebSocket('ws://' + host + ':' + port + '/');
+}
+
+/*
+ * Création et Initialisation des sockets et listeners permettant d'écouter le server.
+*/
+client.prototype.createWebSocket = function(host)
+{
+	var _this = this;
+	
+	//Initialise la fonctionnalité websocket du naviguateur.
+    if(window.MozWebSocket)
+	{
+        window.WebSocket = window.MozWebSocket;
+	}
+	
+	//Si le naviguateur ne supporte pas les websockets, on s'arrête là.
+    if(!window.WebSocket)
+	{
+        alert('Votre navigateur ne supporte pas les webSocket!');
+        return false;
+    }
+	//Sinon
+	else
+	{
+		//On initialise la socket.
+		this.socket = new WebSocket(host);
+		
+		//Si elle est ouverte, on notifie le Front.
+		this.socket.onopen = function()
+		{
+			console.log('Socket ouverte.');
+		}
+		//Si elle est fermée, on notifie le Front.
+		this.socket.onclose = function()
+		{
+			console.log('Socket fermée.');
+		}
+		//S'il y a un problème dans la connection, on notifie le Front.
+		this.socket.onerror = function()
+		{
+			console.log('Une erreur est survenue dans le module de Communication.');
+		}
+		//Si on reçoit un message.
+		this.socket.onmessage = function(msg)
+		{
+			_this.processMsg(msg);
+		}
+    }
+}
+
+/*
+ * Traite un message reçu du Middleware.
+*/
+client.prototype.processMsg = function(msg)
+{
+	if(typeof msg === 'undefined' || typeof msg.data === 'undefined')
+	{
+		return;
+	}
+	
+	var _this = this;
+	
+	
+	//S'il s'agit d'une string et non d'une instruction pour les pointeurs.
+	if(msg.data[0] === '2')
+	{
+		var instruction = msg.data.substring(2, msg.data.length);
+		
+		// if(instruction.indexOf("INCOMING") == -1 && instruction.indexOf('NO-USER') == -1)
+		// {
+			this.mosaic.manageControlEvents(instruction);
+		// }
+	}
+	//Sinon si ce sont les coordonnées de la main droite.
+	// /!\/!\ //
+	else if(msg.data[0] == '1')
+	{
+		var instruction = msg.data.substring(2, msg.data.length);
+		pt = instruction.split(';');
+		var x = Math.abs(parseFloat(pt[0])), y = Math.abs(parseFloat(pt[1]));
+		// console.log(Math.abs(parseFloat(pt[0])), Math.abs(parseFloat(pt[1])));
+		
+		this.pointerLeft = true;
+		clearTimeout(this.pointerLeftTimeout);
+		
+		if(!this.mosaic.mouseInteractions && this.mosaic.currentMode != 'NO-USER' && this.mosaic.currentMode.indexOf('INCOMING') == -1)
+		{
+			// console.log('pt');
+			this.mosaic.refreshMainPointer(x, y);
+		}
+		
+		// /!\ //
+		if(!this.mosaic.isMainPointerDisplayed)
+		{
+			this.mosaic.mainPointerDisplay(true);
+			this.mosaic.isMainPointerDisplayed = true;
+		}
+		
+		this.pointerLeftTimeout = setTimeout(function()
+		{
+			// console.log('RELEASE LEFT');
+			_this.pointerLeft = false;
+			
+			if(_this.mosaic.isMainPointerDisplayed)
+			{
+				_this.mosaic.isMainPointerDisplayed = false;
+				_this.mosaic.mainPointerDisplay(false);
+			}
+		}, this.timePointers);
+	}
+	//Sinon si ce sont les coordonnées de la main gauche.
+	else if(msg.data[0] == '0')
+	{
+		var instruction = msg.data.substring(2, msg.data.length);
+		pt = instruction.split(';');
+		var x = Math.abs(parseFloat(pt[0])), y = Math.abs(parseFloat(pt[1]));
+		// console.log(Math.abs(parseFloat(pt[0])), Math.abs(parseFloat(pt[1])));
+		
+		this.pointerRight = true;
+		clearTimeout(this.pointerRightTimeout);
+		
+		if(!this.mosaic.mouseInteractions && this.mosaic.currentMode != 'NO-USER' && this.mosaic.currentMode.indexOf('INCOMING') == -1)
+		{
+			this.mosaic.refreshSecondPointer(x, y);
+		}
+		
+		if(!this.mosaic.isSecondPointerDisplayed)
+		{
+			this.mosaic.secondPointerDisplay(true);
+			this.mosaic.isSecondPointerDisplayed = true;
+		}
+		
+		this.pointerRightTimeout = setTimeout(function()
+		{
+			// console.log('RELEASE RIGHT');
+			_this.pointerRight = false;
+			
+			if(_this.mosaic.isSecondPointerDisplayed)
+			{
+				_this.mosaic.isSecondPointerDisplayed = false;
+				_this.mosaic.secondPointerDisplay(false);
+			}
+		}, this.timePointers);
+	}
+	
+	if(this.pointerLeft && !this.pointerRight || !this.pointerLeft && this.pointerRight)
+	{
+		//On interrompt l'idle des pointeurs.
+		this.mosaic.pointersIdleAvailable = false;
+		this.mosaic.removeIdlePointers();
+		this.mosaic.areBothPointersHere = false;
+		
+		if(this.mosaic.isSearchByCurvesOn)
+		{
+			this.mosaic.isSearchByCurvesOn = false;
+			if(this.mosaic.searchCanvas)
+			{
+				this.mosaic.searchCanvas.onPointerOut();
+				console.log('OUT !!!!!');
+			}
+		}
+	}
+	if(!this.pointerLeft && !this.pointerRight)
+	{
+		//On interrompt l'idle des pointeurs.
+		this.mosaic.pointersIdleAvailable = false;
+		this.mosaic.removeIdlePointers();
+		this.mosaic.areBothPointersHere = false;
+		
+		if(this.mosaic.isSearchByCurvesOn)
+		{
+			this.mosaic.isSearchByCurvesOn = false;
+			if(this.mosaic.searchCanvas)
+			{
+				this.mosaic.searchCanvas.onPointerOut();
+			}
+		}
+		
+		this.mosaic.deselectAllNeighbours();
+		this.mosaic.preUnzoom();
+	}
+	
+	if(this.pointerLeft && this.pointerRight)
+	{
+		this.mosaic.areBothPointersHere = true;
+		this.mosaic.removeCheckForBothPointersHere();
+		
+		if(this.mosaic.currentMode == 'MOSAIC' || this.mosaic.currentMode == 'FILTER')
+		{
+			$('#mainPointer').css('background-image', './img/cursors/pointer.png');
+			$('#secondPointer').css('background-image', './img/cursors/pointer2.png');
+		}
+		
+		if(this.mosaic.currentMode == 'FILTER' || this.mosaic.currentMode == 'SEARCH')
+		{
+			if(this.mosaic.searchCanvas)
+			{
+				var mainPointerX = +$('#mainPointer').position().left + $('#mainPointer').width() / 2;
+				var mainPointerY = +$('#mainPointer').position().top - this.mosaic.MPTop_margin + $('#mainPointer').height() / 2;
+				var secondPointerX = +$('#secondPointer').position().left + $('#mainPointer').width() / 2;
+				var secondPointerY = +$('#secondPointer').position().top - this.mosaic.MPTop_margin + $('#mainPointer').height() / 2;
+				
+				if(!this.mosaic.isSearchByCurvesOn)
+				{
+					this.mosaic.isSearchByCurvesOn = true;
+					this.mosaic.searchCanvas.onPointerIn(mainPointerX, mainPointerY, secondPointerX, secondPointerY);
+					this.mosaic.canDrawNextCurve = true;
+				}
+				else if(this.mosaic.isSearchByCurvesOn)
+				{
+					if(this.mosaic.canDrawNextCurve)
+					{
+						this.mosaic.canDrawNextCurve = false;
+						if(Math.abs(mainPointerX - this.mosaic.mainPointerLastX) > 10 || Math.abs(mainPointerY - this.mosaic.mainPointerLastY) > 10 || Math.abs(secondPointerX - this.mosaic.secondPointerLastX) > 10 || Math.abs(secondPointerY - this.mosaic.secondPointerLastY) > 10)
+						{
+							console.log('move');
+							this.mosaic.searchCanvas.onPointerMove(mainPointerX, mainPointerY, secondPointerX, secondPointerY);
+						}
+					}
+					else
+					{
+						this.mosaic.nextDrawCurveTimeout = setTimeout(function()
+						{
+							_this.mosaic.canDrawNextCurve = true;
+						}, this.mosaic.config['timeoutNextDrawCurve']);
+					}
+				}
+			}
+		}
+	}
+	
+	//Quant on a reçu un message, on vérifie la présence des deux pointeurs.
+	this.mosaic.checkForBothPointersHere();
+	
+	if(this.mosaic.pointersIdleAvailable)
+	{
+		//On effectue une vérification de la position des pointeurs pour l'idle.
+		this.mosaic.detectIdlePointers();
+	}
+	
+	//Si le timeout a besoin d'être relancé ou bien que l'affichage de l'aide est disponible.
+	if(this.mosaic.pointersIdleNeedLaunch || this.mosaic.canNotifyHelp)
+	{
+		// console.log('launch idle');
+		this.mosaic.launchIdlePointers();
+		this.mosaic.pointersIdleNeedLaunch = false;
+	}
+	
+	//Si la détection d'idle n'est pas activée et qu'on est dans un mode permettant l'interaction de l'utilisateur. 
+	if(!this.mosaic.pointersIdleAvailable && this.mosaic.currentMode != "NO-USER" && this.mosaic.currentMode.indexOf("INCOMING") == -1 && this.mosaic.areBothPointersHere)
+	{
+		//On enclenche la détection d'idle.
+		this.mosaic.pointersIdleAvailable = true;
+		this.mosaic.pointersIdleNeedLaunch = true;
+	}
+	// /!\/!\ //
+}
+
+/*
+ * Permet d'envoyer un message au Middleware (optionnel).
+*/
+client.prototype.sendMessage = function(data)
+{
+	//Si data est un objet, on le change en chaine.
+	if(typeof data === 'object')
+	{
+		data = JSON.stringify(data);
+	}
+	this.socket.send(data);
+}
\ No newline at end of file
--- a/front_idill/src/config.json	Fri Jun 29 15:46:34 2012 +0200
+++ b/front_idill/src/config.json	Fri Jun 29 16:16:24 2012 +0200
@@ -1,11 +1,12 @@
 {
-	"local":"false",
+	"local":"true",
 	"length":"5",
 	"imagesToShow":"20",
-	"totalImages":"23",
+	"totalImages":"22",
 	"timePrezoom":"500",
 	"timePreUnzoom":"200",
-	"timeZoom":"500",
+	"timeZoom":"2000",
+	"zoomTime":"500",
 	"timeUnzoom":"400",
 	"timeNeighbourGlowing":"1000",
 	"timeNeighbourUnglowing":"1000",
@@ -13,7 +14,24 @@
 	"timeSearchFade":"2000",
 	"timeNotifyFade":"2000",
 	"timeFilterFade":"2000",
+	"timeANFade":"500",
+	"timeoutZoom":"2000",
+	"timeoutUnzoom":"1000",
+	"timeoutMoveToNeighbour":"250",
+	"timeoutPointersIdle":"2000",
+	"timeoutAreBothPointersHere":"500",
+	"timeoutRemoveNotificationByGesture":"1500",
+	"timeoutRemoveFailedNotificationByGesture":"1500",
+	"timeoutNotifySwipe":"1000",
+	"timeoutSelectTL":"100",
+	"timeoutSlideTL":"1000",
+	"timeoutCanNotifyHelp":"1000",
+	"timeoutRemoveSpinner":"1000",
+	"timeoutNouser":"3000",
+	"timeoutNextDrawCurve":"500",
 	"zoomPercentage":"0.80",
 	"prezoomPercentage":"0.25",
-	"zoomedMargin":"42"
+	"zoomedMargin":"42",
+	"host":"127.0.0.1",
+	"port":"8090"
 }
\ No newline at end of file
Binary file front_idill/src/img/background.bak.png has changed
Binary file front_idill/src/img/cursors/bottom_blue.png has changed
Binary file front_idill/src/img/cursors/bottom_gray.png has changed
Binary file front_idill/src/img/cursors/left_blue.png has changed
Binary file front_idill/src/img/cursors/left_gray.png has changed
Binary file front_idill/src/img/cursors/pointer.png has changed
Binary file front_idill/src/img/cursors/pointer2.png has changed
Binary file front_idill/src/img/cursors/right_blue.png has changed
Binary file front_idill/src/img/cursors/right_gray.png has changed
Binary file front_idill/src/img/cursors/selector_anim.gif has changed
Binary file front_idill/src/img/cursors/selector_anim_2.gif has changed
Binary file front_idill/src/img/cursors/selector_blue.png has changed
Binary file front_idill/src/img/cursors/selector_gray.png has changed
Binary file front_idill/src/img/cursors/top_blue.png has changed
Binary file front_idill/src/img/cursors/top_gray.png has changed
Binary file front_idill/src/img/pointer.png has changed
Binary file front_idill/src/img/pointer2.png has changed
--- a/front_idill/src/index.html	Fri Jun 29 15:46:34 2012 +0200
+++ b/front_idill/src/index.html	Fri Jun 29 16:16:24 2012 +0200
@@ -32,11 +32,18 @@
         <script type="text/javascript" src="../lib/jquery.min.js"></script>
         <script type="text/javascript" src="../lib/jquery-ui.min.js"></script>
         <script type="text/javascript" src="./mosaic/js/mosaic.js"></script>
+        <script type="text/javascript" src="./mosaic/js/notifications.js"></script>
+        <script type="text/javascript" src="./mosaic/js/pointers.js"></script>
+        <script type="text/javascript" src="./mosaic/js/zoomInteractions.js"></script>
+        <script type="text/javascript" src="./mosaic/js/neighbours.js"></script>
+        <script type="text/javascript" src="./mosaic/js/search.js"></script>
+        <script type="text/javascript" src="./mosaic/js/playerControl.js"></script>
         <script type="text/javascript" src="./mosaic/js/localMosaic.js"></script>
 		<script type="text/javascript" src="./player/metadataplayer/LdtPlayer-core.js"></script>
 		<script type="text/javascript" src="../lib/paper.js"></script>
 		<link rel="stylesheet" type="text/css" href="./search/css/searchCanvas.css" />
 		<script type="text/javascript" src="./search/js/searchCanvas.js"></script>
+		<script type="text/javascript" src="./communication/js/client.js"></script>
     </head>
     
     <body>
@@ -58,7 +65,8 @@
 			default_parameters['totalImages'] = 23;
 			default_parameters['timePrezoom'] = 500;
 			default_parameters['timePreUnzoom'] = 200;
-			default_parameters['timeZoom'] = 500;
+			default_parameters['timeZoom'] = 2000;
+			default_parameters['zoomTime'] = 500;
 			default_parameters['timeUnzoom'] = 400;
 			default_parameters['timeNeighbourGlowing'] = 1000;
 			default_parameters['timeNeighbourUnglowing'] = 1000;
@@ -66,10 +74,27 @@
 			default_parameters['timeSearchFade'] = 2000;
 			default_parameters['timeNotifyFade'] = 2000;
 			default_parameters['timeFilterFade'] = 2000;
+			default_parameters['timeANFade'] = 500;
 			default_parameters['timeFilling'] = 500;
+			default_parameters['timeoutZoom'] = 2000;
+			default_parameters['timeoutUnzoom'] = 1000;
+			default_parameters['timeoutMoveToNeighbour'] = 250;
+			default_parameters['timeoutPointersIdle'] = 2000;
+			default_parameters['timeoutAreBothPointersHere'] = 500;
+			default_parameters['timeoutRemoveNotificationByGesture'] = 1500;
+			default_parameters['timeoutRemoveFailedNotificationByGesture'] = 1500;
+			default_parameters['timeoutNotifySwipe'] = 1000;
+			default_parameters['timeoutSelectTL'] = 100;
+			default_parameters['timeoutSlideTL'] = 1000;
+			default_parameters['timeoutCanNotifyHelp'] = 1000;
+			default_parameters['timeoutRemoveSpinner'] = 1000;
+			default_parameters['timeoutNouser'] = 3000;
+			default_parameters['timeoutNexrDrawCurve'] = 500;
 			default_parameters['zoomPercentage'] = 0.80;
 			default_parameters['prezoomPercentage'] = 0.25;
 			default_parameters['zoomedMargin'] = 42;
+			default_parameters['host'] = '127.0.0.1';
+			default_parameters['port'] = '80';
 			
             /*var length = 5, imagesToShow = 20, totalImages = 23;
             //Temps de chargement du prezoom en ms (seront importés des paramètres du Middleware).
@@ -100,22 +125,22 @@
 			{
                 imgs[i] = i + '.jpg';
 			}*/
-            
+            var mos;
             //Si la page a chargé, on raffraichit la mosaïque.
             $(document).ready(function ()
             {
-				var mos = new mosaic('./config.json', default_parameters);
+				mos = new mosaic('./config.json', default_parameters);
                 //mos.loadMosaic();
                 
-                $('.snapshotDivs').mouseenter(function ()
+                /*$('.snapshotDivs').mouseenter(function ()
                 {
                     //On effectue un prézoom dès qu'on va sur une image.
                     mos.preZoom($(this));
-                });
-                $('body').keypress(function (event)
+                });*/
+                /*$('body').keypress(function (event)
                 {
 					mos.manageControlEvents(event);
-                });
+                });*/
             });
         </script>
     </body>
--- a/front_idill/src/mosaic/css/mosaic.less	Fri Jun 29 15:46:34 2012 +0200
+++ b/front_idill/src/mosaic/css/mosaic.less	Fri Jun 29 16:16:24 2012 +0200
@@ -31,12 +31,14 @@
 @notify-selection-background-image-path: url("../../pictos/notifications/selectionner.png");
 @notify-search-background-image-path: url("../../pictos/notifications/rechercher.png");
 @notify-point-background-image-path: url("../../pictos/notifications/confirmer.png");
+@notify-timeline-background-image-path: url("../../pictos/notifications/deplacer.png");
 @notify-help-background-color: rgba(100, 100, 100, 0.9);
 @notify-help-border-width: 2px;
 @notify-help-margin: 15px;
 @notify-help-search-background-image-path: url("../../pictos/help/recherche.png");
 @notify-help-controls-background-image-path: url("../../pictos/help/controles.png");
-@mainPointer-background-image-path: url("../../img/pointer.png");
+@mainPointer-background-image-path: url("../../img/cursors/pointer.png");
+@secondPointer-background-image-path: url("../../img/cursors/pointer2.png");
 
 html
 {
@@ -47,6 +49,8 @@
 {
     overflow: hidden;
     background-color: @black;
+	background-image: @mosaic-background-image-path;
+	background-repeat: repeat;
 }
 
 /*
@@ -61,8 +65,9 @@
     width: 100%;
     top: 0px;
     left: 0px;
-    background-image: @mosaic-background-image-path;
-    background-repeat: repeat;
+	background: transparent;
+    //background-image: @mosaic-background-image-path;
+    //background-repeat: repeat;
 }
 
 /*
@@ -148,11 +153,11 @@
 .notifications
 {
 	position: absolute;
-	width: 100px;
-	height: 100px;
+	width: 200px;
+	height: 200px;
 	background-repeat: no-repeat;
 	background-position: 0px 0px;
-	background-size: 100px 100px;
+	background-size: 200px 200px;
 	opacity: 0;
 	margin: 15px;
 	z-index: 400;
@@ -194,6 +199,11 @@
 	background-image: @notify-point-background-image-path;
 }
 
+#notify_timeline
+{
+	background-image: @notify-timeline-background-image-path;
+}
+
 /*
  * Aide
  */
@@ -250,19 +260,19 @@
 #search_img
 {
 	background-image: @notify-help-search-background-image-path;
+	background-repeat: no-repeat;
 	background-position: center center;
-	background-repeat: no-repeat;
-	background-size: 150px 150px;
-	height: 150px;
+	width: 100%;
+	height: 225px;
 }
 
 #controls_img
 {
 	background-image: @notify-help-controls-background-image-path;
+	background-repeat: no-repeat;
 	background-position: center center;
-	background-repeat: no-repeat;
-	//background-size: 150px 150px;
-	height: 150px;
+	width: 100%;
+	height: 225px;
 }
 
 #search_2hands_text, #search_body_text, #controls_1hand_text
@@ -278,18 +288,17 @@
 	margin-bottom: 10px;
 }
 
-#search_2hands_imgs, #controls_1hand_imgs
+/*#search_2hands_imgs, #controls_1hand_imgs
 {
 	padding-left: 40px;
-}
+}*/
 
 .notify_imgs_small
 {
 	float: left;
-	width: 80px;
-	height: 80px;
+	width: 130px;
+	height: 130px;
 	background-position: 0px 0px;
-	//background-size: 80px 80px;
 	background-repeat: no-repeat;
 }
 
@@ -314,5 +323,28 @@
 	background-position: 0px 0px;
 	background-repeat: no-repeat;
 	z-index: 500;
-	display: none;
+	opacity: 0;
+}
+
+#secondPointer
+{
+	position: absolute;
+	width: 74px;
+	height: 74px;
+	background-image: @secondPointer-background-image-path;
+	background-position: 0px 0px;
+	background-repeat: no-repeat;
+	z-index: 500;
+	opacity: 0;
+}
+
+.borderNeighbours
+{
+	position: absolute;
+    background-color: #fff;
+    margin: @snapshots-margin;
+    //background-image: @mosaic-background-image-path;
+	background-color: @black;
+	background-repeat: repeat;
+	background-position: 0px 0px;
 }
\ No newline at end of file
--- a/front_idill/src/mosaic/js/mosaic.js	Fri Jun 29 15:46:34 2012 +0200
+++ b/front_idill/src/mosaic/js/mosaic.js	Fri Jun 29 16:16:24 2012 +0200
@@ -24,62 +24,183 @@
  */
 function mosaic(config, default_conf)
 {
+	//Interactions souris/kinect.
+	this.mouseInteractions = false;
+	//Interactions avec/sans préphase.
+	this.prephaseEnabled = true;
+	
+	this.gestures = ["fall", "jump", "circle", "screw", "bend", "arc", "pendulum", "knee-up", "right-angle", "wave", "slow", "hello", "no-motion", "wheel", "contact", "run"];
+
 	//Chemin du fichier de configuration.
 	this.config_path = config;
 	//Configuration par défaut en cas de valeur erronnée.
 	this.default_config = default_conf;
-	this.config = new Object();
+	this.config = new Object();
 	//Tableaux des urls des vidéos, des snapshots et de leur position dans la mosaïque.
 	this.videos = [];
 	this.urls = [];
+	this.sources = [];
 	this.imgs = [];
+	this.opacities = [];
+	this.timeToGoAt = [];
 	this.ids = [];
 	this.fillingIds = [];
 	this.currentRandomVideoIdx = 0;
-	
+	
+	//Dernières positions des pointeurs.
+	this.mainPointerLastX;
+	this.mainPointerLastY;
+	this.secondPointerLastX;
+	this.secondPointerLastY;
+	//Dernières positions avant le lancement de la fonction d'idle.
+	this.mainPointerIdleStartX;
+	this.mainPointerIdleStartY;
+	this.secondPointerIdleStartX;
+	this.secondPointerIdleStartY;
+	
 	//Dimensions de la mosaïque en pixels.
 	this.width;
-	this.height;
+	this.height;
 	//Dimensions d'un snapshot en pixels.
 	this.snapshotWidth;
-	this.snapshotHeight;
+	this.snapshotHeight;
 	//Espacement entre les snapshots en pixels.
 	this.marginWidth;
-	
+	
 	//Booléens permettant ou non certaines intéractions selon le contexte.
 	this.zoomed;
 	this.fullscreen;
 	this.canMoveToNeighbour;
+	this.mainPointerExitBorder;
+	this.secondPointerExitBorder;
+	this.isMainPointerDisplayed;
+	this.isSecondPointerDisplayed;
 	this.helpDisplayed;
+	//Indique si l'utilisateur a manuellement pausé la vidéo.
+	this.userPaused;
+	//Indique si on est en train de se déplacer vers un voisin.
+	this.currentlyMoving;
+	//Indique si on est en train de dézoomer vers la mosaïque.
+	this.currentlyUnzooming;
+	//Indique si on peut s'approcher de kinect.
+	this.canStart;
+	//Indique si on est actuellement sur un snapshot.
+	this.isOnASnapshot;
+	//Indique si l'idle des pointeurs est disponible (deux mains détectées).
+	this.pointersIdleAvailable;
+	//Indique si le timeout pour l'idle des pointeurs à besoin d'être lancé.
+	this.pointersIdleNeedLaunch;
+	//Indique si les deux mains sont là.
+	this.areBothPointersHere;
+	//Indique si le timeout pour la détection de deux pointeurs a été lancé.
+	this.areBothPointersTimeoutLaunched;
+	//Indique si la mosaïque a été filtrée.
+	this.isMosaicFiltered;
+	//Indique si on est actuellement dans une recherche par gesture.
+	this.isCurrentlyInASearchByGesture;
+	//Indique si un pointeur est déjà sur une notification de recherche par gesture.
+	this.alreadyOnNotification;
+	//Si on a fait un swipe.
+	this.isSwipe;
+	//On peut swiper.
+	this.canSwipe;
+	//On passe vers une autre video automatiquement à la fin d'une lecture.
+	this.autoMove;
+	//Si l'utilisateur a demandé à sélectionner la TL.
+	this.isTLRequested;
+	//Le pointeur gauche a sélectionné la TL.
+	this.isTLSelectedBySecondPointer;
+	//Le pointeur droit a sélectionné la TL.
+	this.isTLSelectedByMainPointer;
+	//On peut afficher l'aide.
+	this.canNotifyHelp;
+	//Indique si la mosaique est en train d'être filtrée.
+	this.isMosaicFiltering;
+	this.arrowLeftLoading = false;
+	this.arrowRightLoading = false;
+	this.arrowUpLoading = false;
+	this.arrowDownLoading = false;
+	//On est dans une recherche par courbes.
+	this.isSearchByCurvesOn;
+	this.canDrawNextCurve = false;
+	
+	//Timeout (attente) pour le zoom après un préZoom.
+	this.zoomTimeout;
+	//Timeout (attente) pour le passage vers un voisin.
+	this.moveToNeighbourTimeout;
+	this.mainPointerExitBorderTimeout;
+	this.secondPointerExitBorderTimeout;
+	//Idle time pour les pointeurs afin d'informer le front qu'on souhaite faire une recherche.
+	this.pointersSearchIdleTimeout;
+	//Vérifie toutes les N ms que les deux pointeurs sont détectés.
+	this.areBothPointersHereTimeout;
+	//Délai de suppression d'une notification de recherche par gesture.
+	this.removeNotificationByGestureTimeout;
+	//Délai de suppression d'une notification de recherche par gesture infructueuse.
+	this.removeFailedNotificationByGestureTimeout;
+	//Délai avant la suppression de notification swipe.
+	this.notifySwipeTimeout;
+	//Délai pour la sélection de la TL.
+	this.selectTLTimeout;
+	//Délai pour slider sur la TL.
+	this.canSlideInTLTimeout;
+	//Délai pour afficher l'aide.
+	this.canNotifyHelpTimeout;
+	this.arrowLeftTimeout;
+	this.arrowRightTimeout;
+	this.arrowUpTimeout;
+	this.arrowDownTimeout;
+	
+	this.arrowSpinnerTimeout;
+	this.nouserTimeout;
+	this.nextDrawCurveTimeout;
+	
+	//Dernier message INCOMING (pour éviter d'effectuer n fois la même action.
+	this.lastIncomingMessage;
 	
 	//Type de marqueur recherché dans la mosaïque (en mode filter).
 	this.filterSearchedType = "";
-	
+	
 	//Mode actuel.
-	this.currentMode = "MOSAIC";
+	this.currentMode = "NO-USER";
 	//Snapshot sur lequel on a zoomé.
-	this.previousZoomedSN;
+	this.previousZoomedSN = null;
 	//Son ID.
-	this.previousId;
+	this.previousId;
+	//Dernier snapshot prézoomé non null.
+	this.lastNonNullSN = null;
 	//Largeur de la marge pour le centrage vertical de la mosaïque.
 	this.MPTop_margin;
-	this.top_margin;
-
+	this.top_margin;
+	
+	//Gesture actuellement cherchée.
+	this.currentSearchGesture;
+
 	//Mosaïque locale.
-	this.localMos;
+	this.localMos;
 	//Position des voisins lors d'un zoom.
-	this.neighboursIds = [];
+	this.neighboursIds = [];
 	//ID du snapshot du milieu lors d'un zoom.
 	this.centerId;
 	
+	//Voisins sélectionnés par les pointeurs.
+	this.mainPointerNeighbourSelectedId = null;
+	this.secondPointerNeighbourSelectedId = null;
+	
 	//Snapshots a afficher.
 	this.snapshotsToShow = 1;
 	
 	//Lecteur.
 	this.player;
+	//Si le lecteur est prêt.
+	this.playerIsReady;
+	
 	//Annotations (pour les marqueurs los d'un filtrage).
 	this.annotations = [];
 	
+	//Client websocket pour recevoir les notifications du Middleware.
+	this.client;
+	
 	//Coordonnées et dimensions d'un snapshot zoomé.
 	this.snTop = 0;
 	this.snLeft = 0;
@@ -99,8 +220,8 @@
  */
 mosaic.prototype.createMosaic = function()
 {
-	console.log('CREATE');
-	this.currentMode = "NO-USER";
+	// console.log('CREATE');
+	// this.currentMode = "NO-USER";
 	var initPanel = '<div id="initPanel"></div>';
 	var mp = $('#mainPanel');
 	mp.append(initPanel);
@@ -119,11 +240,36 @@
 	//S'il s'agit d'un rectangle.
     if(imgs % len == 0)
     {
-		this.previousZoomedSN = '';
-		this.previousPrezoomDiv = '';
+		this.previousZoomedSN = null;
+		this.previousPrezoomDiv = null;
 		this.fullscreen = false;
 		this.canMoveToNeighbour = false;
+		this.currentlyZooming = false;
+		this.currentlyUnzooming = false;
 		this.helpDisplayed = false;
+		this.canStart = false;
+		this.isOnASnapshot = false;
+		this.isMosaicFiltered = false;
+		this.areBothPointersHere = false;
+		this.areBothPointersTimeoutLaunched = false;
+		this.isCurrentlyInASearchByGesture = false;
+		this.alreadyOnNotification = false;
+		this.playerIsReady = false;
+		this.currentSearchGesture = '';
+		this.isMainPointerDisplayed = false;
+		this.isSecondPointerDisplayed = false;
+		this.isSwipe = false;
+		this.canSwipe = false;
+		this.autoMove = false;
+		this.isTLRequested = false;
+		this.isTLSelectedByMainPointer = false;
+		this.isTLSelectedBySecondPointer = false;
+		this.canNotifyHelp = false;
+		this.isMosaicFiltering = false;
+		this.isSearchByCurvesOn = false;
+		
+		this.lastIncomingMessage = 'INCOMING-0';
+		
 		var str = '';
 		
 		if(this.imgs.length >= imgs)
@@ -148,7 +294,7 @@
  */
 mosaic.prototype.loadMosaic = function()
 {
-	console.log('LOAD');
+	// console.log('LOAD');
 	var createMosaic = this.createMosaic();
 	
 	if(createMosaic == '')
@@ -178,14 +324,15 @@
     this.MPTop_margin = ($(document).height() - $('#mainPanel').height())/2;
     $('#mainPanel').css('margin-top', this.MPTop_margin).css('margin-bottom', this.MPTop_margin);
 	
-	//On affiche les notifications.
-	this.notifySelectionSearchMosaicFull();
+	//On fait coincider le background du body avec celui de la mosaïque.
+	$('body').css('background-position', '0px ' + this.MPTop_margin + 'px');
+	console.log(this.MPTop_margin);
 	
-	$('.snapshotDivs').mouseenter(function ()
+	/*$('.snapshotDivs').mouseover(function ()
 	{
 		//On effectue un prézoom dès qu'on va sur une image.
 		_this.preZoom($(this));
-	});
+	});*/
 	
 	this.addPointers();
 	
@@ -208,18 +355,56 @@
 	
 	for (var i = 0; i < nbFichiers; i++)
 	{
-		console.log('url : ' + _this.urls[i]);
-		var source = sourceManager.remoteSource({url: _this.urls[i], serializer: IriSP.serializers.ldt});
-		source.onLoad(function()
+		// console.log('url : ' + _this.urls[i]);
+		_this.sources[i] = sourceManager.remoteSource({url: _this.urls[i], serializer: IriSP.serializers.ldt});
+		_this.sources[i].onLoad(function()
 		{
+			var source = this;
+			// console.log(source);
 			globalAnnotations.addElements(source.getAnnotations());
+			// console.log(source.url + ' ' + source.getAnnotations().length);
 			fichiersCharges++;
 			if (fichiersCharges == nbFichiers)
 			{
 				// instructions à exécuter quand tout est chargé
 				_this.annotations = globalAnnotations;
-				console.log('annotations loaded');
-				_this.init();
+				// console.log(_this.annotations.length + ' ' + nbFichiers);
+				console.log(_this.annotations.length + ' annotations loaded from ' + nbFichiers + ' files.');
+				
+				//Si on gère les interactions à la souris.
+				if(_this.mouseInteractions)
+				{
+					$('body').mousemove(function(e){_this.refreshMainPointer(e.pageX, e.pageY, _this)});
+				}
+				
+				// if(false)
+				// {
+				if(_this.prephaseEnabled)
+				{
+					_this.init();
+					_this.showNImages(0);
+					_this.currentMode = "NO-USER";
+				}
+				else
+				{
+					_this.showNImages(20);
+					_this.currentMode = "MOSAIC";
+				}
+				// }
+				
+				// /!\ //
+				// _this.currentMode = "FILTER";
+				// _this.showNImages(20);
+				//_this.isSearchByCurvesOn = true;
+				// _this.startSearch();
+				// console.log('CANVAS READY');
+				// /!\ //
+				
+				/*_this.currentSearchGesture = 'bend';
+				_this.currentMode = 'FILTER';
+				_this.searchFilter('bend');*/
+				
+				_this.previousZoomedSN = $('#snapshotDiv-' + _this.fillingIds[0]);
 			}
 		});
 	}
@@ -232,7 +417,7 @@
 {
 	var _this = this;
 	
-	var supposedToBeInt = ['length', 'imagesToShow', 'totalImages', 'timePrezoom', 'timePreUnzoom', 'timeZoom', 'timeUnzoom', 'timeNeighbourGlowing', 'timeNeighbourUnglowing', 'timeMovingToNeighbour', 'timeSearchFade', 'timeNotifyFade', 'timeFilterFade', 'timeFilling', 'zoomedMargin'];
+	var supposedToBeInt = ['length', 'imagesToShow', 'totalImages', 'timePrezoom', 'timePreUnzoom', 'timeZoom', 'zoomTime', 'timeUnzoom', 'timeNeighbourGlowing', 'timeNeighbourUnglowing', 'timeMovingToNeighbour', 'timeSearchFade', 'timeNotifyFade', 'timeFilterFade', 'timeANFade', 'timeFilling', 'zoomedMargin', 'timeoutZoom', 'timeoutUnzoom', 'timeoutMoveToNeighbour', 'timeoutPointersIdle', 'timeoutAreBothPointersHere', 'timeoutRemoveNotificationByGesture', 'timeoutRemoveFailedNotificationByGesture', 'timeoutNotifySwipe', 'timeoutSelectTL', 'timeoutSlideTL', 'timeoutCanNotifyHelp', 'timeoutRemoveSpinner', 'timeoutNouser', 'timeoutNextDrawCurve'];
 	var supposedToBeFloat = ['zoomPercentage', 'prezoomPercentage'];
 	
 	$.getJSON(file_path, function(data)
@@ -246,7 +431,7 @@
 				var intVal = parseInt(val);
 				if(isNaN(intVal))
 				{
-					console.log(_this.default_config);
+					// console.log(_this.default_config);
 					_this.config[key] = _this.default_config[key];
 					console.log("param[" + key + "] : Valeur " + val + " incorrecte (non Int). Valeur par défaut " + _this.default_config[key] + " chargée à la place.");
 				}
@@ -294,14 +479,17 @@
 		
 		if(_this.config['local'] == 'true')
 		{
-			console.log("Loading local metadata.");
+			// console.log("Loading local metadata.");
 			_this.loadFromJson('./player/json/local_videos.json');
 		}
 		else
 		{
-			console.log("Loading online metadata.");
+			// console.log("Loading online metadata.");
 			_this.loadFromJson('./player/json/online_videos.json');
 		}
+		
+		//On initialise le client.
+		_this.client = new client(_this.config['host'], _this.config['port'], _this);
 	});
 }
 
@@ -313,19 +501,22 @@
 mosaic.prototype.init = function()
 {
 	var _this = this;
-	
+
 	if(this.currentRandomVideoIdx > this.config['imagesToShow'])
 	{
 		this.currentRandomVideoIdx = 0;
 	}
 	
+	
 	this.previousZoomedSN = $('#snapshotDiv-' + this.fillingIds[this.currentRandomVideoIdx]);
 	this.previousId = $('img', this.previousZoomedSN).attr('id');
 	
-	console.log('ids', this.fillingIds[this.currentRandomVideoIdx]);
+	// console.log('CURRENT MODE : ' + _this.currentMode);
+	// console.log('ids', this.fillingIds[this.currentRandomVideoIdx]);
 	
 	this.previousZoomedSN.fadeTo(this.config['timePrezoom'], 1, function()
 	{
+		// console.log('CURRENT MODE : ' + _this.currentMode);
 		_this.zoom();
 		_this.currentRandomVideoIdx++;
 	});
@@ -336,38 +527,68 @@
 */
 mosaic.prototype.showNImages = function(n)
 {
-	if(n > 1)
+	if(this.currentlyMoving)
+	{
+		return;
+	}
+	
+	// console.log('INCOMING ----- ' + n);
+	//Si il y a plus d'un snapshot à afficher, on entre dans le mode INCOMING avec en paramètre le nombre à afficher.
+	if(n > 1 && n < this.config['imagesToShow'])
 	{
 		this.currentMode = "INCOMING-" + n;
 		this.unzoom();
+		this.currentSearchGesture = '';
+		$('.notifications').remove();
+		this.isMosaicFiltered = false;
+		this.isCurrentlyInASearchByGesture = false;
+		$('#mainPointer').fadeTo(this.config['timePrezoom'], 0);
+		$('#secondPointer').fadeTo(this.config['timePrezoom'], 0);
+		$('#spinner').remove();
+		this.deselectAllNeighbours();
+		$('.prezoomContainers').remove();
+	}
+	// console.log('n : ' + n);
+	if(n >= this.config['imagesToShow'])
+	{
+		// this.unzoom();
+		if(this.currentMode == "NO-USER" || this.currentMode.indexOf("INCOMING-") > -1)
+		{
+			this.currentMode = "INCOMING-20";
+			this.unzoom();
+			this.currentMode = "MOSAIC";
+			$('.notifications').remove();
+			this.mosaicSelectionAndSearch();
+			clearTimeout(this.nouserTimeout);
+			console.log('OK');
+		}
+		//On affiche les notifications.
+		// this.notifySelectionSearchMosaicFull();
+	
+		// $('#mainPointer').fadeTo(this.config['timePrezoom'], 1);
+		// $('#secondPointer').fadeTo(this.config['timePrezoom'], 1);
 	}
 	
+	//Pour les snapshots à afficher.
 	for(var i = 0 ; i < n ; i++)
 	{
-		if($('#snapshotDiv-' + i).css('opacity') < 1)
+		//Si les snapshots ne sont pas affichés.
+		if($('#snapshotDiv-' + this.fillingIds[i]).css('opacity') < 1)
 		{
-			$('#snapshotDiv-' + i).fadeTo(this.config['timeFilling'], 1);
+			//On les fait apparaître.
+			$('#snapshotDiv-' + this.fillingIds[i]).fadeTo(this.config['timeFilling'], '1');
 		}
 	}
-}
-
-/*
- * Affiche les pointeurs.
-*/
-mosaic.prototype.addPointers = function()
-{
-	var _this = this;
-	
-	var mainPointer = '<div id="mainPointer" class="pointers"></div>';
-	$('body').append(mainPointer);
-	$('body').mousemove(function(evt)
+	//Pour ceux à masquer.
+	for(var i = n ; i < this.config['imagesToShow'] ; i++)
 	{
-		$('#mainPointer').css(
+		//Si les snapshots ne sont pas masqués et qu'il ne s'agit pas du dernier snapshot en lecture aléatoire (mode NO-USER).
+		if($('#snapshotDiv-' + this.fillingIds[i]).css('opacity') > 0 && this.fillingIds[i] != this.currentRandomVideoIdx)
 		{
-			top: evt.pageY - $('#mainPointer').height()/2,
-			left: evt.pageX - $('#mainPointer').width()/2
-		});
-	});
+			//On les masque.
+			$('#snapshotDiv-' + this.fillingIds[i]).fadeTo(this.config['timeFilling'], '0');
+		}
+	}
 }
 
 /*
@@ -375,9 +596,20 @@
 */
 mosaic.prototype.manageControlEvents = function(event)
 {
-	console.log('manage');
+	// console.log('manage');
+	
+	var _this = this;
+	
+	if(typeof event === 'undefined')
+	{
+		return;
+	}
+	
+	var gestureReceived = '';
+	
 	//Sinon si on a appuyé sur 'g' ou 'G'.
-	if(event.which == 103 || event.which == 71)
+	// if(event.which == 103 || event.which == 71)
+	/*if(event == "CURVES")
 	{
 		//Si on est déjà en recherche par courbes.
 		if(this.currentMode == "SEARCH" || this.currentMode == "FILTER")
@@ -415,7 +647,8 @@
 		}
 	}
 	//Si c'est a ou A.
-	else if(event.which == 65 || event.which == 97)
+	// else if(event.which == 65 || event.which == 97)
+	else if(event == "HELP")
 	{
 		if(!this.helpDisplayed)
 		{
@@ -427,307 +660,218 @@
 		}
 	}
 	//Si c'est v ou V.
-	else if(event.which == 86 || event.which == 118)
+	// else if(event.which == 86 || event.which == 118)
+	else if(event == "NOTIFY-SEARCH")
 	{
 		this.notifySearchMarkers('run;jump;fall');
 	}
 	//Si c'est b ou B.
-	else if(event.which == 66 || event.which == 98)
+	// else if(event.which == 66 || event.which == 98)
+	else if(event == "REMOVE-SEARCH")
 	{
 		this.removeSearchMarkers();
 	}
 	//Si c'est k ou K.
-	else if(event.which == 75 || event.which == 107)
+	// else if(event.which == 75 || event.which == 107)
+	else if(event == "FILTER")
 	{
 		this.searchFilter('circle');
 	}
 	//Si c'est l ou L.
-	else if(event.which == 76 || event.which == 108)
+	// else if(event.which == 76 || event.which == 108)
+	else if(event == "REMOVE-FILTER")
 	{
 		this.removeFilter();
 	}
 	//Si on a appuié sur la touche 'q' ou 'Q';
-	else if(event.which == 113 || event.which == 81)
+	// else if(event.which == 113 || event.which == 81)
+	else if(event == "UNZOOM")
 	{
 		this.unzoom();
-	}
-	else if(event.which == 111 || event.which == 79)
+	}*/
+	// else if(event.which == 111 || event.which == 79)
+	if(event.indexOf("INCOMING-") != -1 && this.prephaseEnabled)
 	{
-		if(this.snapshotsToShow > this.imagesToShow)
+		// console.log(this.date() + ' ' + event);
+		// console.log('CAN START : ' + this.canStart);
+		if(this.canStart)
 		{
-			this.snapshotsToShow = this.imagesToShow;
-		}
-		else
-		{
-			this.snapshotsToShow += 5;
+			if(this.snapshotsToShow > this.config['imagesToShow'])
+			{
+				this.snapshotsToShow = this.config['imagesToShow'];
+			}
+			else
+			{
+				var params = event.split('-');
+				// console.log(event);
+				this.snapshotsToShow = params[1];
+			}
+			
+			//Si la position de l'utilisateur a changé.
+			if(event != this.lastIncomingMessage)
+			{
+				console.log(this.snapshotsToShow);
+				this.lastIncomingMessage = event;
+				this.showNImages(this.snapshotsToShow);
+			}
 		}
 		
-		this.showNImages(this.snapshotsToShow);
+		clearTimeout(this.nouserTimeout);
+		this.nouserTimeout = setTimeout(function()
+		{
+			/*_this.showNImages(0);
+			_this.init();
+			_this.canStart = false;
+			_this.currentMode = "NO-USER";*/
+			
+				window.location.reload();
+			// mos = new mosaic('./config.json', default_parameters);
+			
+			console.log('NOUSER');
+		}, this.config['timeoutNouser']);
 	}
-}
-
-/*
- * Zoom sur la position d'une image, 1ère partie. Durant le laps de temps de time ms, l'utilisateur a le choix de zoomer sur une autre image.
- * Après ce laps de temps, l'image zoom complétement et il n'est plus possible de sélectionner une autre image par pointage.
- */
-mosaic.prototype.preZoom = function(snapshot)
-{
-    if(this.fullscreen)
+	else if((event == "NO-USER" || event == "INCOMING-0" || event == "INCOMING-1") && this.prephaseEnabled)
 	{
-        return;
+		/*this.showNImages(0);
+		this.init();
+		this.canStart = false;
+		this.currentMode = "NO-USER";*/
+		
+			window.location.reload();
+		// mos = new mosaic('./config.json', default_parameters);
+		
+		console.log('NOUSER');
+		
+		/*this.currentMode = "NO-USER";
+		this.showNImages(0);
+		this.canStart = false;
+		this.init();*/
 	}
-	
-	//On enlève les notifications initiales si elles existent.
-	this.removeSelectionSearchMosaicFull();
-	
-    //Mosaïque.
-    var _this = this;
-    //Dimensions de la mosaïque.
-    var h = this.height, w = this.width;
-    //Longueur en images, nombre d'images et taille de bordure de la mosaïque.
-    var len = this.config['length'], imgs = this.config['imagesToShow'], margin = this.marginWidth;
-    //Dimensions et position d'un snapshot dans la mosaïque.
-    var snHeight = this.snapshotHeight, snWidth = this.snapshotWidth;
-    var sTop = snapshot.position().top, sLeft = snapshot.position().left;
-    var prezoomPercentage = this.config['prezoomPercentage'];
-    
-    //ID de l'image actuelle.
-    var currentId = $('img', snapshot).attr('id');
-    
-    //Si un zoom est déjà en cours, on ne zoom sur rien d'autre en attendant que ce snapshot ai dézoomé en cas de mouseleave.
-    if(this.zoomed)
+	// /!\/!\ //
+	else if(event.indexOf("SWIPE") != -1)
 	{
-        if($('#preZoomContainer-' + currentId) != $(this) && this.previousZoomedSN != '' && this.previousId != '')
+		if(this.player && this.player.widgets && this.playerIsReady && !this.isSwipe)
 		{
-            this.preUnzoom();
-		}
-        else
-		{
-            return;
+			this.isSwipe = true;
+			
+			if(this.currentMode == 'SEARCH' && this.isMosaicFiltered && !this.player.widgets[0].isAMarkerAhead(this.currentSearchGesture))
+			{
+				this.playNextVideo();
+			}
+			
+			//L'utilisateur a fait un swipe left.
+			if(event.indexOf("LEFT") != -1)
+			{
+				this.player.widgets[0].switchToMarker(true, this.currentSearchGesture);
+				if(this.currentMode == 'VIDEO')
+				{
+					$('.notifications').remove();
+					this.videoSwipe('left');
+				}
+				else if(this.currentMode == 'SEARCH' && !this.currentSearchGesture)
+				{
+					$('.notifications').remove();
+					this.searchSearchAndSwipe('left');
+				}
+				else if(this.currentMode == 'SEARCH' && this.currentSearchGesture)
+				{
+					$('.notifications').remove();
+					this.searchGestureAndSwipe(this.currentSearchGesture, 'valid', 'left');
+				}
+			}
+			//L'utilisateur a fait un swipe right.
+			else if(event.indexOf("RIGHT") != -1)
+			{
+				this.player.widgets[0].switchToMarker(false, this.currentSearchGesture);
+				if(this.currentMode == 'VIDEO')
+				{
+					$('.notifications').remove();
+					this.videoSwipe('right');
+				}
+				else if(this.currentMode == 'SEARCH' && !this.currentSearchGesture)
+				{
+					$('.notifications').remove();
+					this.searchSearchAndSwipe('right');
+				}
+				else if(this.currentMode == 'SEARCH' && this.currentSearchGesture)
+				{
+					$('.notifications').remove();
+					this.searchGestureAndSwipe(this.currentSearchGesture, 'valid', 'right');
+				}
+			}
+			
+			//On le fait disparaitre au bout d'un certain temps.
+			this.notifySwipeTimeout = setTimeout(function()
+			{
+				_this.isSwipe = false;
+				
+				// /!\ //
+				$('.notifications').remove();
+				
+				if(_this.currentMode == 'SEARCH' && !_this.currentSearchGesture)
+				{
+					_this.searchSearch();
+				}
+				else if(_this.currentMode == 'SEARCH' && _this.currentSearchGesture)
+				{
+					_this.searchGesture(_this.currentSearchGesture, 'valid');
+				}
+				
+			}, this.config['timeoutNotifySwipe']);
 		}
 	}
-    
-    //On indique qu'on a zoomé et on spécifie le snapshot sur lequel on a zoomé.
-    this.zoomed = true;
-    this.previousZoomedSN = snapshot;
-    this.previousId = currentId;
-    
-    //On récupère les attributs de l'image.
-    var fakeImg = $('img', snapshot);
-    //On forme la balise de la fausse image et on passe son url pour les grands snapshots.
-    fakeImg = '<img id="fake-' + currentId + '" class="snapshots" src="' + fakeImg.attr('src').replace('-little/', '/') + '" />';
-    //On génère un faux snapshot identique au précédent et qu'on va coller dessus.
-    var fakeSnapshot = '<div id="prezoomContainer-' + currentId + '" class="prezoomContainers"><div id="prezoomSnapshot-' + currentId + '" class="snapshotDivs">' + fakeImg + '</div></div>';
-    
-    //On l'ajoute à la mosaïque.
-    $('#mainPanel').append(fakeSnapshot);
-    //On modifie ses attributs.
-    $('#fake-' + currentId).load(function()
-    {
-        $('#prezoomContainer-' + currentId).css('display', 'block');
-        $('#prezoomContainer-' + currentId).css('top', sTop).css('left', sLeft).css('width', (snWidth + margin)).css('height', (snHeight + margin));
-        $('#prezoomSnapshot-' + currentId).css('width', (snWidth)).css('height', (snHeight));
-        
-        //Dimensions et coordonnées initiales du div sur lequel on zoom.
-        var initialDivWidth = $('#prezoomContainer-' + currentId).width(), initialDivHeight = $('#prezoomContainer-' + currentId).height();
-        var initialDivTop = $('#prezoomContainer-' + currentId).position().top, initialDivLeft = $('#prezoomContainer-' + currentId).position().left;
-        //Dimensions et coordonnées finales du div.
-        var finalDivWidth = initialDivWidth * (prezoomPercentage+1), diffWidth = finalDivWidth - initialDivWidth, finalDivHeight = initialDivHeight + diffWidth;
-        var finalDivTop = (initialDivTop - (finalDivHeight - snHeight)/2), finalDivLeft = (initialDivLeft - (finalDivWidth - snWidth)/2);
-        
-        //CAS PARTICULIER pour la position du snapshot zoomé : les bordures.
-        if(finalDivTop < 0)
+	else if(event.indexOf("BEND") != -1 || event.indexOf('KNEE-UP') != -1 || event.indexOf('FALL') != -1 || event.indexOf('JUMP') != -1)
+	{
+		gestureReceived = event.toLowerCase();
+		gestureReceived = gestureReceived.replace('wave', 'hello');
+		this.currentSearchGesture = gestureReceived;
+	}
+	else if(event.indexOf("HELLO") != -1 && this.canNotifyHelp && !this.areBothPointersHere)
+	{
+		if(this.currentMode == 'SEARCH')
 		{
-            finalDivTop = -margin;
-		}
-        if(finalDivTop + finalDivHeight > h)
-		{
-            finalDivTop = h - finalDivHeight;
-		}
-        if(finalDivLeft < 0)
-		{
-            finalDivLeft = 0;
-		}
-        if(finalDivLeft + finalDivWidth + margin*2 > w)
-		{
-            finalDivLeft = w - finalDivWidth - margin*2;
+			this.notifyHelp(false);
 		}
-        
-        ////Code de debug.
-        ////CAUTION////
-        /*var red = '<div id="red"></div>';
-        if($('#red') != null || $('#red') != undefined)
-            $('body').append(red);
-        $('#red').css('background-color', '#FF0000').css('position', 'absolute').css('top', '0px').css('left', '0px').css('width', '100px').css('height', '100px');
-        $('#red').css('top', finalDivTop).css('left', finalDivLeft).css('width', finalDivWidth).css('height', finalDivHeight);*/
-        //alert("initial : " + initialDivWidth + " " + initialDivHeight + " ; final : " + finalDivWidth + " " + finalDivHeight);
-        ////CAUTION////
-        
-        //On prézoom le div en le centrant sur le milieu du snapshot pointé.
-        $('#prezoomSnapshot-' + currentId).animate(
-        {
-            width: finalDivWidth + margin,
-            height: finalDivHeight - margin*2,
-            top: finalDivTop + margin,
-            left: finalDivLeft + margin
-        }, _this.config['timePrezoom']);
-        $('#prezoomContainer-' + currentId).animate(
-        {
-            width: finalDivWidth + margin*2,
-            height: finalDivHeight - margin,
-            top: finalDivTop + margin,
-            left: finalDivLeft
-        }, _this.config['timePrezoom'], function()
+		else if(this.currentMode == 'FILTER')
 		{
-			_this.notifyPointMosaicPrezoom();
-		});
-    });
-    
-    //Si on clique sur le snapshot prézoomé, on enclenche un zoom total sur ce snapshot.
-    $('#prezoomContainer-' + currentId).click(function ()
-    {
-        if(this.previousZoomedSN != '')
-		{
-            _this.zoom();
+			this.notifyHelp(true);
 		}
-    });
-}
-
-/*
- * Dézoome sur la position de l'image. Il est à noter que ce dézoome diffère du dézoom global dans la mesure où celui-ci ne concerne que l'image sur laquelle on a zoomé.
- */
-mosaic.prototype.preUnzoom = function()
-{
-    //Si on n'a pas zoomé, on quitte la fonction.
-    if(!this.zoomed)
-	{
-        return;
 	}
 	
-	this.removePointMosaicPrezoom();
-    
-    //On spécifie la marge afin de centrer le prédézoom.
-    var margin = this.marginWidth;
-    //ID du snapshot précédemment pointé.
-    var id = this.previousId;
-    //On ne zoom plus.
-    this.zoomed = false;
-    //On rétrécit le snapshot de prézoom, puis on le supprime en donnant l'illusion qu'il s'agissait du véritable snapshot, alors qu'en fait c'était un clone.
-    $('#prezoomSnapshot-' + id).animate(
-    {
-        width: this.snapshotWidth,
-        height: this.snapshotHeight,
-        top: this.previousZoomedSN.position().top,
-        left: this.previousZoomedSN.position().left
-    }, this.config['preUnzoomTime']);
-    $('#prezoomContainer-' + id).animate(
-    {
-        width: this.snapshotWidth + margin,
-        height: this.snapshotHeight + margin,
-        top: this.previousZoomedSN.position().top,
-        left: this.previousZoomedSN.position().left
-    }, this.config['preUnzoomTime'], function(){ $(this).remove(); this.zoomed = false; });
-}
-
-
-/*
- * Zoom d'un snapshot en plein écran.
- */
-mosaic.prototype.zoom = function()
-{
-    var _this = this;
-    
-    //Si la mosaïque est en pleine écran, pas la peine de zoomer.
-    if(this.currentMode == "VIDEO" || this.currentMode == "SEARCH")
+	if(gestureReceived != '')
 	{
-        return;
-	}
-	
-	this.removePointMosaicPrezoom();
-    
-    //On prend les attributs nécessaires au calculs.
-    var margin = this.marginWidth, len = this.config['length'], imgs = this.config['imagesToShow'], zoomedMargin = this.config['zoomedMargin'];
-	var zoomPercentage = this.config['zoomPercentage'];
-    var initMPWidth = this.previousZoomedSN.width() * len + margin*len, initMPHeight = this.previousZoomedSN.height() * (imgs / len) + margin*(imgs / len);
-    var newMPWidth = initMPWidth * len + zoomedMargin * (len), newMPHeight = initMPHeight * (imgs / len) + zoomedMargin * ((imgs / len));
-    var newPreMPWidth = initMPWidth * len * zoomPercentage + zoomedMargin * (len), newPreMPHeight = initMPHeight * (imgs / len) * zoomPercentage + zoomedMargin * ((imgs / len));
-    
-    //Dimensions et coordonnées initiales du div sur lequel on zoom.
-    var initialDivWidth = this.previousZoomedSN.width(), initialDivHeight = this.previousZoomedSN.height();
-    var initialDivTop = this.previousZoomedSN.position().top, initialDivLeft = this.previousZoomedSN.position().left;
-    //Dimensions et coordonnées finales du div.
-    var finalDivWidth = initialDivWidth * (zoomPercentage+1), finalDivHeight = initialDivHeight * (zoomPercentage+1);
-    var newZoomTop = -this.previousZoomedSN.position().top*(newPreMPHeight/initMPHeight) - zoomedMargin/2 + (initMPHeight - initMPHeight * zoomPercentage)/2, newZoomLeft = -this.previousZoomedSN.position().left*(newPreMPWidth/initMPWidth) - zoomedMargin/2 + (initMPWidth - initMPWidth * zoomPercentage)/2;
-    var newSnWidth = initMPWidth * zoomPercentage, newSnHeight = initMPHeight * zoomPercentage;
-    
-    this.preUnzoom(this);
-    /*SINGULARITE*/
-    this.fullscreen = true;
-    
-    //On passe l'image du snapshot pointé en HD.
-    var zoomedImg = $('img', this.previousZoomedSN);
-    var src = zoomedImg.attr('src');
-    zoomedImg.attr('src', src.replace('-little/', '/'));
-    
-    //On récupère son ID.
-    var tab, zoomedImgId;
-    tab = _this.previousId.split('-');
-    zoomedImgId = tab[1];
-	
-	//On donne les dimensions des snapshots.
-	$('.snapshotDivs').animate(
-	{
-		width: newSnWidth,
-		height: newSnHeight,
-		margin: zoomedMargin/2 + 'px',
-	}, this.config['zoomTime']);
-	
-	if(this.currentMode != 'NO-USER')
-	{
-		//Les snapshots baissent alors en opacité, donnant l'impression qu'ils sont grisés.
-		$('.snapshotDivs').animate(
+		if(this.currentMode == "SEARCH" && this.playerIsReady)
 		{
-			opacity: '0.4'
-		}, this.config['zoomTime']);
-		//Le snapshot du milieu revient à une opacité optimale, ce qui attire l'attention de l'utilisateur.
-		$(this.previousZoomedSN).animate(
+			this.player.widgets[0].searchByGesture(gestureReceived);
+			this.isCurrentlyInASearchByGesture = this.player.widgets[0].isCurrentlyInASearchByGesture;
+			
+			$('.notifications').remove();
+			this.searchGesture(gestureReceived, 'valid');
+		}
+		else if(this.currentMode == "FILTER")
 		{
-			opacity: '1'
-		}, this.config['zoomTime']);
-	}
-	
-    //On zoome sur la mosaïque.
-    $('#mainPanel').animate(
-    {
-        width: newPreMPWidth,
-        height: newPreMPHeight,
-        top: newZoomTop,
-        left: newZoomLeft
-    }, this.config['zoomTime'], function()
-    {
-        //On charge les interactions avec les voisins.
-        _this.centerId = zoomedImgId;
-		
-		if(_this.currentMode != "NO-USER")
-		{
-			_this.currentMode = 'VIDEO';
-			_this.listenToNeighbours();
+			if(this.isMosaicFiltered)
+			{
+				// console.log('FILTER !!!');
+				// this.notifySearch1Gesture(gestureReceived, 'valid');
+				$('.notifications').remove();
+				this.filterGesture(gestureReceived, 'valid');
+				this.searchFilter(gestureReceived);
+			}
 		}
 		
-		_this.snTop = (zoomedImg.position().top + newZoomTop + _this.MPTop_margin), _this.snLeft = (zoomedImg.position().left + newZoomLeft);
-		_this.snWidth = newSnWidth + 1, _this.snHeight = newSnHeight + 1;
-		
-		_this.notifyTopVideo = newZoomTop;
-		_this.notifyLeftVideo = newZoomLeft;
-		
-		_this.loadPlayer(_this.snTop, _this.snLeft, _this.snWidth, _this.snHeight, newZoomTop, newZoomLeft);
-    });
+		if(this.helpDisplayed)
+		{
+			this.removeHelp();
+		}
+	}
+	// /!\/!\ //
 }
 
 /*
  * Chargement du player basé sur le metadataplayer.
 */
-mosaic.prototype.loadPlayer = function(newZoomTop, newZoomLeft, newSnWidth, newSnHeight, zoomTop, zoomLeft)
+mosaic.prototype.loadPlayer = function(newZoomTop, newZoomLeft, newSnWidth, newSnHeight, zoomTop, zoomLeft, timeToGo)
 {
 	var _this = this;
 	
@@ -782,376 +926,112 @@
 	
 	//On démarre le player.
 	this.player = null;
+	
 	this.player = new IriSP.Metadataplayer(_config, _metadata);
 	
-	if(this.currentMode == 'NO-USER')
-	{
-		this.player.onLoad(function()
-		{
-			console.log(_this.player);
-			console.log(_this.player.popcorn);
-			//Lorsque le player est en pause (par exemple lorsque le curseur arrive à la fin de la timeline).
-			if(_this.player.popcorn != undefined)
-			{
-				_this.player.popcorn.listen('pause', function()
-				{
-					_this.unzoom();
-				});
-			}
-		});
-	}
-}
-
-/*
- * Retour à la taille normale de la mosaïque.
- */
-mosaic.prototype.unzoom = function()
-{
-    //Si on n'est pas en plein écran, on quitte.
-	console.log("'" + this.currentMode + "'");
-    if(this.currentMode != "SEARCH" && this.currentMode != "VIDEO" && this.currentMode != "NO-USER" && this.currentMode.indexOf("INCOMING") == -1)
+	this.player.onLoad(function()
 	{
-        return;
-	}
-	
-	this.snTop = 0;
-	this.snLeft = 0;
-	this.Width = 0;
-	this.snHeight = 0;
-    
-    //On charge les attributs nécessaires aux calculs.
-    var sWidth = this.snapshotWidth, sHeight = this.snapshotHeight;
-    var mpWidth = this.width, mpHeight = this.height;
-    var _this = this;
-    
-    //On passe le snapshot sur lequel on a zoomé en SD.
-    var zoomedImg = $('img', this.previousZoomedSN);
-    var src = zoomedImg.attr('src');
-    zoomedImg.attr('src', src.replace('snapshots/', 'snapshots-little/'));
-	
-	_this.player.widgets[0].freePlayer();
-	$('.LdtPlayer').remove();
-	$('body').append('<div class="LdtPlayer" id="LdtPlayer"></div>');
-	_this.reaffectKeyPress();
-    
-    //On rend leur opacité aux snapshots. Qui ne sont alors plus grisés.
-    $('.snapshotDivs').animate(
-    {
-        width: sWidth,
-        height: sHeight,
-        margin: this.marginWidth/2 + 'px'
-    }, this.config['unzoomTime']);
-	
-	if(this.currentMode != 'NO-USER')
-	{
-		if(this.currentMode.indexOf("INCOMING") == -1)
+		if(_this.currentMode == 'NO-USER')
 		{
-			$('.snapshotDivs').animate(
-			{
-				opacity: '1'
-			}, this.config['unzoomTime']);
+			//On peut s'approcher de la kinect.
+			_this.canStart = true;
+			console.log('CAN START !');
+			// console.log(_this.player);
+			// console.log(_this.player.popcorn);
 		}
-	}
-	else
-	{
-		console.log('init');
-		this.previousZoomedSN.fadeTo(this.config['unzoomTime'], 0, function()
+		//Lorsque le player est en pause (par exemple lorsque le curseur arrive à la fin de la timeline).
+		if(_this.player.popcorn)
 		{
-			_this.init();
-		});
-	}
-	
-    //On dézoom sur la mosaïque.
-    $('#mainPanel').animate(
-    {
-        width: mpWidth,
-        height: mpHeight,
-        top: '0px',
-        left: '0px'
-    }, this.config['unzoomTime'], function()
-    {
-        //On n'est plus en plein écran, et on ne peut plus se déplacer vers le prochain voisin.
-        _this.fullscreen = false;
-        _this.canMoveToNeighbour = false;
-		
-		if(_this.currentMode != 'NO-USER')
-		{
-			//On revient en mode MOSAIC.
-			_this.currentMode = 'MOSAIC';
-			//On ne permet plus le déplacement vers les voisins.
-			$('.snapshotDivs').unbind('mouseover', function()
+			_this.player.popcorn.listen('pause', function()
 			{
-				_this.selectNeighbour();
+				//Si l'utilisateur a mis en pause.
+				if(_this.userPaused)
+				{
+				
+				}
+				//Si la pause est naturelle (fin de la timeline, dézoom, déplacement vers un voisin).
+				else
+				{
+					//Si c'est en mode sans utilisateur.
+					if(_this.currentMode == 'NO-USER')
+					{
+						//On dézoome.
+						_this.unzoom();
+					}
+					//Sinon.
+					else
+					{
+						//Si ce n'est pas causé par un déplacement ou un dézoom.
+						if(!_this.currentlyMoving && !_this.currentlyUnzooming)
+						{
+							//On réinitialise la position du curseur à la prochaine lecture de la vidéo.
+							console.log('REINIT');
+							//On passe a la video suivante.
+							console.log('AUTOMOVE');
+							
+							//Si on est en mode timeline et qu'on est en pause, c'est probablement que l'user a placé le curseur à la fin.
+							if(_this.currentMode != 'TIMELINE')
+							{
+								_this.playNextVideo();
+							}
+							//_this.timeToGoAt[parseInt(_this.centerId)] = 0;
+							console.log('time to go at to 0');
+							// return;
+						}
+					}
+				}
 			});
-			//On remet les notifications initiales.
-			_this.notifySelectionSearchMosaicFull();
+			// console.log('mosaic filtered : ' + _this.isMosaicFiltered);
+			
+			_this.player.popcorn.on("markersready", function()
+			{
+				_this.playerIsReady = true;
+				
+				if(_this.currentMode == 'VIDEO' || _this.currentMode == 'SEARCH' || _this.currentMode == 'TIMELINE')
+				{
+					_this.canSwipe = true;
+				}
+				
+				console.log('TIME TO GO AT : ' + _this.timeToGoAt[_this.centerId], _this.centerId, _this.imgs[_this.centerId]);
+				
+				if(_this.isMosaicFiltered)
+				{
+					if(_this.currentSearchGesture == '')
+					{
+						_this.removeFilter();
+					}
+					else
+					{
+						_this.currentMode = 'SEARCH';
+						// console.log(_this.currentSearchGesture);
+						_this.player.widgets[0].searchByGesture(_this.currentSearchGesture);
+						_this.isCurrentlyInASearchByGesture = _this.player.widgets[0].isCurrentlyInASearchByGesture;
+						
+						if(_this.timeToGoAt[_this.centerId] === 0 && _this.player.widgets[0].atLeastOneSearchMarker(_this.currentSearchGesture))
+						{
+							_this.player.widgets[0].goToFirstSearchedMarker(_this.currentSearchGesture);
+						}
+						else
+						{
+							_this.player.popcorn.currentTime(_this.timeToGoAt[_this.centerId]);
+						}
+					}
+				}
+				// /!\ //
+				else
+				{
+					if(_this.player.popcorn)
+					{
+						_this.player.popcorn.currentTime(_this.timeToGoAt[_this.centerId]);
+					}
+				}
+			});
 		}
-    });
-}
-
-/*
- * Affecte les listeners mouseenter aux voisins lors d'une vue en plein écran.
- */
-mosaic.prototype.listenToNeighbours = function()
-{
-    ////TEST
-    //$('.test').empty();
-    var _this = this;
-    
-	this.canMoveToNeighbour = false;
-    var currentLine = Math.floor(this.centerId / this.config['length']), currentColumn = this.centerId % this.config['length'];
-    var zoomedImg = $('img', this.previousZoomedSN);
-    
-    //On cherche l'ID des voisins.
-    //Si le voisin de gauche est sur la même ligne, on n'est pas sur la bordure de gauche.
-    this.neighboursIds[0] = (currentColumn > 0) ? (this.centerId - 1) : -1;
-    //Si le voisin de droite est sur la même ligne, on n'est pas sur la bordure de droite.
-    this.neighboursIds[1] = (currentColumn < this.config['length']) ? (+this.centerId + 1) : -1;
-    //Si le voisin du haut est sur la même colonne, on n'est pas sur la bordure du haut.
-    this.neighboursIds[2] = (currentLine > 0) ? (this.centerId - this.config['length']) : -1;
-    //Si le voisin du bas est sur la même colonne, on n'est pas sur la bordure du bas.
-    this.neighboursIds[3] = (currentLine < (this.config['imagesToShow'] / this.config['length'])) ? (+this.centerId + this.config['length']) : -1;
-    
-	//ID du cadre voisin.
-	var preId;
-	
-    for(var i = 0 ; i < this.neighboursIds.length ; i++)
-    {
-        if(this.neighboursIds[i] != -1)
-        {
-			preId = '#neighbourFrameBorder-' + this.neighboursIds[i];
-            //On permet le déplacement vers les voisins.
-            // $('#snapshotDiv-' + this.neighboursIds[i] + ', ' + preId + '-left,' + preId + '-right,' + preId + '-up,' + preId + '-down').mouseenter(mos.selectNeighbour);
-			
-            $('#snapshotDiv-' + this.neighboursIds[i]).mouseover(function()
-			{
-				_this.selectNeighbour($(this));
-			});
-        }
-    }
+	});
 }
 
 /*
- * Change la coloration d'une bordure où on se positionne lors d'une vue en plein écran.
- */
-mosaic.prototype.selectNeighbour = function(neighbour)
-{
-    ////TEST
-    //$('.test').append(mos.currentMode + " " + $(this).attr('id') + " " + 'snapshotDiv-' + mos.centerId + ',');
-	var _this = this;
-	
-    //Si on est en mode VIDEO (plein écran) ET si le snapshot pointé est un voisin.
-    
-    if((this.currentMode == 'VIDEO') && (neighbour.attr('id') != 'snapshotDiv-' + this.centerId))
-    {
-        //On crée le cadre qui va être superposé au voisin.
-        //On le colle au voisin.
-		var tab = neighbour.attr('id').split('-');
-		var snapshotId = tab[1];
-        var neighbourFrame = '';
-		var marginValue = parseFloat(neighbour.css('margin'));
-		
-		neighbourFrame += '<div class="neighbourFrame" id="neighbourFrame-' + snapshotId + '"><div class="neighbourImgBg" id="neighbourImgBg-' + snapshotId + '"><div class="neighbourImg" id="neighbourImg-' + snapshotId + '"></div></div></div>';
-		
-        $('#mainPanel').append(neighbourFrame);
-		
-		//On positionne le div de background juste au niveau du voisin.
-        $('#neighbourFrame-' + snapshotId).css(
-		{
-			'top': (+neighbour.position().top + marginValue),
-			'left': (+neighbour.position().left + marginValue),
-			'width': neighbour.width(),
-			'height': neighbour.height()
-		});
-		//On positionne le div de background noir juste au niveau de l'image du voisin.
-        $('#neighbourImgBg-' + snapshotId).css(
-		{
-			'top': marginValue,
-			'left': marginValue,
-			'width': neighbour.width() - marginValue*2,
-			'height': neighbour.height() - marginValue*2,
-		});
-		//On met par dessus le div de l'image clonée du voisin.
-		$('#neighbourImg-' + snapshotId).css(
-		{
-			'top': 0,
-			'left': 0,
-			'width': neighbour.width() - marginValue*2,
-			'height': neighbour.height() - marginValue*2,
-			'background-image': 'url("' + $('img', neighbour).attr('src') + '")',
-			'background-size': neighbour.width() + 'px ' + neighbour.height() + 'px',
-			'background-position': -marginValue + 'px ' + -marginValue + 'px',
-			'opacity': '0.4'
-		});
-		
-		var fId = '#neighbourFrame-' + snapshotId;
-		
-		$(fId).animate(
-        {
-            //On le fait apparaître.
-            opacity: '1'
-        }, _this.config['timeNeighbourGlowing'], function()
-        {
-            //On peut désormais se déplacer vers ce voisin.
-            _this.canMoveToNeighbour = true;
-        });
-		//Lorsqu'on quitte un des snapshots (bien entendu le voisin en question), on retire le cadre.
-		//Si on clique sur le voisin ou son cadre, on passe au voisin suivant.
-		$(fId).mouseout(function()
-		{
-			_this.deselectNeighbour($(this))
-		}).click(function()
-		{
-			_this.moveToNeighbour($(this))
-		});
-    }
-}
-
-/*
- * Change la coloration d'une bordure quittée lors d'une vue en plein écran.
- */
-mosaic.prototype.deselectNeighbour = function(neighbour)
-{
-    ////TEST
-    //$('.test').append('un,');
-	
-    //On ne peut plus se déplacer vers les voisins.
-    this.canMoveToNeighbour = false;
-    
-	//On récupère le voisin.
-	var neighbourFrame = neighbour;
-	
-    //Si on est en mode VIDEO.
-    if(this.currentMode == 'VIDEO')
-    {
-        //On le fait disparaître progressivement.
-        neighbourFrame.animate(
-        {
-            opacity: '0'
-        }, this.config['timeNeighbourUnglowing'], function()
-        {
-            //Une fois invisible, on le supprime.
-            neighbourFrame.remove();
-        });
-    }
-}
-
-/*
- * Lors d'une vue en plein écran, on se déplace vers le voisin dont l'id a été spécifié dans la fonction appelante.
- */
-mosaic.prototype.moveToNeighbour = function(neighbour)
-{
-	var _this = this;
-    //Si on ne peut pas se déplacer vers les voisins, on quitte.
-    if(!_this.canMoveToNeighbour)
-	{
-        return;
-	}
-    
-    //On obtient l'ID de destination.
-    var tab = neighbour.attr('id').split('-');
-    var destinationId = tab[1];
-    
-    //On charge les attributs nécessaires aux calculs.
-	var length = _this.config['length'];
-    var MPCurrentTop = $('#mainPanel').position().top, MPCurrentLeft = $('#mainPanel').position().left;
-    var divideCoeffTop = Math.floor(destinationId / length) == 0 ? 1 : Math.floor(destinationId / length);
-    var divideCoeffLeft = destinationId % length == 0 ? 1 : destinationId % length;
-    var neighbourFrameTop = $('#snapshotDiv-' + destinationId).position().top, neighbourFrameLeft = $('#snapshotDiv-' + destinationId).position().left;
-    
-    //On définit pour le déplacement vertical s'il est nécessaire de se déplacer en haut ou en bas.
-    if(_this.previousZoomedSN.position().top > neighbourFrameTop)
-        MPCurrentTop += Math.abs(neighbourFrameTop - _this.previousZoomedSN.position().top);
-    else if(_this.previousZoomedSN.position().top < neighbourFrameTop)
-        MPCurrentTop -= Math.abs(neighbourFrameTop - _this.previousZoomedSN.position().top);
-    //On définit pour le déplacement horizontal s'il est nécessaire de se déplacer à gauche ou à droite.
-    if(_this.previousZoomedSN.position().left > neighbourFrameLeft)
-        MPCurrentLeft += Math.abs(neighbourFrameLeft - _this.previousZoomedSN.position().left);
-    else if(_this.previousZoomedSN.position().left < neighbourFrameLeft)
-        MPCurrentLeft -= Math.abs(neighbourFrameLeft - _this.previousZoomedSN.position().left);
-    
-    //On passe le snapshot de destination en HD.
-    var destinationImg = $('#snapshot-' + destinationId);
-    var destinationImgSrc = destinationImg.attr('src');
-    destinationImg.attr('src', destinationImgSrc.replace('snapshots-little/', 'snapshots/'));
-    
-    //On passe l'ancien snapshot en SD.
-    var currentImgSrc = $('img', _this.previousZoomedSN).attr('src');
-    $('img', _this.previousZoomedSN).attr('src', currentImgSrc.replace('snapshots/', 'snapshots-little/'));
-    
-    //On obtient l'ID du div de coloration du snapshot vers lequel on se déplace afin de le supprimer.
-    var neighbourFrame = neighbour;
-    var tab = neighbourFrame.attr('id').split('-');
-    _this.centerId = tab[1];
-    $(this).css('opacity', '0');
-    neighbourFrame.remove();
-    
-	_this.player.widgets[0].freePlayer();
-	$('.LdtPlayer').remove();
-	$('body').append('<div class="LdtPlayer" id="LdtPlayer"></div>');
-	_this.reaffectKeyPress();
-	
-    //On grise le snapshot qu'on vient de quitter.
-    _this.previousZoomedSN.animate(
-    {
-        opacity: '0.4'
-    });
-    
-    //On se déplace.
-    $('#mainPanel').animate(
-    {
-        top: MPCurrentTop,
-        left: MPCurrentLeft
-    }, _this.config['timeMovingToNeighbour'], function()
-    {
-        //On fait apparaître le snapshot vers lequel on s'est déplacé.
-        $('#snapshotDiv-' + destinationId).animate(
-        {
-            opacity: '1'
-        }, _this.config['zoomTime'], function()
-        {
-            //On recharge les voisins.
-            $('.snapshotDivs').unbind('mouseenter', _this.selectNeighbour);
-            _this.previousZoomedSN = $('#snapshotDiv-' + _this.centerId);
-            _this.listenToNeighbours();
-			
-			_this.notifyTopVideo = MPCurrentTop;
-			_this.notifyLeftVideo = MPCurrentLeft;
-			
-			_this.loadPlayer((destinationImg.position().top + MPCurrentTop + _this.MPTop_margin), (destinationImg.position().left + MPCurrentLeft), destinationImg.width(), destinationImg.height(), MPCurrentTop, MPCurrentLeft);
-        });
-    });
-}
-
-/*
- * Déchargement du contenu de la mosaïque pour le chargement de la mosaïque locale.
- */
-mosaic.prototype.unload = function()
-{
-    //On supprime les event listeners des objets de la mosaïque.
-    $('.snapshotDivs').unbind();
-    $('.snapshots').unbind();
-    $('.prezoomContainers').unbind();
-    //On supprime physiquement les objets.
-    $('#mainPanel').empty();
-}
-
-/*
- * Centre verticalement un snapshot.
- */
-/*function verticalCenterImg(mosaic, img)
-{
-    //On récupère sa hauteur.
-    var image_height = img.height();
-    //Calcule la marge du haut de chaque div pour le centrage.
-    if(mosaic.top_margin == undefined)
-        mosaic.top_margin = (mosaic.snapshotHeight > image_height) ? (mosaic.snapshotHeight - image_height)/2 : (image_height - mosaic.snapshotHeight)/2;
-    //On centre le snapshot.
-    img.css('margin-top', mosaic.top_margin).css('margin-bottom', mosaic.top_margin);
-}*/
-
-/*
- * Permet de tester l'égalité des éléments de deux objets.
+ * Permet de tester l'égalité des éléments de deux objets.
  * Pour ce faire on compare les éléments définissant ces objets.
  */
 $.fn.equals = function(compareTo)
@@ -1189,21 +1069,23 @@
 					if(_this.config['local'] == 'true')
 					{
 						_this.affectVideoById(val_video.metadata, meta.medias[0].url.replace('rtmp://media.iri.centrepompidou.fr/ddc_player/', './player/videos/').replace('mp4:', '').replace('video/', '').replace('ldtplatform/', '').replace('.m4v', '.mp4'));
-						console.log(meta.medias[0].url.replace('rtmp://media.iri.centrepompidou.fr/ddc_player/', './player/videos/').replace('mp4:', '').replace('video/', '').replace('ldtplatform/', '').replace('.m4v', '.mp4'));
+						// console.log(meta.medias[0].url.replace('rtmp://media.iri.centrepompidou.fr/ddc_player/', './player/videos/').replace('mp4:', '').replace('video/', '').replace('ldtplatform/', '').replace('.m4v', '.mp4'));
 					}
 					else
 					{
 						_this.affectVideoById(val_video.metadata, meta.medias[0].url.replace('rtmp://', 'http://').replace('/ddc_player/', '/').replace('mp4:', '').replace('.m4v', '.mp4'));
-						console.log(meta.medias[0].url.replace('rtmp://', 'http://').replace('/ddc_player/', '/').replace('mp4:', '').replace('.m4v', '.mp4'));
+						// console.log(meta.medias[0].url.replace('rtmp://', 'http://').replace('/ddc_player/', '/').replace('mp4:', '').replace('.m4v', '.mp4'));
 					}
 				});
 				_this.imgs[_this.ids[i]] = val_video.snapshot;
 				_this.urls[_this.ids[i]] = val_video.metadata;
-				console.log('ids : ' + _this.ids[i]);
+				//Au départ, on commence à 0 ms dans les vidéos.
+				_this.timeToGoAt[_this.ids[i]] = 0;
+				// console.log('ids : ' + _this.ids[i]);
 				i++;
 			});
 		});
-		console.log('rdy');
+		// console.log('rdy');
 		_this.loadMosaic();
 	});
 }
@@ -1224,476 +1106,6 @@
 }
 
 /*
- * Lance une recherche par courbes.
- */
-mosaic.prototype.startSearch = function()
-{
-	var top, left, width, height, margin_top, inMosaic;
-	//Si on est dans le cas d'un filtrage de mosaïque.
-	if(this.currentMode == "FILTER")
-	{
-		var mainPanel = $('#mainPanel');
-		top = mainPanel.position().top;
-		left = mainPanel.position().left;
-		width = mainPanel.width();
-		height = mainPanel.height();
-		margin_top = this.MPTop_margin;
-		inMosaic = true;
-	}
-	//Sinon si c'est une recherche dans la vidéo.
-	else if(this.currentMode == "SEARCH")
-	{
-		top = this.snTop;
-		left = this.snLeft;
-		width = this.snWidth;
-		height = this.snHeight;
-		margin_top = '0px';
-		inMosaic = false;
-	}
-	
-	this.searchCanvas = new searchCanvas(top, left, width, height, margin_top, this.timeSearchFade, inMosaic);
-	this.searchCanvas.create();
-}
-
-/*
- * Quitte une recherche par courbes.
- */
-mosaic.prototype.leaveSearch = function()
-{
-	this.searchCanvas.leaveSearch();
-}
-
-/* ===============================================
- *												   *
- *		      ZONE DES NOTIFICATIONS			   *
- *												   *
-   =============================================== */
-
-/*
- * Affiche la notification de sélection/recherche lorsque la mosaique est complète.
-*/
-mosaic.prototype.notifySelectionSearchMosaicFull = function()
-{
-	if(this.currentMode == "NO-USER" || this.currentMode.indexOf("INCOMING") == -1)
-	{
-		return;
-	}
-	
-	//On spécifie les notifications en div.
-	var notification_selection = "<div id='notify_selection' class='notifications'></div>";
-	var notification_search = "<div id='notify_search' class='notifications'></div>";
-	
-	//On les ajoute à la mosaïque.
-	$('#mainPanel').append(notification_selection + notification_search);
-
-	//On calcule leurs coordonnées et dimensions.
-	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-	var notify_margin = parseInt($('.notifications').css('margin'));
-	var selection_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
-	var search_left = selection_left + notify_width + notify_margin;
-	
-	//On les positionne.
-	$('#notify_selection').css(
-	{
-		left: selection_left
-	});
-	$('#notify_search').css(
-	{
-		left: search_left
-	});
-	
-	//On les fait apparaître.
-	$('.notifications').css(
-	{
-		opacity: "0.9"
-	});
-}
-
-/*
- * Supprime la notification de sélection/recherche lorsque la mosaique est complète.
-*/
-mosaic.prototype.removeSelectionSearchMosaicFull = function()
-{
-	$('#notify_selection, #notify_search').remove();
-}
-
-/*
- * Affiche la notification de maintient du pointage lors d'une phase de prézoom.
-*/
-mosaic.prototype.notifyPointMosaicPrezoom = function()
-{
-	if($('#notify_point').length > 0 || this.currentMode == "NO-USER" || this.currentMode.indexOf("INCOMING") == -1)
-	{
-		return;
-	}
-	
-	//On spécifie les notifications en div.
-	var notification_point = "<div id='notify_point' class='notifications'></div>";
-	
-	//On les ajoute à la mosaïque.
-	$('#mainPanel').append(notification_point);
-	
-	//On calcule leurs coordonnées et dimensions.
-	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
-	var notify_margin = parseInt($('.notifications').css('margin'));
-	var point_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
-	
-	//On les positionne.
-	$('#notify_point').css(
-	{
-		left: point_left
-	});
-	
-	//On les fait apparaître.
-	$('.notifications').css(
-	{
-		opacity: "0.9"
-	});
-}
-
-/*
- * Supprime la notification de maintient du pointage.
-*/
-mosaic.prototype.removePointMosaicPrezoom = function()
-{	
-	$('#notify_point').remove();
-}
-
-/*
- * Affiche l'aide.
-*/
-mosaic.prototype.notifyHelp = function()
-{
-	if(this.helpDisplayed)
-	{
-		return;
-	}
-	
-	this.removeSelectionSearchMosaicFull();
-	this.removePointMosaicPrezoom();
-	
-	this.helpDisplayed = true;
-	
-	var search_2hands_tab = ['no_motion', 'right_angle', 'contact', 'grand_jete', 'circle', 'screw', 'arc', 'rythme', 'slow', 'up_down', 'wave', 'wheel'];
-	var search_body_tab = ['bend', 'fall', 'jump', 'hello', 'knee_up'];
-	var controls_1hand_tab = ['selection'];
-	
-	//On spécifie les notifications en div.
-	var search_title = "<div id='search_title'></div>";
-	var search_img = "<div id='search_img' class='notify_imgs'></div>";
-	var search_2hands_text = "<div id='search_2hands_text'></div>";
-	var search_2hands_imgs = "<div id='search_2hands_imgs' class='notify_imgs_big'>";
-	
-	for(var i = 0 ; i < search_2hands_tab.length ; i++)
-	{
-		search_2hands_imgs += "<div id='2hands_" + search_2hands_tab[i] + "' class='notify_imgs_small'></div>";
-	}
-	search_2hands_imgs += "</div>";
-	
-	var search_body_text = "<div id='search_body_text'></div>";
-	var search_body_imgs = "<div id='search_2hands_imgs' class='notify_imgs'>"
-	
-	for(var i = 0 ; i < search_body_tab.length ; i++)
-	{
-		search_body_imgs += "<div id='body_" + search_body_tab[i] + "' class='notify_imgs_small'></div>";
-	}
-	search_body_imgs += "</div>";
-	
-	var controls_title = "<div id='controls_title'></div>";
-	var controls_img = "<div id='controls_img' class='notify_imgs'></div>";
-	var controls_1hand_text = "<div id='controls_1hand_text'></div>";
-	var controls_1hand_imgs = "<div id='controls_1hand_imgs' class='notify_imgs'>";
-	
-	for(var i = 0 ; i < controls_1hand_tab.length ; i++)
-	{
-		controls_1hand_imgs += "<div id='1hand_" + controls_1hand_tab[i] + "' class='notify_imgs_small'></div>";
-	}
-	controls_1hand_imgs += "</div>";
-	
-	var help_search = "<div id='help_search'>" + search_title + search_img + search_2hands_text + search_2hands_imgs + search_body_text + search_body_imgs + "</div>";
-	var help_controls = "<div id='help_controls'>" + controls_title + controls_img + controls_1hand_text + controls_1hand_imgs + "</div>";
-	
-	var notification_help = "<div id='notify_help'>" + help_search + "<div id='help_sep'></div>" + help_controls + "</div>";
-	
-	//On les ajoute à la mosaïque.
-	$('body').append(notification_help);
-	
-	//On calcule leurs coordonnées et dimensions.
-	var notify_width = $(window).width(), notify_height = $(window).height();
-	var notify_margin = parseInt($('#notify_help').css('margin'));
-	var notify_ = 10;
-	
-	//On les positionne.
-	$('#notify_help').css(
-	{
-		left: "0px",
-		top: "0px",
-		width: notify_width - notify_margin * 2,
-		height: notify_height - notify_margin * 2
-	});
-	
-	var search_width = $('#help_search').width();
-	
-	$('#search_title').html('Recherche');
-	$('#search_2hands_text').html('Gestes à effectuer avec les deux mains');
-	$('#search_body_text').html('Gestes à effectuer avec le corps entier');
-	
-	for(var i = 0 ; i < search_2hands_tab.length ; i++)
-	{
-		$("#2hands_" + search_2hands_tab[i]).css("background-image", "url('./pictos/help/" + search_2hands_tab[i] + ".png')");
-		//console.log("url('../../pictos/help/" + search_2hands_tab[i] + ".png')");
-	}
-	
-	for(var i = 0 ; i < search_body_tab.length ; i++)
-	{
-		$("#body_" + search_body_tab[i]).css("background-image", "url('./pictos/help/" + search_body_tab[i] + ".png')");
-		//console.log("url('../../pictos/help/" + search_2hands_tab[i] + ".png')");
-	}
-	
-	$('#controls_title').html('Contrôles');
-	$('#controls_1hand_text').html('Gestes à effectuer avec une seule main');
-	
-	for(var i = 0 ; i < controls_1hand_tab.length ; i++)
-	{
-		$("#1hand_" + controls_1hand_tab[i]).css("background-image", "url('./pictos/help/" + controls_1hand_tab[i] + ".png')");
-		//console.log("url('../../pictos/help/" + search_2hands_tab[i] + ".png')");
-	}
-	
-	//On les fait apparaître.
-	$('#notify_help').css(
-	{
-		opacity: "1"
-	});
-	
-	$('.notify_imgs_big').css(
-	{
-		opacity: "1"
-	});
-}
-
-/*
- * Supprime l'aide.
-*/
-mosaic.prototype.removeHelp = function()
-{
-	if(!this.helpDisplayed)
-	{
-		return;
-	}
-	
-	var _this = this;
-	
-	$('#notify_help').fadeOut(this.timeNotifyFade, function()
-	{
-		_this.helpDisplayed = false;
-		$('#notify_help').remove();
-	});
-}
-
-/*
- * Affiche les types de marqueurs correspondants à ce qu'on a commencé à tracer lors d'une recherche.
-*/
- mosaic.prototype.notifySearchMarkers = function(markersStr)
-{
-	if($('.notifications_inSearch_container').length > 0)
-	{
-		return;
-	}
-	
-	console.log(markersStr);
-	
-	var markersList = markersStr.split(new RegExp(';'));
-	
-	var notification_search_markers = "<div class='notifications_inSearch_container'>";
-	
-	//On spécifie les notifications en div.
-	for(var i = 0 ; i < markersList.length ; i++)
-	{
-		notification_search_markers += "<div class='notifications_inSearch' style='background-image: url(./pictos/big/normal/" + markersList[i] + ".png);'></div>";
-	}
-	
-	notification_search_markers += "</div>";
-	
-	//On les ajoute à la mosaïque.
-	$('#mainPanel').append(notification_search_markers);
-	
-	//On calcule leurs coordonnées et dimensions.
-	var notify_width = $('.notifications_inSearch_container').width(), notify_height = $('.notifications_inSearch_container').height();
-	var notify_margin = parseInt($('.notifications_inSearch').css('margin'));
-	var point_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
-	var point_top = 0;
-	
-	if(this.currentMode == "VIDEO" || this.currentMode == "SEARCH")
-	{
-		point_top = -this.notifyTopVideo,
-		point_left = -this.notifyLeftVideo + ($(window).width() - notify_width) / 2
-	}
-	
-	//On les positionne.
-	$('.notifications_inSearch_container').css(
-	{
-		left: point_left,
-		top: point_top
-	});
-	
-	//On les fait apparaître.
-	$('.notifications_inSearch').css(
-	{
-		opacity: "0.9"
-	});
-}
-
-/*
- * Supprime la notification de maintient du pointage.
-*/
-mosaic.prototype.removeSearchMarkers = function()
-{	
-	$('.notifications_inSearch_container').remove();
-}
-
-/*
- * Effectuer un filtrage de la mosaïque par rapport à un type de marqueurs.
-*/
-mosaic.prototype.searchFilter = function(type)
-{
-	var _this = this;
-	
-	if(this.currentMode == "MOSAIC")
-	{
-		this.currentMode = "FILTER";
-		
-		if(this.annotations.length > 0)
-		{
-			var gestureNumberByVideo = new Object();
-			var maxAnnotationNumber = 0;
-			// for(var i = 0 ; i < this.config['imagesToShow'] ; i++)
-			for(var i = 0 ; i < this.annotations.length ; i++)
-			{
-				var current = this.annotations[i];
-				if(current.annotationType.contents.title == type)
-				{
-					if(gestureNumberByVideo[current.source.url] == undefined || gestureNumberByVideo[current.source.url] == '')
-					{
-						gestureNumberByVideo[current.source.url] = 0;
-					}
-					
-					gestureNumberByVideo[current.source.url]++;
-				}
-			}
-			
-			for(var i = 0 ; i < this.urls.length ; i++)
-			{
-				if(gestureNumberByVideo[this.urls[i]] == undefined || gestureNumberByVideo[this.urls[i]] == '')
-				{
-					gestureNumberByVideo[this.urls[i]] = 0;
-				}
-			}
-			
-			//On récupère la vidéo qui score le nombre d'occurences de la gesture le plus haut.
-			for(i in gestureNumberByVideo)
-			{	
-				// console.log(i + " " + gestureNumberByVideo[i]);
-				if(maxAnnotationNumber < gestureNumberByVideo[i])
-				{
-					maxAnnotationNumber = gestureNumberByVideo[i];
-				}
-			}
-			
-			var snMargin = parseInt($('.snapshotDivs').css('margin'));
-			
-			//On affiche l'opacité résultante pour chaque vidéo.
-			for(i in gestureNumberByVideo)
-			{
-				//Opacité conventionelle.
-				var opacity = gestureNumberByVideo[i] / maxAnnotationNumber;
-				// console.log('opacity b : ' + opacity + ' for ' + gestureNumberByVideo[i]);
-				//Ce qui est à zéro le restera (par conséquent le snapshot associé sera invisible).
-				if(opacity > 0)
-				{
-					//On réhausse l'opacité de 50%.
-					opacity = this.scaleIntervals(0., 1., 0.5, 1., opacity);
-				}
-				
-				var filterIndex = this.getIdxFromMetadata(i);
-				
-				if(filterIndex >= 0)
-				{
-					console.log('#snapshotDiv-' + filterIndex + " " + _this.config['timeFilterFade'] + " " + opacity);
-					$('#snapshotDiv-' + filterIndex).fadeTo(_this.config['timeFilterFade'], opacity);
-					
-					if(opacity == 0)
-					{
-						var filteredSnapshot = $('#snapshotDiv-' + filterIndex);
-						
-						if(filteredSnapshot.length > 0)
-						{
-							var hider = '<div id="filterHider-' + filterIndex + '" class="filterHiders"></div>';
-							$('#mainPanel').append(hider);
-							
-							$('#filterHider-' + filterIndex).css(
-							{
-								width: +filteredSnapshot.width() + 4 * snMargin,
-								height: +filteredSnapshot.height() + 4 * snMargin,
-								top: filteredSnapshot.position().top - snMargin,
-								left: filteredSnapshot.position().left - snMargin
-							});
-						}
-					}
-				}
-			}
-		}
-	}
-}
-
-/*
- * Passe une valeur de l'intervalle [A, B] à l'intervalle [C, D].
-*/
-mosaic.prototype.scaleIntervals = function(A, B, C, D, val)
-{
-	return (D - C + A) * val + (C - A);
-}
-
-/*
- * Retourne l'index d'un snapshot en fonction de ses metadonnées.
-*/
-mosaic.prototype.getIdxFromMetadata = function(metadata)
-{
-	var _this = this;
-	
-	for(idx in this.urls)
-	{
-		if(this.urls[idx] == metadata)
-		{
-			for(id in this.ids)
-			{
-				if(this.ids[id] == idx)
-				{
-					return id;
-				}
-			}
-		}
-	}
-	
-	return -1;
-}
-
-/*
- * Enlève une recherche par filtre.
-*/
-mosaic.prototype.removeFilter = function()
-{
-	if(this.currentMode == "FILTER")
-	{
-		this.currentMode = "MOSAIC";
-		
-		var _this = this;
-		
-		$('.filterHiders').remove();
-		$('.snapshotDivs').fadeTo(_this.config['timeFilterFade'], 1);
-	}
-}
-
-/*
  * Rebind keypress pour body.
 */
 mosaic.prototype.reaffectKeyPress = function()
@@ -1704,4 +1116,20 @@
 	{
 		_this.manageControlEvents(event);
 	});
-}
\ No newline at end of file
+}
+
+mosaic.prototype.date = function()
+{
+   var date, h, min, s;
+   date = new Date();
+   h = date.getHours();
+   min = date.getMinutes();
+   s = date.getSeconds();
+   if (h < 10)
+      h = "0" + h;
+   if (min < 10)
+      min = "0" + min;
+   if (s < 10)
+      s = "0" + s;
+   return (h + ":" + min + ":" + s);
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/front_idill/src/mosaic/js/neighbours.js	Fri Jun 29 16:16:24 2012 +0200
@@ -0,0 +1,674 @@
+/*
+ * Affecte les listeners mouseenter aux voisins lors d'une vue en plein écran.
+ */
+mosaic.prototype.listenToNeighbours = function()
+{
+    ////TEST
+    //$('.test').empty();
+	console.log('LISTEN TO NEIGHBOURS');
+	$('.notifications').remove();
+	
+	if(this.currentMode == "NO-USER" || this.currentMode.indexOf("INCOMING") != -1)
+	{
+		return;
+	}
+	
+	// console.log('MODE : ' + this.currentMode);
+	
+	if(this.neighboursIds == null || this.neighboursIds != null && this.neighboursIds.length > 0)
+	{
+		return;
+	}
+	
+    var _this = this;
+    
+	this.canMoveToNeighbour = false;
+    var currentLine = Math.floor(this.centerId / this.config['length']), currentColumn = this.centerId % this.config['length'];
+    var zoomedImg = $('img', this.previousZoomedSN);
+	
+    //On cherche l'ID des voisins.
+    //Si le voisin de gauche est sur la même ligne, on n'est pas sur la bordure de gauche.
+    this.neighboursIds[0] = (currentColumn > 0) ? (this.centerId - 1) : -1;
+    //Si le voisin de droite est sur la même ligne, on n'est pas sur la bordure de droite.
+    this.neighboursIds[1] = (currentColumn < this.config['length'] - 1) ? (+this.centerId + 1) : -1;
+    //Si le voisin du haut est sur la même colonne, on n'est pas sur la bordure du haut.
+    this.neighboursIds[2] = (currentLine > 0) ? (this.centerId - this.config['length']) : -1;
+    //Si le voisin du bas est sur la même colonne, on n'est pas sur la bordure du bas.
+    this.neighboursIds[3] = (currentLine < (this.config['imagesToShow'] / this.config['length'])) ? (+this.centerId + this.config['length']) : -1;
+    
+	//ID du cadre voisin.
+	var preId;
+	
+    for(var i = 0 ; i < this.neighboursIds.length ; i++)
+    {
+		// console.log('pre : ' + this.neighboursIds[i]);
+		if(this.neighboursIds[i] >= this.config['imagesToShow'])
+		{
+			this.neighboursIds[i] = -1;
+		}
+    }
+	
+	// console.log('neighbours : ', this.neighboursIds);
+	
+	//Si on est sur une bordure.
+	//On crée des voisins supplémentaires.
+	if(_.include(this.neighboursIds, -1))
+	{
+		this.createAdditionalNeighbours();
+	}
+}
+
+/*
+ * Crée des voisins supplémentaires pour garantir le déplacement / dézoom quand on arrive sur le bord de la mosaïque.
+*/
+mosaic.prototype.createAdditionalNeighbours = function()
+{
+	if(this.currentMode == "NO-USER")
+	{
+		return;
+	}
+	
+	// console.log('Create additional neighbours');
+	
+	var additionalNeighbours = '';
+	for(var i = 0 ; i < this.neighboursIds.length ; i++)
+	{
+		var sn = $('#snapshotDiv-' + this.centerId);
+		var m = parseInt(sn.css('margin'));
+		var centerTop = sn.position().top + this.notifyTopVideo + this.MPTop_margin, centerLeft = sn.position().left + this.notifyLeftVideo;
+		var centerWidth = sn.width(), centerHeight = sn.height();
+		
+		// console.log('top : ' + sn.position().top + ', left : ' + this.notifyTopVideo + ' ' + this.notifyLeftVideo + ' ' + this.centerId);
+		// console.log(this.neighboursIds[i]);
+		
+		var top, left;
+				
+		if(this.neighboursIds[i] == -1)
+		{
+			if(i == 0)
+			{
+				top = centerTop + m / 2;
+				left = centerLeft - centerWidth - 2 * m;
+			}
+			else if(i == 1)
+			{
+				top = centerTop + m / 2;
+				left = centerLeft + centerWidth + 3 * m;
+			}
+			else if(i == 2)
+			{
+				top = centerTop - centerHeight - 2 * m;
+				left = centerLeft + m / 2;
+			}
+			else if(i == 3)
+			{
+				top = centerTop + centerHeight + 3 * m;
+				left = centerLeft + m / 2;
+			}
+			
+			additionalNeighbours += '<div id="borderNeighbour-' + i + '" class="borderNeighbours" style="opacity: 0; width: ' + centerWidth + 'px; height: ' + centerHeight + 'px; top: ' + top + 'px; left: ' + left + 'px;"></div>';
+		}
+	}
+	// console.log(additionalNeighbours);
+	$('body').append(additionalNeighbours);
+	
+	$('.borderNeighbours').fadeTo(this.config['timeANFade'], '1');
+}
+
+/*
+ * Supprime les voisins supplémentaires.
+*/
+mosaic.prototype.removeAdditionalNeighbours = function()
+{
+	$('.borderNeighbours').fadeTo(this.config['timeANFade'], '0', function()
+	{
+		$('.borderNeighbours').remove();
+	});
+	this.deselectAllNeighbours();
+}
+
+/*
+ * Déselectionne tous les voisins, même les additionnels.
+*/
+mosaic.prototype.deselectAllNeighbours = function()
+{
+	$('.neighbourFrame').fadeTo(this.config['timeANFade'], '0', function()
+	{
+		$('.neighbourFrame').remove();
+	});
+}
+
+/*
+ * Change la coloration d'une bordure où on se positionne lors d'une vue en plein écran.
+ */
+mosaic.prototype.selectNeighbour = function(neighbour, pointer)
+{
+    ////TEST
+    //$('.test').append(mos.currentMode + " " + $(this).attr('id') + " " + 'snapshotDiv-' + mos.centerId + ',');
+	
+	// console.log(this.currentlyMoving, this.currentlyUnzooming, this.helpDisplayed);
+	
+	if(this.currentlyMoving || this.currentlyUnzooming || this.helpDisplayed)
+	{
+		return;
+	}
+
+	// console.log('test (2)');
+	
+	this.canSwipe = false;
+	
+	var _this = this;
+	
+	// console.log('SEL NEI', this.neighbourIds);
+	
+    //Si on est en mode VIDEO (plein écran) ET si le snapshot pointé est un voisin.
+
+	// console.log('test (3)');
+    
+    if((this.currentMode == 'VIDEO' || this.currentMode == 'SEARCH') && (neighbour.attr('id') != 'snapshotDiv-' + this.centerId))
+    {
+        //On crée le cadre qui va être superposé au voisin.
+        //On le colle au voisin.
+		var tab = neighbour.attr('id').split('-');
+		var snapshotId = tab[1];
+        var neighbourFrame = '';
+		var marginValue = parseFloat(neighbour.css('margin'));
+		
+		//Si la frame existe déjà, on quitte.
+		if($('#neighbourFrame-' + snapshotId).length > 0)
+		{
+			return;
+		}
+		
+		//Si c'est un voisin additionnel.
+		if(neighbour.attr('id').indexOf('borderNeighbour') != -1)
+		{
+			snapshotId = +snapshotId + this.config['imagesToShow'];
+			neighbourFrame += '<div class="neighbourFrame" id="neighbourFrame-' + snapshotId + '"></div>';
+			if($('#neighbourFrame-' + snapshotId).length > 0)
+			{
+				return;
+			}
+			$('body').append(neighbourFrame);
+		}
+		else
+		{
+			neighbourFrame += '<div class="neighbourFrame" id="neighbourFrame-' + snapshotId + '"><div class="neighbourImgBg" id="neighbourImgBg-' + snapshotId + '"><div class="neighbourImg" id="neighbourImg-' + snapshotId + '"></div></div></div>';
+			if($('#neighbourFrame-' + snapshotId).length > 0)
+			{
+				return;
+			}
+			$('#mainPanel').append(neighbourFrame);
+		}
+		
+		//On positionne le div de background juste au niveau du voisin.
+        $('#neighbourFrame-' + snapshotId).css(
+		{
+			'top': (+neighbour.position().top + marginValue),
+			'left': (+neighbour.position().left + marginValue),
+			'width': neighbour.width(),
+			'height': neighbour.height()
+		});
+		//On positionne le div de background noir juste au niveau de l'image du voisin.
+        $('#neighbourImgBg-' + snapshotId).css(
+		{
+			'top': marginValue,
+			'left': marginValue,
+			'width': neighbour.width() - marginValue*2,
+			'height': neighbour.height() - marginValue*2,
+		});
+		//On met par dessus le div de l'image clonée du voisin.
+		$('#neighbourImg-' + snapshotId).css(
+		{
+			'top': 0,
+			'left': 0,
+			'width': neighbour.width() - marginValue*2,
+			'height': neighbour.height() - marginValue*2,
+			'background-image': 'url("' + $('img', neighbour).attr('src') + '")',
+			'background-size': neighbour.width() + 'px ' + neighbour.height() + 'px',
+			'background-position': -marginValue + 'px ' + -marginValue + 'px',
+			'opacity': '0.4'
+		});
+		
+		var fId = '#neighbourFrame-' + snapshotId;
+		
+		$(fId).animate(
+        {
+            //On le fait apparaître.
+            opacity: '1'
+        }, _this.config['timeNeighbourGlowing'], function()
+		{
+			console.log('SWAG !!!', _this.currentMode, _this.currentSearchGesture);
+			if(_this.currentMode == 'VIDEO')
+			{
+				$('.notifications').remove();
+				_this.videoMoveAndUnzoom(snapshotId);
+			}
+			else if(_this.currentMode == 'SEARCH' && !_this.currentSearchGesture)
+			{
+				$('.notifications').remove();
+				_this.searchSearchAndMoveAndUnzoom(snapshotId);
+			}
+			else if(_this.currentMode == 'SEARCH' && _this.currentSearchGesture)
+			{
+				$('.notifications').remove();
+				console.log('swag');
+				_this.searchGestureAndMoveAndUnzoom(_this.currentSearchGesture, 'valid', snapshotId);
+			}
+		});
+		
+		var side = $.inArray(parseInt(snapshotId), this.neighboursIds);
+		
+		if(side == -1)
+		{
+			return;
+		}
+		
+		var sides = ['left', 'right', 'down', 'up'];
+		pointer.css('background-image', 'url(./img/cursors/' + sides[side] + '_gray.png)');
+    }
+}
+
+
+
+/*
+ * Change la coloration d'une bordure quittée lors d'une vue en plein écran.
+ */
+mosaic.prototype.deselectNeighbour = function(neighbourId)
+{
+    ////TEST
+    //$('.test').append('un,');
+	
+	//this.removeNotifyMoveUnzoom();
+	
+	if($('#neighbourFrame-' + neighbourId).length <= 0)
+	{
+		return;
+	}
+	
+	var _this = this;
+	
+	// console.log('DES');
+	
+    //On ne peut plus se déplacer vers les voisins.
+    this.canMoveToNeighbour = true;
+    
+	//On récupère le voisin.
+	var neighbourFrame = $('#neighbourFrame-' + neighbourId);
+	
+    //Si on est en mode VIDEO.
+    if(this.currentMode == 'VIDEO' || this.currentMode == 'SEARCH')
+    {
+        //On le fait disparaître progressivement.
+        neighbourFrame.animate(
+        {
+            opacity: '0'
+        }, this.config['timeNeighbourUnglowing'], function()
+        {
+            //Une fois invisible, on le supprime.
+            neighbourFrame.remove();
+			$('.notifications').remove();
+			
+			if(_this.currentMode == 'SEARCH' && !_this.currentSearchGesture)
+			{
+				_this.searchSearch();
+			}
+			else if(_this.currentMode == 'SEARCH' && _this.currentSearchGesture)
+			{
+				_this.searchGesture(_this.currentSearchGesture, 'valid');
+			}
+			
+			_this.canSwipe = true;
+        });
+    }
+}
+
+/*
+ * Permet de savoir si un déplacement est possible en fonction de l'id de snapshot entré.
+ * x et y sont les positions du pointeur.
+ * Déplace vers le voisin si possible.
+*/
+mosaic.prototype.correctMoveToNeighbour = function(id, x, y)
+{
+	var _this = this;
+	
+	if(this.neighboursIds != null && this.neighboursIds.length > 0 && this.canMoveToNeighbour)
+	{
+		var idx = $.inArray(id, this.neighboursIds);
+		//Si l'id du snapshot qu'on vient de quitter fait partie des voisins.
+		if(idx > -1)
+		{
+			//Correspondance indices : position par rapport au snapshot du milieu.
+			//0 : gauche.
+			//1 : droite.
+			//2 : haut.
+			//3 : bas.
+			
+			//On cherche le symétrique de l'id du voisin quitté.
+			//Astuce : S'il est pair, cela signifie qu'on doit faire +1, sinon c'est -1.
+			//var sym = (idx % 2 == 0) ? (+idx + 1) : (idx - 1);
+			
+			//S'il est > -1 alors forcément il existe.
+			//Si on peut se déplacer vers un voisin, on le fait.
+			if(this.neighboursIds[idx] > -1)
+			{
+				var centerWidth = -this.notifyLeftVideo + $(window).width() / 2, centerHeight = -this.notifyTopVideo + $(window).height() / 2;
+				
+				// console.log('x : ' + x + ' cw : ' + centerWidth + ', y : ' + y + ' ch : ' + centerHeight);
+				
+				//Si l'id du tableau est pair, alors forcément le pointeur doit être plus à droite/plus en bas que le milieu de l'écran pour se déplacer vers le voisin.
+				//Sinon c'est l'inverse.
+				//(sym et idx on été échangés).
+				if(idx == 0 && x > centerWidth || idx == 2 && y > centerHeight || idx == 1 && x < centerWidth || idx == 3 && y < centerHeight)
+				{
+					// console.log('d to (' + idx + ' - ' + this.neighboursIds[idx] + '): ' + this.imgs[this.neighboursIds[idx]]);
+					
+					this.moveToNeighbour($('#snapshotDiv-' + this.neighboursIds[idx]));
+				}
+			}
+		}
+		else if(id >= this.config['imagesToShow'])
+		{
+			//On otbient le vrai ID du voisin additionnel.
+			var additionalNeighbourId = id - this.config['imagesToShow'];
+			var sym = (additionalNeighbourId % 2 == 0) ? (+additionalNeighbourId + 1) : (additionalNeighbourId - 1);
+		}
+	}
+}
+
+/*
+ * Lors d'une vue en plein écran, on se déplace vers le voisin dont l'id a été spécifié dans la fonction appelante.
+ */
+mosaic.prototype.moveToNeighbour = function(neighbour)
+{
+	var _this = this;
+	
+	console.log('automove : ' + this.autoMove);
+	
+    //Si on ne peut pas se déplacer vers les voisins, on quitte.
+    if((!this.canMoveToNeighbour || neighbour.length <= 0 || this.currentlyMoving) && !this.autoMove)
+	{
+        return;
+	}
+	
+	console.log('MOVE');
+	this.canMoveToNeighbour = false;
+	this.currentlyMoving = true;
+	this.removeAdditionalNeighbours();
+    
+    //On obtient l'ID de destination.
+    var tab = neighbour.attr('id').split('-');
+    var destinationId = tab[1];
+	
+	var startId = this.previousZoomedSN.attr('id').replace('snapshotDiv-', '');
+    
+    //On charge les attributs nécessaires aux calculs.
+	var length = _this.config['length'];
+    var MPCurrentTop = $('#mainPanel').position().top, MPCurrentLeft = $('#mainPanel').position().left;
+    var divideCoeffTop = Math.floor(destinationId / length) == 0 ? 1 : Math.floor(destinationId / length);
+    var divideCoeffLeft = destinationId % length == 0 ? 1 : destinationId % length;
+    var neighbourFrameTop = $('#snapshotDiv-' + destinationId).position().top, neighbourFrameLeft = $('#snapshotDiv-' + destinationId).position().left;
+    
+	_this.previousZoomedSN = $('#snapshotDiv-' + this.centerId);
+	// var centerSN = $('#snapshotDiv-' + this.centerId);
+	
+	//On définit pour le déplacement vertical s'il est nécessaire de se déplacer en haut ou en bas.
+	if(_this.previousZoomedSN.position().top > neighbourFrameTop)
+		MPCurrentTop += Math.abs(neighbourFrameTop - _this.previousZoomedSN.position().top);
+	else if(_this.previousZoomedSN.position().top < neighbourFrameTop)
+		MPCurrentTop -= Math.abs(neighbourFrameTop - _this.previousZoomedSN.position().top);
+	//On définit pour le déplacement horizontal s'il est nécessaire de se déplacer à gauche ou à droite.
+	if(_this.previousZoomedSN.position().left > neighbourFrameLeft)
+		MPCurrentLeft += Math.abs(neighbourFrameLeft - _this.previousZoomedSN.position().left);
+	else if(_this.previousZoomedSN.position().left < neighbourFrameLeft)
+		MPCurrentLeft -= Math.abs(neighbourFrameLeft - _this.previousZoomedSN.position().left);
+    
+    //On passe le snapshot de destination en HD.
+    var destinationImg = $('#snapshot-' + destinationId);
+    var destinationImgSrc = destinationImg.attr('src');
+    destinationImg.attr('src', destinationImgSrc.replace('snapshots-little/', 'snapshots/'));
+    
+    //On passe l'ancien snapshot en SD.
+    var currentImgSrc = $('img', _this.previousZoomedSN).attr('src');
+    $('img', _this.previousZoomedSN).attr('src', currentImgSrc.replace('snapshots/', 'snapshots-little/'));
+
+    $('#snapshotDiv-' + destinationId).css('opacity', '1');
+    
+	if(_this.playerIsReady)
+	{
+		if(_this.currentMode == 'TIMELINE')
+		{
+			_this.exitTimeline('move');
+		}
+		
+		console.log(Math.floor(_this.player.popcorn.currentTime()));
+		if(_this.autoMove)
+		{
+			_this.timeToGoAt[_this.centerId] = 0;
+			this.autoMove = false;
+		}
+		else
+		{
+			_this.timeToGoAt[_this.centerId] = Math.floor(_this.player.popcorn.currentTime());
+		}
+		_this.player.widgets[0].freePlayer();
+		_this.playerIsReady = false;
+		$('.LdtPlayer').remove();
+		$('body').append('<div class="LdtPlayer" id="LdtPlayer"></div>');
+	}
+	
+	//On obtient l'ID du div de coloration du snapshot vers lequel on se déplace afin de le supprimer.
+    _this.centerId = destinationId;
+	
+    //On grise le snapshot qu'on vient de quitter.
+    _this.previousZoomedSN.fadeTo(_this.config['zoomTime'], '0.4');
+    
+	//console.log(MPCurrentLeft);
+	
+    //On se déplace.
+    $('#mainPanel').animate(
+    {
+        top: MPCurrentTop,
+        left: MPCurrentLeft
+    }, _this.config['timeMovingToNeighbour'], function()
+    {
+        //On fait apparaître le snapshot vers lequel on s'est déplacé.
+        $('#snapshotDiv-' + destinationId).fadeTo(_this.config['zoomTime'], '1', function()
+        {
+            //On recharge les voisins.
+            _this.previousZoomedSN = $('#snapshotDiv-' + _this.centerId);
+            
+			_this.notifyTopVideo = MPCurrentTop;
+			_this.notifyLeftVideo = MPCurrentLeft;
+			_this.neighboursIds.length = 0;
+			_this.currentlyMoving = false;
+			_this.listenToNeighbours();
+			
+			
+			_this.loadPlayer((destinationImg.position().top + MPCurrentTop + _this.MPTop_margin), (destinationImg.position().left + MPCurrentLeft), destinationImg.width(), destinationImg.height(), MPCurrentTop, MPCurrentLeft, _this.timeToGoAt[_this.centerId]);
+        });
+    });
+}
+
+/*
+ * Donne éventuellement un snapshot d'après les coordonnées du pointeur sur l'écran.
+ * Renvoie null sinon.
+*/
+mosaic.prototype.pointerPositionToSN = function(x, y, isMainPointer)
+{
+	if(this.helpDisplayed)
+	{
+		return;
+	}
+	
+	x += $('#mainPointer').width() / 2;
+	y += $('#mainPointer').height() / 2;
+	
+	// $('.snapshotDivs').css('opacity', '0.5');
+	//Taille de la marge des snapshots.
+	var m = parseInt($('.snapshotDivs').css('margin'));
+	
+	//Dimensions d'un snapshot de la mosaïque.
+	var W = $('.snapshotDivs').width() + m * 2, H = $('.snapshotDivs').height() + m * 2;
+	
+	//Position supposée du snapshot dans la mosaïque.
+	//Au départ on ne sélectionne rien.
+	var i = -1, j = -1;
+	
+	//Espace de centrage vertical de la mosaïque.
+	var top_margin = parseInt(this.MPTop_margin);
+	//Dimensions de la mosaïque en nombre de snapshots.
+	var mosW = this.config['length'], mosH = this.config['imagesToShow'] / mosW;
+	
+	//Si le pointeur se trouve au niveau de la mosaïque.
+	if(x < W * mosW && y >= top_margin && y < H * mosH + top_margin)
+	{
+		//Si le pointeur est sur une des bordures.
+		var xb = x % W;
+		var yb = y - top_margin;
+		yb %= H;
+		
+		if(xb < m || xb > W - m || yb < m || yb > H - m)
+		{
+			//On renvoie null.
+			return null;
+		}
+		//Sinon il est forcément sur un des snapshots.
+		else
+		{
+			i = Math.floor(x / W);
+			j = Math.floor((y - top_margin) / H);
+		}
+		
+		//On passe des coordonnées 2D en 1D.
+		var snapshot = $('#snapshotDiv-' + (j * mosW + i));
+		
+		//Si le snapshot a été filtré, on renvoie null si on se trouve dans la mosaïque.
+		if(this.isMosaicFiltered && (this.currentMode == "MOSAIC" || this.currentMode == "FILTER") && snapshot.css('opacity') == 0)
+		{
+			return null;
+		}
+		
+		//On renvoie le snapshot.
+		return snapshot;
+	}
+	
+	//Si on est arrivé là, c'est que le pointeur n'est pas dans la mosaïque.
+	return null;
+}
+
+/*
+ * Donne éventuellement un voisin additionnel d'après les coordonnées du pointeur sur l'écran.
+ * Renvoie null sinon.
+*/
+mosaic.prototype.pointerPositionToAN = function(x, y, isMainPointer)
+{
+	if(this.helpDisplayed)
+	{
+		return;
+	}
+	
+	x += $('#mainPointer').width() / 2;
+	y += $('#mainPointer').height() / 2;
+	
+	//Pour tous les voisins.
+	for(var i = 0 ; i < this.neighboursIds.length ; i++)
+	{
+		//Si on est sur un bord.
+		if(this.neighboursIds[i] == -1)
+		{
+			//On récupère un voisin au delà du bord.
+			var neighbour = $('#borderNeighbour-' + i);
+			
+			if(neighbour == null || neighbour == undefined || neighbour.position() == null)
+			{
+				return;
+			}
+			
+			//Si le pointeur est sur le voisin, on le retourne.
+			if(x > neighbour.position().left && x < +neighbour.position().left + neighbour.width() && y > neighbour.position().top && y < +neighbour.position().top + neighbour.height())
+			{
+				return neighbour;
+			}
+		}
+	}
+	return null;
+}
+
+/*
+ * Vérifie l'intéraction dézoom.
+*/
+mosaic.prototype.checkForDezoom = function()
+{
+	//Si on se trouve en mode VIDEO ou SEARCH.
+	if(this.currentMode == "VIDEO" || this.currentMode == "SEARCH")
+	{
+		//Si les deux pointeurs sont allés puis ont quitté une bordure.
+		if(this.mainPointerExitBorder && this.secondPointerExitBorder)
+		{
+			//Si les voisins existent.
+			if(this.neighboursIds != null && this.neighboursIds.length > 0)
+			{
+				var localIdMainPointerNeighbour = $.inArray(this.mainPointerNeighbourSelectedId, this.neighboursIds);
+				var localIdSecondPointerNeighbour = $.inArray(this.secondPointerNeighbourSelectedId, this.neighboursIds);
+				
+				//Cas où on a des voisins additionnels.
+				if(this.mainPointerNeighbourSelectedId >= this.config['imagesToShow'])
+				{
+					localIdMainPointerNeighbour = this.mainPointerNeighbourSelectedId - this.config['imagesToShow'];
+				}
+				if(this.secondPointerNeighbourSelectedId >= this.config['imagesToShow'])
+				{
+					localIdSecondPointerNeighbour = this.secondPointerNeighbourSelectedId - this.config['imagesToShow'];
+				}
+				
+				// console.log(localIdMainPointerNeighbour + ' <=> ' + localIdSecondPointerNeighbour);
+				
+				if(localIdMainPointerNeighbour > -1 && localIdMainPointerNeighbour < 4 && localIdSecondPointerNeighbour > -1 && localIdSecondPointerNeighbour < 4)
+				{
+					var sym = (localIdMainPointerNeighbour % 2 == 0) ? (+localIdMainPointerNeighbour + 1) : (localIdMainPointerNeighbour - 1);
+					
+					//Si les voisins sélectionnés sont opposés.
+					if(sym == localIdSecondPointerNeighbour)
+					{
+						//Positions des pointeurs.
+						var xMain = $('#mainPointer').position().left - $('#mainPointer').width() / 2;
+						var yMain = $('#mainPointer').position().top - $('#mainPointer').height() / 2;
+						var xSecond = $('#secondPointer').position().left - $('#secondPointer').width() / 2;
+						var ySecond = $('#secondPointer').position().top - $('#secondPointer').height() / 2;
+						
+						//Snapshot central.
+						var centerSN = $('#snapshotDiv-' + this.centerId);
+						
+						//Quarts du snapshot central.
+						var center1QuartWidth = centerSN.position().left + this.notifyLeftVideo + centerSN.width() / 4;
+						var center3QuartsWidth = centerSN.position().left + this.notifyLeftVideo + centerSN.width() * 3 / 4;
+						var center1QuartHeight = centerSN.position().top + this.notifyTopVideo + centerSN.height() / 4;
+						var center3QuartsHeight = centerSN.position().top + this.notifyTopVideo + centerSN.height() * 3 / 4;
+						
+						//Pour activer le dézoom, il suffit que les pointeurs soient dans un rectangle délimité au centre de l'écran.
+						//Si les voisins sélectionnés sont de disposition horizontale.
+						if(sym == 0 || sym == 1)
+						{
+							if(xMain > center1QuartWidth && xSecond > center1QuartWidth && xMain < center3QuartsWidth && xSecond < center3QuartsWidth)
+							{
+								console.log('HORIZONTAL UNZOOM - ' + this.currentMode);
+								this.unzoom();
+								console.log('HORIZONTAL UNZOOM AFTER - ' + this.currentMode);
+							}
+						}
+						//Sinon s'ils sont de disposition verticale.
+						else if(sym == 2 || sym == 3)
+						{
+							if(yMain > center1QuartHeight && ySecond > center1QuartHeight && yMain < center3QuartsHeight && ySecond < center3QuartsHeight)
+							{
+								console.log('VERTICAL UNZOOM - ' + this.currentMode);
+								this.unzoom();
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/front_idill/src/mosaic/js/notifications.js	Fri Jun 29 16:16:24 2012 +0200
@@ -0,0 +1,1535 @@
+/* ===============================================
+ *												   *
+ *		      ZONE DES NOTIFICATIONS			   *
+ *												   *
+   =============================================== */
+
+/*
+ * Affiche la notification de sélection/recherche lorsque la mosaique est complète.
+*/
+mosaic.prototype.notifySelectionSearchMosaicFull = function()
+{
+	if(this.currentMode != "MOSAIC" && this.currentMode != "FILTER" || this.isCurrentlyInASearchByGesture || $('#notify_selection').length > 0 || $('#notify_search').length > 0 || $('#notify_point').length > 0)
+	{
+		return;
+	}
+	
+	console.log('NOTIFY SEL SEA');
+	
+	//On spécifie les notifications en div.
+	var notification_selection = "<div id='notify_selection' class='notifications'></div>";
+	var notification_search = "<div id='notify_search' class='notifications'></div>";
+	
+	//On les ajoute à la mosaïque.
+	$('#mainPanel').append(notification_selection + notification_search);
+
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var selection_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
+	var search_left = selection_left + notify_width + notify_margin;
+	
+	//On les positionne.
+	$('#notify_selection').css(
+	{
+		left: selection_left
+	});
+	$('#notify_search').css(
+	{
+		left: search_left
+	});
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Supprime la notification de sélection/recherche lorsque la mosaique est complète.
+*/
+mosaic.prototype.removeSelectionSearchMosaicFull = function()
+{
+	if(this.isOnASnapshot)
+	{
+		// console.log('DEL SEL SEA');
+		$('#notify_selection, #notify_search').remove();
+	}
+}
+
+/*
+ * Affiche la notification de maintient du pointage lors d'une phase de prézoom.
+*/
+mosaic.prototype.notifyPointMosaicPrezoom = function()
+{
+	this.removeSelectionSearchMosaicFull();
+	if($('#notify_point').length > 0 || $('#notify_search').length > 0 || this.currentMode != 'MOSAIC' && this.currentMode != 'FILTER' && !this.isOnASnapshot)
+	{
+		this.removePointMosaicPrezoom();
+		return;
+	}
+	
+	//On spécifie les notifications en div.
+	var notification_point = "<div id='notify_point' class='notifications'></div>";
+	
+	//On les ajoute à la mosaïque.
+	$('#mainPanel').append(notification_point);
+	
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var point_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
+	
+	//On les positionne.
+	$('#notify_point').css(
+	{
+		left: point_left
+	});
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Supprime la notification de maintient du pointage.
+*/
+mosaic.prototype.removePointMosaicPrezoom = function()
+{
+	//if(!this.isOnASnapshot)
+	//{
+		$('#notify_point').remove();
+	//}
+}
+
+/*
+ * Affiche la notification de recherche (qu'elle soit par gesture ou par courbes).
+*/
+mosaic.prototype.notifySearch = function()
+{
+	/*this.removeSelectionSearchMosaicFull();
+	if($('#notify_point').length > 0 || $('#notify_search').length > 0 || this.currentMode != 'MOSAIC' && this.currentMode != 'FILTER' && !this.isOnASnapshot)
+	{
+		//this.removeNotifySearch();
+		//return;
+	}*/
+	
+	if($('.notifications').length > 0)
+	{
+		$('.notifications').remove();
+	}
+	
+	//On spécifie les notifications en div.
+	var notification_search = "<div id='notify_search' class='notifications'></div>";
+	
+	//On les ajoute à la mosaïque.
+	$('body').append(notification_search);
+	
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var point_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
+	
+	//On les positionne.
+	$('#notify_search').css(
+	{
+		left: point_left
+	});
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Supprime la notification de maintient du pointage.
+*/
+mosaic.prototype.removeNotifySearch = function()
+{
+	//if(!this.isOnASnapshot)
+	//{
+		//$('#notify_search').remove();
+	//}
+}
+
+/*
+ * Affiche la notification de changement de voisin et de dezoom.
+*/
+mosaic.prototype.notifyMoveUnzoom = function(targetId)
+{
+	console.log('MOVE & UNZOOM');
+	
+	if($('.notifications').length > 0 || !this.neighboursIds || this.neighboursIds.length == 0 || targetId == -1 || this.currentMode != 'VIDEO' && this.currentMode != 'SEARCH' && this.currentMode != 'TIMELINE')
+	{
+		return;
+	}
+	
+	console.log('NOT');
+		
+	var _this = this;
+	
+	//On spécifie les notifications en div.
+	var notification_move_unzoom = "<div id='notify_move' class='notifications'></div><div id='notify_unzoom' class='notifications'></div>";
+	
+	//On les ajoute à la mosaïque.
+	$('body').append(notification_move_unzoom);
+	
+	// console.log(this.player.config.gui.zoomTop + " " + this.player.config.gui.zoomLeft);
+	
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var point_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
+	
+	var side = $.inArray(parseInt(targetId), this.neighboursIds);
+	// console.log(this.neighboursIds, parseInt(targetId), side);
+	if(side == -1)
+	{
+		return;
+	}
+	
+	var sides = ['left', 'right', 'up', 'down'];
+	var unzooms = ['horizontal', 'vertical'];
+	
+	// var notifyTop = this.notifyTopVideo, notifyLeft = this.notifyLeftVideo;
+	var notifyTop = 0, notifyLeft = 0;
+	
+	//On les positionne.
+	$('#notify_move').css(
+	{
+		top: -notifyTop,
+		left: -notifyLeft + ($(window).width() - notify_width * 2 - notify_margin * 2) / 2,
+		'background-image': 'url(./pictos/notifications/move_' + sides[side] + '.png)'
+	});
+	
+	$('#notify_unzoom').css(
+	{
+		top: -notifyTop,
+		left: -notifyLeft + ($(window).width()) / 2,
+		'background-image': 'url(./pictos/notifications/unzoom_' + unzooms[Math.floor(side / 2)] + '.png)'
+	});
+	
+	// console.log('url(./pictos/notifications/move_' + sides[side] + '.png)');
+	// console.log($('#notify_move').css('background-image', 'url(./pictos/notifications/move_' + sides[side] + '.png)'));
+	// console.log($('#notify_move').css('background-image'));
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Supprime la notification de recherche de gesture.
+*/
+mosaic.prototype.removeNotifyMoveUnzoom = function()
+{
+	$('#notify_move').remove();
+	$('#notify_unzoom').remove();
+}
+
+/*
+ * Affiche la notification de dezoom.
+*/
+mosaic.prototype.notifyUnzoom = function(targetId)
+{
+	console.log('UNZOOM');
+	
+	if($('.notifications').length > 0 || !this.neighboursIds || this.neighboursIds.length == 0 || targetId == -1 || this.currentMode != 'VIDEO' && this.currentMode != 'SEARCH' && this.currentMode != 'TIMELINE')
+	{
+		return;
+	}
+	
+	console.log('NOT');
+		
+	var _this = this;
+	
+	//On spécifie les notifications en div.
+	var notification_move_unzoom = "<div id='notify_move' class='notifications'></div><div id='notify_unzoom' class='notifications'></div>";
+	
+	//On les ajoute à la mosaïque.
+	$('body').append(notification_move_unzoom);
+	
+	// console.log(this.player.config.gui.zoomTop + " " + this.player.config.gui.zoomLeft);
+	
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var point_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
+	
+	var side = $.inArray(parseInt(targetId), this.neighboursIds);
+	// console.log(this.neighboursIds, parseInt(targetId), side);
+	if(side == -1)
+	{
+		return;
+	}
+	
+	var sides = ['left', 'right', 'up', 'down'];
+	var unzooms = ['horizontal', 'vertical'];
+	
+	// var notifyTop = this.notifyTopVideo, notifyLeft = this.notifyLeftVideo;
+	var notifyTop = 0, notifyLeft = 0;
+	
+	//On les positionne.
+	$('#notify_move').css(
+	{
+		top: -notifyTop,
+		left: -notifyLeft + ($(window).width() - notify_width * 2 - notify_margin * 2) / 2,
+		'background-image': 'url(./pictos/notifications/move_' + sides[side] + '.png)'
+	});
+	
+	$('#notify_unzoom').css(
+	{
+		top: -notifyTop,
+		left: -notifyLeft + ($(window).width()) / 2,
+		'background-image': 'url(./pictos/notifications/unzoom_' + unzooms[Math.floor(side / 2)] + '.png)'
+	});
+	
+	// console.log('url(./pictos/notifications/move_' + sides[side] + '.png)');
+	// console.log($('#notify_move').css('background-image', 'url(./pictos/notifications/move_' + sides[side] + '.png)'));
+	// console.log($('#notify_move').css('background-image'));
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Supprime la notification de dezoom.
+*/
+mosaic.prototype.removeNotifyUnzoom = function()
+{
+	$('#notify_unzoom').remove();
+}
+
+/*
+ * Affiche la notification de dezoom.
+ * Direction vaut left ou right.
+*/
+mosaic.prototype.notifySwipe = function(direction)
+{
+	console.log('TRY SWIPE');
+	
+	if($('.notifications').length > 0 || this.currentMode != 'VIDEO' && this.currentMode != 'SEARCH' && this.currentMode != 'TIMELINE' && !this.isSwipe)
+	{
+		return;
+	}
+	
+	console.log('IN SWIPE');
+		
+	var _this = this;
+	
+	//On spécifie les notifications en div.
+	var notification_swipe = "<div id='notify_swipe' class='notifications'></div>";
+	
+	//On les ajoute à la mosaïque.
+	$('body').append(notification_swipe);
+	
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var point_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
+	
+	// var notifyTop = this.notifyTopVideo, notifyLeft = this.notifyLeftVideo;
+	var notifyTop = 0, notifyLeft = 0;
+	
+	//On les positionne.
+	$('#notify_swipe').css(
+	{
+		top: -notifyTop,
+		left: -notifyLeft + ($(window).width() - notify_width - notify_margin) / 2,
+		'background-image': 'url(./pictos/notifications/swipe_' + direction + '.png)'
+	});
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Supprime la notification de dezoom.
+*/
+mosaic.prototype.removeNotifyUnzoom = function()
+{
+	$('#notify_unzoom').remove();
+}
+
+/*
+ * Affiche l'aide.
+*/
+mosaic.prototype.notifyHelp = function(inMosaic)
+{
+	if(this.helpDisplayed)
+	{
+		return;
+	}
+	
+	this.removeSelectionSearchMosaicFull();
+	this.removePointMosaicPrezoom();
+	
+	this.helpDisplayed = true;
+	
+	var search_2hands_tab = ['arret', 'contact', 'grandjete', 'group_spin', 'port_de_bras', 'rythme', 'slow', 'spin', 'up_down', 'wave'];
+	var search_2hands_tab_opacities = [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5];
+	var search_body_tab = ['chute', 'knee_up', 'jump', 'bend'];
+	var search_body_tab_opacities = [1, 1, 1, 1];
+	var controls_1hand_tab;
+	var controls_1hand_tab_1;
+	var controls_1hand_tab_2;
+	var controls_1hand_tab_opacities;
+	var controls_1hand_tab_opacities_1;
+	var controls_1hand_tab_opacities_2;
+	
+	if(inMosaic)
+	{
+		controls_1hand_tab = ['selection'];
+		controls_1hand_tab_opacities = [1];
+	}
+	else
+	{
+		controls_1hand_tab_1 = ['deplacer', 'precedent', 'suivant', 'mosaique_horizontal', 'mosaique_vertical'];
+		controls_1hand_tab_2 = ['move_down', 'move_up', 'move_right', 'move_left'];
+		controls_1hand_tab_opacities_1 = [1, 1, 1, 1, 1];
+		controls_1hand_tab_opacities_2 = [1, 1, 1, 1];
+	}
+	
+	//On spécifie les notifications en div.
+	var search_title = "<div id='search_title'></div>";
+	var search_img = "<div id='search_img' class='notify_imgs'></div>";
+	var search_2hands_text = "<div id='search_2hands_text'></div>";
+	var search_2hands_imgs = "<div id='search_2hands_imgs' class='notify_imgs_big'>";
+	
+	for(var i = 0 ; i < search_2hands_tab.length ; i++)
+	{
+		search_2hands_imgs += "<div id='2hands_" + search_2hands_tab[i] + "' class='notify_imgs_small' style='opacity: " + search_2hands_tab_opacities[i] + ";'></div>";
+	}
+	search_2hands_imgs += "</div>";
+	
+	var search_body_text = "<div id='search_body_text'></div>";
+	var search_body_imgs = "<div id='search_body_imgs' class='notify_imgs'>"
+	
+	for(var i = 0 ; i < search_body_tab.length ; i++)
+	{
+		search_body_imgs += "<div id='body_" + search_body_tab[i] + "' class='notify_imgs_small' style='opacity: " + search_body_tab_opacities[i] + ";'></div>";
+	}
+	search_body_imgs += "</div>";
+	
+	var controls_title = "<div id='controls_title'></div>";
+	var controls_img = "<div id='controls_img' class='notify_imgs'></div>";
+	var controls_1hand_text = "<div id='controls_1hand_text'></div>";
+	var controls_1hand_imgs;
+	var controls_1hand_imgs_1;
+	var controls_1hand_imgs_2;
+	
+	if(inMosaic)
+	{
+		controls_1hand_imgs = "<div id='controls_1hand_imgs' class='notify_imgs'>";
+		for(var i = 0 ; i < controls_1hand_tab.length ; i++)
+		{
+			controls_1hand_imgs += "<div id='1hand_" + controls_1hand_tab[i] + "' class='notify_imgs_small' style='opacity: " + controls_1hand_tab_opacities[i] + ";'></div>";
+		}
+		controls_1hand_imgs += "</div>";
+	}
+	else
+	{
+		controls_1hand_imgs_1 = "<div id='controls_1hand_imgs_1' class='notify_imgs'>";
+		controls_1hand_imgs_2 = "<div id='controls_1hand_imgs_2' class='notify_imgs'>";
+		for(var i = 0 ; i < controls_1hand_tab_1.length ; i++)
+		{
+			controls_1hand_imgs_1 += "<div id='1hand_" + controls_1hand_tab_1[i] + "' class='notify_imgs_small' style='opacity: " + controls_1hand_tab_opacities_1[i] + ";'></div>";
+		}
+		controls_1hand_imgs_1 += "</div>";
+		for(var i = 0 ; i < controls_1hand_tab_2.length ; i++)
+		{
+			controls_1hand_imgs_2 += "<div id='1hand_" + controls_1hand_tab_2[i] + "' class='notify_imgs_small' style='opacity: " + controls_1hand_tab_opacities_2[i] + ";'></div>";
+		}
+		controls_1hand_imgs_2 += "</div>";
+	}
+	
+	var help_search = "<div id='help_search'>" + search_title + search_img + search_2hands_text + search_2hands_imgs + search_body_text + search_body_imgs + "</div>";
+	var help_controls;
+
+	if(inMosaic)
+	{
+		help_controls = "<div id='help_controls'>" + controls_title + controls_img + controls_1hand_text + controls_1hand_imgs + "</div>";
+	}
+	else
+	{
+		help_controls = "<div id='help_controls'>" + controls_title + controls_img + controls_1hand_text + controls_1hand_imgs_1 + controls_1hand_imgs_2 + "</div>";
+	}
+	
+	var notification_help = "<div id='notify_help'>" + help_search + "<div id='help_sep'></div>" + help_controls + "</div>";
+	
+	//On les ajoute à la mosaïque.
+	$('body').append(notification_help);
+	
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $(window).width(), notify_height = $(window).height();
+	var notify_margin = parseInt($('#notify_help').css('margin'));
+	var notify_ = 10;
+	
+	//On les positionne.
+	$('#notify_help').css(
+	{
+		left: "0px",
+		top: "0px",
+		width: notify_width - notify_margin * 2,
+		height: notify_height - notify_margin * 2,
+		'z-index': 2000
+	});
+	
+	// console.log(($('#help_search').width() - ($('.notify_imgs_small').width() * 5 + parseInt($('.notify_imgs_small').css('margin')))) / 2);
+	
+	$('#search_2hands_imgs').css(
+	{
+		'padding-left': ($('#help_search').width() - ($('.notify_imgs_small').width() * 5 + parseInt($('.notify_imgs_small').css('margin')))) / 2,
+		'height': ($('.notify_imgs_small').height() * 2 + parseInt($('.notify_imgs_small').css('margin')))
+	});
+	
+	$('#search_body_imgs').css(
+	{
+		'padding-left': ($('#help_search').width() - ($('.notify_imgs_small').width() * 4 + parseInt($('.notify_imgs_small').css('margin')))) / 2,
+		'height': ($('.notify_imgs_small').height() * 2 + parseInt($('.notify_imgs_small').css('margin')))
+	});
+	
+	if(inMosaic)
+	{
+		$('#controls_1hand_imgs').css(
+		{
+			'padding-left': ($('#help_controls').width() - ($('.notify_imgs_small').width())) / 2,
+			'height': ($('.notify_imgs_small').height())
+		});
+	}
+	else
+	{
+		$('#controls_1hand_imgs_1').css(
+		{
+			'padding-left': ($('#help_controls').width() - ($('.notify_imgs_small').width() * 5 + parseInt($('.notify_imgs_small').css('margin')))) / 2,
+			'height': ($('.notify_imgs_small').height())
+		});
+		$('#controls_1hand_imgs_2').css(
+		{
+			'padding-left': ($('#help_controls').width() - ($('.notify_imgs_small').width() * 4 + parseInt($('.notify_imgs_small').css('margin')))) / 2,
+			'height': ($('.notify_imgs_small').height())
+		});
+	}
+	
+	var search_width = $('#help_search').width();
+	
+	$('#search_title').html('Recherche');
+	$('#search_2hands_text').html('Gestes à effectuer avec les deux mains');
+	$('#search_body_text').html('Gestes à effectuer avec le corps entier');
+	
+	for(var i = 0 ; i < search_2hands_tab.length ; i++)
+	{
+		$("#2hands_" + search_2hands_tab[i]).css("background-image", "url('./pictos/help/" + search_2hands_tab[i] + ".png')");
+		//console.log("url('../../pictos/help/" + search_2hands_tab[i] + ".png')");
+	}
+	
+	for(var i = 0 ; i < search_body_tab.length ; i++)
+	{
+		$("#body_" + search_body_tab[i]).css("background-image", "url('./pictos/help/" + search_body_tab[i] + ".png')");
+		//console.log("url('../../pictos/help/" + search_2hands_tab[i] + ".png')");
+	}
+	
+	$('#controls_title').html('Contrôles');
+	$('#controls_1hand_text').html('Gestes à effectuer avec une seule main');
+	
+	if(inMosaic)
+	{
+		for(var i = 0 ; i < controls_1hand_tab.length ; i++)
+		{
+			$("#1hand_" + controls_1hand_tab[i]).css("background-image", "url('./pictos/help/" + controls_1hand_tab[i] + ".png')");
+		}
+	}
+	else
+	{
+		for(var i = 0 ; i < controls_1hand_tab_1.length ; i++)
+		{
+			$("#1hand_" + controls_1hand_tab_1[i]).css("background-image", "url('./pictos/help/" + controls_1hand_tab_1[i] + ".png')");
+		}
+		for(var i = 0 ; i < controls_1hand_tab_2.length ; i++)
+		{
+			$("#1hand_" + controls_1hand_tab_2[i]).css("background-image", "url('./pictos/help/" + controls_1hand_tab_2[i] + ".png')");
+		}
+	}
+	
+	//On les fait apparaître.
+	$('#notify_help').css(
+	{
+		opacity: "1"
+	});
+	
+	$('.notify_imgs_big').css(
+	{
+		opacity: "1"
+	});
+}
+
+/*
+ * Supprime l'aide.
+*/
+mosaic.prototype.removeHelp = function()
+{
+	if(!this.helpDisplayed)
+	{
+		return;
+	}
+	
+	var _this = this;
+	
+	$('#notify_help').fadeOut(this.timeNotifyFade, function()
+	{
+		_this.helpDisplayed = false;
+		// _this.canNotifyHelp = false;
+		_this.canNotifyHelp = true;
+		console.log('CAN NOT NOTIFY HELP');
+		$('#notify_help').remove();
+	});
+}
+
+/*
+ * Affiche la notification de validation/survol de gesture de filtrage.
+ * Mode prend pour valeurs : "valid" ou "hover".
+*/
+mosaic.prototype.notifySearch1Gesture = function(gestureName, mode)
+{
+	// console.log('C');
+	if($('#notify_search_1gesture').length > 0)
+	{
+		$('#notify_search_1gesture').remove();
+	}
+	
+	//Si on a effectué une demande de recherche auparavant, on supprime la notification de demande de recherche.
+	if($('#notify_search').length > 0)
+	{
+		$('.notifications').remove();
+	}
+	
+	var _this = this;
+	
+	//On spécifie les notifications en div.
+	var notification_search_1gesture = "<div id='notify_search_1gesture' class='notifications'></div>";
+	
+	//On les ajoute à la mosaïque.
+	$('body').append(notification_search_1gesture);
+	
+	// console.log(this.player.config.gui.zoomTop + " " + this.player.config.gui.zoomLeft);
+	
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var point_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
+	
+	if(_.include(this.gestures, gestureName))
+	{
+		$('#notify_search_1gesture').css('background-image', 'url("./pictos/big/' + mode + '/' + gestureName + '.png")');
+	}
+	else if(mode == 'none')
+	{
+		$('#notify_search_1gesture').css('background-image', 'url("./pictos/big/normal/inconnu.png")');
+	}
+	
+	//On les positionne.
+	$('#notify_search_1gesture').css(
+	{
+		top: 0,
+		left: ($(window).width() - notify_width) / 2
+	});
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+// /!\/!\/!\ //
+
+/* NOUVELLES NOTIFICATIONS */
+
+// /!\/!\/!\ //
+
+/*
+ * Affichage de la notification de sélection & recherche dans la mosaïque.
+*/
+mosaic.prototype.mosaicSelectionAndSearch = function()
+{
+	if(this.currentMode != 'MOSAIC')
+	{
+		return;
+	}
+	
+	//On spécifie les notifications en div.
+	var notification_selection = "<div id='notify_selection' class='notifications'></div>";
+	var notification_search = "<div id='notify_search' class='notifications'></div>";
+	
+	//On les ajoute à la mosaïque.
+	$('body').append(notification_selection + notification_search);
+
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var selection_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
+	var search_left = selection_left + notify_width + notify_margin;
+	
+	//On les positionne.
+	$('#notify_selection').css(
+	{
+		left: selection_left
+	});
+	$('#notify_search').css(
+	{
+		left: search_left
+	});
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Affichage de la notification de sélection dans la mosaïque.
+*/
+mosaic.prototype.mosaicSelection = function()
+{
+	if(this.currentMode != 'MOSAIC')
+	{
+		return;
+	}
+	
+	//On spécifie la notification en div.
+	var notification_selection = "<div id='notify_selection' class='notifications'></div>";
+	
+	//On l'ajoute à la mosaïque.
+	$('body').append(notification_selection);
+
+	//On calcule ses coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var selection_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
+	
+	//On les positionne.
+	$('#notify_selection').css(
+	{
+		left: selection_left
+	});
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Affichage de la notification de recherche dans une demande de filtrage de la mosaïque.
+*/
+mosaic.prototype.filterSearch = function()
+{
+	if(this.currentMode != 'FILTER' || this.filterSearchedType)
+	{
+		return;
+	}
+	
+	// window.location.reload();
+	
+	//On spécifie la notification en div.
+	var notification_search = "<div id='notify_search' class='notifications'></div>";
+	
+	//On l'ajoute à la mosaïque.
+	$('body').append(notification_search);
+
+	//On calcule ses coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var search_left = $(window).width() / 2 - notify_width / 2 - notify_margin;
+	
+	//On la positionne.
+	$('#notify_search').css(
+	{
+		left: search_left
+	});
+	
+	//On la fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Affichage de la notification de recherche & sélection dans une demande de filtrage de la mosaïque.
+*/
+mosaic.prototype.filterSearchAndSelection = function()
+{
+	if(this.currentMode != 'FILTER' || this.filterSearchedType)
+	{
+		return;
+	}
+	
+	//On spécifie les notifications en div.
+	var notification_selection = "<div id='notify_selection' class='notifications'></div>";
+	var notification_search = "<div id='notify_search' class='notifications'></div>";
+	
+	//On les ajoute à la mosaïque.
+	$('body').append(notification_selection + notification_search);
+
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var search_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
+	var selection_left = search_left + notify_width + notify_margin;
+	
+	//On les positionne.
+	$('#notify_selection').css(
+	{
+		left: selection_left
+	});
+	$('#notify_search').css(
+	{
+		left: search_left
+	});
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Affichage de la notification de résultat de gesture dans la mosaïque filtrée.
+*/
+mosaic.prototype.filterGesture = function(gestureName, mode)
+{
+	if(this.currentMode != 'FILTER' || !this.filterSearchedType)
+	{
+		return;
+	}
+	
+	var _this = this;
+	
+	//On spécifie les notifications en div.
+	var notification_search_1gesture = "<div id='notify_search_1gesture' class='notifications'></div>";
+	
+	//On les ajoute à la mosaïque.
+	$('body').append(notification_search_1gesture);
+	
+	// console.log(this.player.config.gui.zoomTop + " " + this.player.config.gui.zoomLeft);
+	
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var point_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
+	
+	if(_.include(this.gestures, gestureName))
+	{
+		$('#notify_search_1gesture').css('background-image', 'url("./pictos/big/' + mode + '/' + gestureName + '.png")');
+	}
+	else if(mode == 'none')
+	{
+		$('#notify_search_1gesture').css('background-image', 'url("./pictos/big/normal/inconnu.png")');
+	}
+	
+	//On les positionne.
+	$('#notify_search_1gesture').css(
+	{
+		top: 0,
+		left: ($(window).width() - notify_width) / 2
+	});
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Affichage de la notification de résultat de gesture & de sélection dans la mosaïque filtrée.
+*/
+mosaic.prototype.filterGestureAndSelection = function(gestureName, mode)
+{
+	if(this.currentMode != 'FILTER' || !this.filterSearchedType)
+	{
+		return;
+	}
+	
+	//On spécifie les notifications en div.
+	var notification_search_1gesture = "<div id='notify_search_1gesture' class='notifications'></div>";
+	var notification_selection = "<div id='notify_selection' class='notifications'></div>";
+	
+	//On les ajoute à la mosaïque.
+	$('body').append(notification_search_1gesture + notification_selection);
+
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var search_1gesture_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
+	var selection_left = search_1gesture_left + notify_width + notify_margin;
+	
+	if(_.include(this.gestures, gestureName))
+	{
+		$('#notify_search_1gesture').css('background-image', 'url("./pictos/big/' + mode + '/' + gestureName + '.png")');
+	}
+	else if(mode == 'none')
+	{
+		$('#notify_search_1gesture').css('background-image', 'url("./pictos/big/normal/inconnu.png")');
+	}
+	
+	//On les positionne.
+	$('#notify_search_1gesture').css(
+	{
+		left: search_1gesture_left
+	});
+	$('#notify_selection').css(
+	{
+		left: selection_left
+	});
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Affiche la notification de dezoom.
+ * Direction vaut left ou right.
+*/
+mosaic.prototype.videoSwipe = function(direction)
+{
+	if(this.currentMode != 'VIDEO' || !this.isSwipe)
+	{
+		return;
+	}
+	
+	var _this = this;
+	
+	//On spécifie les notifications en div.
+	var notification_swipe = "<div id='notify_swipe' class='notifications'></div>";
+	
+	//On les ajoute à la mosaïque.
+	$('body').append(notification_swipe);
+	
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var point_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
+	
+	// var notifyTop = this.notifyTopVideo, notifyLeft = this.notifyLeftVideo;
+	var notifyTop = 0, notifyLeft = 0;
+	
+	//On les positionne.
+	$('#notify_swipe').css(
+	{
+		top: -notifyTop,
+		left: -notifyLeft + ($(window).width() - notify_width - notify_margin) / 2,
+		'background-image': 'url(./pictos/notifications/swipe_' + direction + '.png)'
+	});
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Affichage de la notification de résultat de move vers un voisin & de dézoom dans une vidéo.
+*/
+mosaic.prototype.videoMoveAndUnzoom = function(targetId)
+{
+	if(this.currentMode != 'VIDEO')
+	{
+		return;
+	}
+	
+	var _this = this;
+	
+	//On spécifie les notifications en div.
+	var notification_move = "<div id='notify_move' class='notifications'></div>";
+	var notification_unzoom = "<div id='notify_unzoom' class='notifications'></div>";
+	
+	//On les ajoute à la mosaïque.
+	$('body').append(notification_move + notification_unzoom);
+	
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var move_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
+	var unzoom_left = move_left + notify_width + notify_margin;
+	
+	var side = $.inArray(parseInt(targetId), this.neighboursIds);
+	// console.log(this.neighboursIds, parseInt(targetId), side);
+	if(side == -1)
+	{
+		return;
+	}
+	
+	var sides = ['left', 'right', 'up', 'down'];
+	var unzooms = ['horizontal', 'vertical'];
+	
+	// var notifyTop = this.notifyTopVideo, notifyLeft = this.notifyLeftVideo;
+	var notifyTop = 0, notifyLeft = 0;
+	
+	//On les positionne.
+	$('#notify_move').css(
+	{
+		top: -notifyTop,
+		left: -notifyLeft + move_left,
+		'background-image': 'url(./pictos/notifications/move_' + sides[side] + '.png)'
+	});
+	
+	$('#notify_unzoom').css(
+	{
+		top: -notifyTop,
+		left: -notifyLeft + unzoom_left,
+		'background-image': 'url(./pictos/notifications/unzoom_' + unzooms[Math.floor(side / 2)] + '.png)'
+	});
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Affichage de la notification de résultat de dézoom dans une vidéo.
+*/
+mosaic.prototype.videoUnzoom = function(targetId)
+{
+	if(this.currentMode != 'VIDEO')
+	{
+		return;
+	}
+	
+	var _this = this;
+	
+	//On spécifie la notifications en div.
+	var notification_unzoom = "<div id='notify_unzoom' class='notifications'></div>";
+	
+	//On l'ajoute à la mosaïque.
+	$('body').append(notification_unzoom);
+	
+	//On calcule ses coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var unzoom_left = $(window).width() / 2 - notify_width / 2 - notify_margin;
+	
+	var side = $.inArray(parseInt(targetId), this.neighboursIds);
+	if(side == -1)
+	{
+		return;
+	}
+	
+	var unzooms = ['horizontal', 'vertical'];
+	
+	// var notifyTop = this.notifyTopVideo, notifyLeft = this.notifyLeftVideo;
+	var notifyTop = 0, notifyLeft = 0;
+	
+	//On la positionne.
+	$('#notify_unzoom').css(
+	{
+		top: -notifyTop,
+		left: -notifyLeft + unzoom_left,
+		'background-image': 'url(./pictos/notifications/unzoom_' + unzooms[Math.floor(side / 2)] + '.png)'
+	});
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Affichage de la notification de timeline dans une vidéo/recherche.
+*/
+mosaic.prototype.timelineTimeline = function()
+{
+	if(this.currentMode != 'TIMELINE')
+	{
+		return;
+	}
+	
+	var _this = this;
+	
+	//On spécifie la notifications en div.
+	var notification_timeline = "<div id='notify_timeline' class='notifications'></div>";
+	
+	//On l'ajoute à la mosaïque.
+	$('body').append(notification_timeline);
+	
+	//On calcule ses coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var timeline_left = $(window).width() / 2 - notify_width / 2 - notify_margin;
+	
+	// var notifyTop = this.notifyTopVideo, notifyLeft = this.notifyLeftVideo;
+	var notifyTop = 0, notifyLeft = 0;
+	
+	//On la positionne.
+	$('#notify_timeline').css(
+	{
+		top: -notifyTop,
+		left: -notifyLeft + timeline_left
+	});
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Affichage de la notification de recherche dans une vidéo de recherche.
+*/
+mosaic.prototype.searchSearch = function()
+{
+	if(this.currentMode != 'SEARCH' || this.isCurrentlyInASearchByGesture)
+	{
+		return;
+	}
+	
+	var _this = this;
+	
+	//On spécifie la notifications en div.
+	var notification_search = "<div id='notify_search' class='notifications'></div>";
+	
+	//On l'ajoute à la mosaïque.
+	$('body').append(notification_search);
+	
+	//On calcule ses coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var search_left = $(window).width() / 2 - notify_width / 2 - notify_margin;
+	
+	// var notifyTop = this.notifyTopVideo, notifyLeft = this.notifyLeftVideo;
+	var notifyTop = 0, notifyLeft = 0;
+	
+	//On la positionne.
+	$('#notify_search').css(
+	{
+		top: -notifyTop,
+		left: -notifyLeft + search_left
+	});
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Affichage de la notification de recherche & de swipe dans une vidéo de recherche.
+*/
+mosaic.prototype.searchSearchAndSwipe = function(direction)
+{
+	if(this.currentMode != 'SEARCH' || this.isCurrentlyInASearchByGesture || !this.isSwipe)
+	{
+		return;
+	}
+	
+	var _this = this;
+	
+	//On spécifie les notifications en div.
+	var notification_search = "<div id='notify_search' class='notifications'></div>";
+	var notification_swipe = "<div id='notify_swipe' class='notifications'></div>";
+	
+	//On les ajoute à la mosaïque.
+	$('body').append(notification_search + notification_swipe);
+	
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var search_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
+	var swipe_left = search_left + notify_width + notify_margin;
+	
+	// var notifyTop = this.notifyTopVideo, notifyLeft = this.notifyLeftVideo;
+	var notifyTop = 0, notifyLeft = 0;
+	
+	//On les positionne.
+	$('#notify_search').css(
+	{
+		top: -notifyTop,
+		left: -notifyLeft + search_left
+	});
+	$('#notify_swipe').css(
+	{
+		top: -notifyTop,
+		left: -notifyLeft + swipe_left,
+		'background-image': 'url(./pictos/notifications/swipe_' + direction + '.png)'
+	});
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Affichage de la notification de recherche, de move vers un voisin & de dézoom dans une vidéo de recherche.
+*/
+mosaic.prototype.searchSearchAndMoveAndUnzoom = function(targetId)
+{
+	if(this.currentMode != 'SEARCH' || this.isCurrentlyInASearchByGesture)
+	{
+		return;
+	}
+	
+	//On spécifie les notifications en div.
+	var notification_search = "<div id='notify_search' class='notifications'></div>";
+	var notification_move = "<div id='notify_move' class='notifications'></div>";
+	var notification_unzoom = "<div id='notify_unzoom' class='notifications'></div>";
+	
+	//On les ajoute à la mosaïque.
+	$('body').append(notification_search + notification_move + notification_unzoom);
+	
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var search_left = $(window).width() / 2 - (notify_width * 3 + notify_margin * 4) / 2;
+	var move_left = search_left + notify_width + notify_margin;
+	var unzoom_left = move_left + notify_width + notify_margin;
+	
+	var side = $.inArray(parseInt(targetId), this.neighboursIds);
+	
+	if(side == -1)
+	{
+		return;
+	}
+	
+	var sides = ['left', 'right', 'up', 'down'];
+	var unzooms = ['horizontal', 'vertical'];
+	
+	// var notifyTop = this.notifyTopVideo, notifyLeft = this.notifyLeftVideo;
+	var notifyTop = 0, notifyLeft = 0;
+	
+	//On les positionne.
+	$('#notify_search').css(
+	{
+		top: -notifyTop,
+		left: -notifyLeft + search_left
+	});
+	$('#notify_move').css(
+	{
+		top: -notifyTop,
+		left: -notifyLeft + move_left,
+		'background-image': 'url(./pictos/notifications/move_' + sides[side] + '.png)'
+	});
+	$('#notify_unzoom').css(
+	{
+		top: -notifyTop,
+		left: -notifyLeft + unzoom_left,
+		'background-image': 'url(./pictos/notifications/unzoom_' + unzooms[Math.floor(side / 2)] + '.png)'
+	});
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Affichage de la notification de recherche & de dézoom dans une vidéo de recherche.
+*/
+mosaic.prototype.searchSearchAndUnzoom = function()
+{
+	if(this.currentMode != 'SEARCH' || this.isCurrentlyInASearchByGesture)
+	{
+		return;
+	}
+	
+	var _this = this;
+	
+	//On spécifie les notifications en div.
+	var notification_search = "<div id='notify_search' class='notifications'></div>";
+	var notification_unzoom = "<div id='notify_unzoom' class='notifications'></div>";
+	
+	//On les ajoute à la mosaïque.
+	$('body').append(notification_search + notification_unzoom);
+	
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var search_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
+	var unzoom_left = search_left + notify_width + notify_margin;
+	
+	var side = $.inArray(parseInt(targetId), this.neighboursIds);
+	// console.log(this.neighboursIds, parseInt(targetId), side);
+	if(side == -1)
+	{
+		return;
+	}
+	
+	var unzooms = ['horizontal', 'vertical'];
+	
+	// var notifyTop = this.notifyTopVideo, notifyLeft = this.notifyLeftVideo;
+	var notifyTop = 0, notifyLeft = 0;
+	
+	//On les positionne.
+	$('#notify_move').css(
+	{
+		top: -notifyTop,
+		left: -notifyLeft + search_left
+	});
+	
+	$('#notify_unzoom').css(
+	{
+		top: -notifyTop,
+		left: -notifyLeft + unzoom_left,
+		'background-image': 'url(./pictos/notifications/unzoom_' + unzooms[Math.floor(side / 2)] + '.png)'
+	});
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Affichage de la notification de résultat dans une vidéo de recherche.
+*/
+mosaic.prototype.searchGesture = function(gestureName, mode)
+{
+	if(this.currentMode != 'SEARCH' || !this.isCurrentlyInASearchByGesture)
+	{
+		return;
+	}
+	
+	var _this = this;
+	
+	//On spécifie les notifications en div.
+	var notification_search_1gesture = "<div id='notify_search_1gesture' class='notifications'></div>";
+	
+	//On les ajoute à la mosaïque.
+	$('body').append(notification_search_1gesture);
+	
+	// console.log(this.player.config.gui.zoomTop + " " + this.player.config.gui.zoomLeft);
+	
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var point_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
+	
+	if(_.include(this.gestures, gestureName))
+	{
+		$('#notify_search_1gesture').css('background-image', 'url("./pictos/big/' + mode + '/' + gestureName + '.png")');
+	}
+	else if(mode == 'none')
+	{
+		$('#notify_search_1gesture').css('background-image', 'url("./pictos/big/normal/inconnu.png")');
+	}
+	
+	//On les positionne.
+	$('#notify_search_1gesture').css(
+	{
+		top: 0,
+		left: ($(window).width() - notify_width) / 2
+	});
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Affichage de la notification de résultat & de swipe dans une vidéo de recherche.
+*/
+mosaic.prototype.searchGestureAndSwipe = function(gestureName, mode, direction)
+{
+	if(this.currentMode != 'SEARCH' || !this.isCurrentlyInASearchByGesture || !this.isSwipe)
+	{
+		return;
+	}
+	
+	var _this = this;
+	
+	//On spécifie les notifications en div.
+	var notification_search_1gesture = "<div id='notify_search_1gesture' class='notifications'></div>";
+	var notification_swipe = "<div id='notify_swipe' class='notifications'></div>";
+	
+	//On les ajoute à la mosaïque.
+	$('body').append(notification_search_1gesture + notification_swipe);
+	
+	// console.log(this.player.config.gui.zoomTop + " " + this.player.config.gui.zoomLeft);
+	
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var search_1gesture_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
+	var swipe_left = search_1gesture_left + notify_width + notify_margin;
+	
+	if(_.include(this.gestures, gestureName))
+	{
+		$('#notify_search_1gesture').css('background-image', 'url("./pictos/big/' + mode + '/' + gestureName + '.png")');
+	}
+	else if(mode == 'none')
+	{
+		$('#notify_search_1gesture').css('background-image', 'url("./pictos/big/normal/inconnu.png")');
+	}
+	
+	//On les positionne.
+	$('#notify_search_1gesture').css(
+	{
+		left: search_1gesture_left
+	});
+	$('#notify_swipe').css(
+	{
+		left: swipe_left,
+		'background-image': 'url(./pictos/notifications/swipe_' + direction + '.png)'
+	});
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Affichage de la notification de résultat, de move vers un voisin & de dézoom dans une vidéo de recherche.
+*/
+mosaic.prototype.searchGestureAndMoveAndUnzoom = function(gestureName, mode, targetId)
+{
+	if(this.currentMode != 'SEARCH' || !this.isCurrentlyInASearchByGesture)
+	{
+		return;
+	}
+	
+	var _this = this;
+	
+	//On spécifie les notifications en div.
+	var notification_search_1gesture = "<div id='notify_search_1gesture' class='notifications'></div>";
+	var notification_move = "<div id='notify_move' class='notifications'></div>";
+	var notification_unzoom = "<div id='notify_unzoom' class='notifications'></div>";
+	
+	//On les ajoute à la mosaïque.
+	$('body').append(notification_search_1gesture + notification_move + notification_unzoom);
+	
+	// console.log(this.player.config.gui.zoomTop + " " + this.player.config.gui.zoomLeft);
+	
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var search_1gesture_left = $(window).width() / 2 - (notify_width * 3 + notify_margin * 4) / 2;
+	var move_left = search_1gesture_left + notify_width + notify_margin;
+	var unzoom_left = move_left + notify_width + notify_margin;
+	
+	if(_.include(this.gestures, gestureName))
+	{
+		$('#notify_search_1gesture').css('background-image', 'url("./pictos/big/' + mode + '/' + gestureName + '.png")');
+	}
+	else if(mode == 'none')
+	{
+		$('#notify_search_1gesture').css('background-image', 'url("./pictos/big/normal/inconnu.png")');
+	}
+	
+	var side = $.inArray(parseInt(targetId), this.neighboursIds);
+	
+	if(side == -1)
+	{
+		return;
+	}
+	
+	var sides = ['left', 'right', 'up', 'down'];
+	var unzooms = ['horizontal', 'vertical'];
+	
+	//On les positionne.
+	$('#notify_search_1gesture').css(
+	{
+		left: search_1gesture_left
+	});
+	$('#notify_move').css(
+	{
+		left: move_left,
+		'background-image': 'url(./pictos/notifications/move_' + sides[side] + '.png)'
+	});
+	$('#notify_unzoom').css(
+	{
+		left: unzoom_left,
+		'background-image': 'url(./pictos/notifications/unzoom_' + unzooms[Math.floor(side / 2)] + '.png)'
+	});
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Affichage de la notification de résultat & de dézoom dans une vidéo de recherche.
+*/
+mosaic.prototype.searchGestureAndUnzoom = function()
+{
+	if(this.currentMode != 'SEARCH' || !this.isCurrentlyInASearchByGesture)
+	{
+		return;
+	}
+	
+	var _this = this;
+	
+	//On spécifie les notifications en div.
+	var notification_search_1gesture = "<div id='notify_search_1gesture' class='notifications'></div>";
+	var notification_unzoom = "<div id='notify_unzoom' class='notifications'></div>";
+	
+	//On les ajoute à la mosaïque.
+	$('body').append(notification_search_1gesture + notification_unzoom);
+	
+	// console.log(this.player.config.gui.zoomTop + " " + this.player.config.gui.zoomLeft);
+	
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
+	var notify_margin = parseInt($('.notifications').css('margin'));
+	var search_1gesture_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
+	var unzoom_left = search_1gesture_left + notify_width + notify_margin;
+	
+	if(_.include(this.gestures, gestureName))
+	{
+		$('#notify_search_1gesture').css('background-image', 'url("./pictos/big/' + mode + '/' + gestureName + '.png")');
+	}
+	else if(mode == 'none')
+	{
+		$('#notify_search_1gesture').css('background-image', 'url("./pictos/big/normal/inconnu.png")');
+	}
+	
+	//On les positionne.
+	$('#notify_search_1gesture').css(
+	{
+		left: search_1gesture_left
+	});
+	$('#notify_unzoom').css(
+	{
+		left: unzoom_left
+	});
+	
+	//On les fait apparaître.
+	$('.notifications').css(
+	{
+		opacity: "0.9"
+	});
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/front_idill/src/mosaic/js/playerControl.js	Fri Jun 29 16:16:24 2012 +0200
@@ -0,0 +1,122 @@
+mosaic.prototype.playNextVideo = function()
+{
+	var videoId = this.centerId, nextId = (+videoId + 1);
+	
+	//Si on arrive à la fin de la mosaique on revient au début.
+	if(videoId >= this.config['imagesToShow'] - 1)
+	{
+		nextId = 0;
+	}
+	
+	//Si la mosaique est filtrée, on passe directement à la prochaine vidéo non filtrée.
+	if(this.isMosaicFiltered)
+	{
+		while(this.opacities[nextId] == 0 && nextId < this.config['imagesToShow'])
+		{
+			nextId++;
+		}
+		
+		if(nextId == this.config['imagesToShow'])
+		{
+			nextId = 0;
+			// return;
+		}
+	}
+	
+	console.log('movetonext');
+	this.autoMove = true;
+	console.log('dep : ' + this.centerId + ' next : ' + nextId);
+	this.moveToNeighbour($('#snapshotDiv-' + nextId));
+}
+
+mosaic.prototype.isTLSelected = function(entering, mainPointer)
+{
+	//Si les deux pointeurs ne sont pas là ou qu'on n'est pas en lecture d'une vidéo.
+	if(this.isMainPointerDisplayed && this.isSecondPointerDisplayed || this.currentMode != 'VIDEO' && this.currentMode != 'SEARCH' && this.currentMode != 'TIMELINE' || !this.playerIsReady)
+	{
+		// $('.a').remove();
+		return false;
+	}
+	
+	var pointer = (mainPointer ? $('#mainPointer') : $('#secondPointer'));
+	
+	var TL = $('.Ldt-Timeline');
+	var TLwidth = TL.width(), TLheight = TL.height();
+	var TLtop = (+$('.LdtPlayer').position().top + $('.LdtPlayer').height() - TLheight), TLleft = $('.LdtPlayer').position().left;
+	var Px = pointer.position().left + pointer.width() / 2, Py = pointer.position().top + pointer.height() / 2;
+	
+	var correctHorizontalPosition = (entering ? (Px > TLleft && Px < (+TLleft + TLwidth)) : (true));
+	
+	//Seulement avec une main.
+	// if(this.isMainPointerDisplayed && !this.isSecondPointerDisplayed && correctHorizontalPosition && Py > (TLtop - TLheight / 2) && Py < (+TLtop + TLheight))
+	
+	if(correctHorizontalPosition && Py > (TLtop - TLheight / 2) && Py < (+TLtop + TLheight))
+	{
+		// if($('.a').length < 1)
+			// $('body').append('<div class="a" style="position: absolute; background-color: #fff; top: ' + (TLtop - TLheight / 2) + 'px; left: ' + TLleft + 'px; height: ' + (TLheight * 3 / 2) +'px; width: ' + TLwidth + 'px"></div>');
+		return true;
+	}
+	
+	// $(".a").remove();
+	return false;
+}
+
+mosaic.prototype.exitTimeline = function(typeOfInteraction)
+{
+	if(this.currentMode == 'TIMELINE' && this.playerIsReady)
+	{
+		console.log('(5) QUIT');
+		// console.trace();
+		$('.notifications').remove();
+		
+		this.isTLRequested = false;
+		this.canSlideInTL = false;
+		this.player.widgets[0].deselectTimeline();
+		
+		if($('#spinner').length > 0)
+		{
+			$('#spinner').remove();
+		}
+		
+		if(this.isTLSelectedByMainPointer)
+		{
+			$('#mainPointer').css('background-image', 'url(./img/cursors/pointer.png)');
+		}
+		if(this.isTLSelectedBySecondPointer)
+		{
+			$('#secondPointer').css('background-image', 'url(./img/cursors/pointer2.png)');
+		}
+		
+		this.isTLSelectedByMainPointer = false;
+		this.isTLSelectedBySecondPointer = false;
+		
+		if(typeOfInteraction == 'unzoom')
+		{
+			if(this.isMosaicFiltered)
+			{
+				this.currentMode = 'FILTER';
+			}
+			else
+			{
+				this.currentMode = 'MOSAIC';
+			}
+		}
+		else if(typeOfInteraction == 'move')
+		{
+			this.currentMode = 'VIDEO';
+		}
+		else
+		{
+			if(this.isCurrentlyInASearchByGesture)
+			{
+				this.currentMode = 'SEARCH';
+				
+				this.searchGesture(this.currentSearchGesture, 'valid');
+			}
+			else
+			{
+				this.currentMode = 'VIDEO';
+			}
+		}
+	}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/front_idill/src/mosaic/js/pointers.js	Fri Jun 29 16:16:24 2012 +0200
@@ -0,0 +1,952 @@
+/*
+ * Affiche les pointeurs.
+*/
+mosaic.prototype.addPointers = function()
+{
+	var mainPointer = '<div id="mainPointer" class="pointers"></div>';
+	var secondPointer = '<div id="secondPointer" class="pointers"></div>';
+	$('body').append(mainPointer + secondPointer);
+	
+	$('#secondPointer').css(
+	{
+		top: $(window).height() / 2 - $('#secondPointer').height() / 2,
+		left: $(window).width() / 4 - $('#secondPointer').width() / 2
+	});
+	
+	this.secondPointerLastX = $(window).width() / 4 - $('#secondPointer').width() / 2;
+	this.secondPointerLastY = $(window).height() / 2 - $('#secondPointer').height() / 2;
+	
+	$('#mainPointer').css(
+	{
+		top: $(window).height() / 2 - $('#mainPointer').height() / 2,
+		left: $(window).width() * 3 / 4 - $('#mainPointer').width() / 2
+	});
+
+	this.mainPointerLastX = $(window).width() * 3 / 4 - $('#mainPointer').width() / 2;
+	this.mainPointerLastY = $(window).height() / 2 - $('#mainPointer').height() / 2;
+	
+	this.mainPointerIdleStartX = this.mainPointerLastX;
+	this.mainPointerIdleStartY = this.mainPointerLastY;
+	this.secondPointerIdleStartX = this.secondPointerLastX;
+	this.secondPointerIdleStartY = this.secondPointerLastY;
+}
+
+/*
+ * Affiche/Masque le pointeur principal.
+ * Main est un booléen valant vrai s'il faut afficher le pointeur.
+*/
+mosaic.prototype.mainPointerDisplay = function(main)
+{
+	var _this = this;
+	
+	//On n'affiche pas les pointeurs dans le mode sans utilisateur ni utilisateur en phase d'approche.
+	if(this.currentMode != 'NO-USER' && this.currentMode.indexOf('INCOMING-') == -1)
+	{
+		if(main)
+		{
+			clearTimeout(this.arrowSpinnerTimeout);
+			
+			$('#mainPointer').fadeTo(this.config['timeFilling'], '1');
+			
+			//Si on a un seul pointeur, on affiche la mire.
+			if(!this.areBothPointersHere)
+			{
+				// console.log('ONE');
+				/*$('#mainPointer').css(
+				{
+					'background-image': 'url(./img/cursors/selector_gray.png)',
+					width: 85,
+					height: 85
+				});*/
+			}
+		}
+	}
+	
+	//Si le booléen est à faux, on masque le pointeur.
+	if(!main)
+	{
+		$('#spinner').remove();
+		
+		$('#mainPointer').fadeTo(this.config['timeFilling'], '0');
+		if(this.mainPointerNeighbourSelectedId != null)
+		{
+			// this.deselectNeighbour(this.mainPointerNeighbourSelectedId);
+		}
+		
+		//Si on a zoomé sur une vidéo.
+		if(this.currentMode == 'VIDEO' || this.currentMode == 'SEARCH')
+		{
+			//On annule aussi la TL s'il y a lieu.
+			if(this.isTLSelected())
+			{
+				this.isTLRequested = false;
+				clearTimeout(this.selectTLTimeout);
+			}
+		}
+		
+		if(this.isTLSelectedByMainPointer)
+		{
+			//On déselectionne la TL.
+			this.exitTimeline('');
+		}
+	}
+}
+/*
+ * Affiche/Masque le pointeur secondaire.
+ * Main est un booléen valant vrai s'il faut afficher le pointeur.
+*/
+mosaic.prototype.secondPointerDisplay = function(second)
+{
+	//On n'affiche pas les pointeurs dans le mode sans utilisateur ni utilisateur en phase d'approche.
+	if(this.currentMode != 'NO-USER' && this.currentMode.indexOf('INCOMING-') == -1)
+	{
+		if(second)
+		{
+			clearTimeout(this.arrowSpinnerTimeout);
+			
+			$('#secondPointer').fadeTo(this.config['timeFilling'], '1');
+			
+			//Si on a un seul pointeur, on affiche la mire.
+			if(!this.areBothPointersHere)
+			{
+				// console.log('ONE');
+				/*$('#secondPointer').css(
+				{
+					'background-image': 'url(./img/cursors/selector_gray.png)',
+					width: 85,
+					height: 85
+				});*/
+			}
+		}
+	}
+	
+	//Si le booléen est à faux, on masque le pointeur.
+	if(!second)
+	{
+		$('#spinner').remove();
+		
+		$('#secondPointer').fadeTo(this.config['timeFilling'], '0');
+		if(this.secondPointerNeighbourSelectedId != null)
+		{
+			// this.deselectNeighbour(this.secondPointerNeighbourSelectedId);
+		}
+		
+		if(this.isTLSelectedBySecondPointer)
+		{
+			//On déselectionne la TL.
+			this.exitTimeline('');
+		}
+	}
+}
+
+/*
+ * Raffraîchit la position des pointeurs.
+*/
+mosaic.prototype.refreshMainPointer = function(x, y)
+{
+	// console.log('                                    DEBUG MP');
+	if(this.currentMode == "NO-USER" || this.currentMode.indexOf('INCOMING-') != -1)
+	{
+		return;
+	}
+	
+	if(!this.mouseInteractions)
+	{
+		x *= 7;
+		y *= 7;
+		x -= $(window).width() * 3 / 4;
+		y -= $(window).height() * 2 / 4;
+	}
+	
+	//Si le pointeur quitte la fenêtre en X, on ne le change pas.
+	// console.log('x : ' + x + ' mplx : ' + this.mainPointerLastX);
+	if(x < 0 || x > $(window).width())
+	{
+		x = this.mainPointerLastX;
+	}
+	//Sinon, on le met à jour.
+	else
+	{
+		this.mainPointerLastX = x;
+	}
+	
+	//Si le pointeur quitte la fenêtre en Y, on ne le change pas.
+	if(y < 0 || y > $(window).height())
+	{
+		y = this.mainPointerLastY;
+	}
+	//Sinon, on le met à jour.
+	else
+	{
+		this.mainPointerLastY = y;
+	}
+	
+	var pointerX = x - $('#mainPointer').width()/2, pointerY = y - $('#mainPointer').height()/2;
+	var _this = this;
+	
+	$('#mainPointer').css(
+	{
+		top: pointerY,
+		left: pointerX
+	});
+	
+	if($('#spinner').length > 0)
+	{
+		$('#spinner').css(
+		{
+			top: pointerY,
+			left: pointerX
+		});
+	}
+	
+	var snapshot = null;
+	
+	if(this.currentMode == 'MOSAIC' || this.currentMode == 'FILTER' && this.isMosaicFiltered)
+	{
+		snapshot = this.pointerPositionToSN(pointerX, pointerY, true);
+		
+		if(this.previousZoomedSN != null)
+		{
+			var id = this.previousZoomedSN.attr('id').replace('snapshotDiv-', '');
+		}
+		
+		if(snapshot == null)
+		{
+			this.isOnASnapshot = false;
+			this.lastNonNullSN = this.previousZoomedSN;
+			this.preUnzoom();
+			
+			$('#mainPointer').css('background-image', 'url(./img/cursors/pointer.png)');
+		}
+		
+		if(!this.isSecondPointerDisplayed && snapshot != null && (this.previousZoomedSN != null && snapshot.attr('id') !== this.previousZoomedSN.attr('id') || this.lastNonNullSN != null && snapshot.attr('id') === this.lastNonNullSN.attr('id')) && !this.areBothPointersHere)
+		{
+			this.isOnASnapshot = true;
+			this.previousZoomedSN = snapshot;
+			this.lastNonNullSN = null;
+			this.preZoom(snapshot);
+			
+			$('#mainPointer').css('background-image', 'url(./img/cursors/selector_gray.png)');
+			// console.log(this.isMainPointerDisplayed + ' ' + this.isSecondPointerDisplayed);
+		}
+		
+		//Si on se trouve actuellement dans une recherche par gestures.
+		// /!\ // RAJOUTE EN ATTENDANT UN GESTE DE CANCEL.
+		if(this.isMosaicFiltered && !this.isMosaicFiltering)
+		{
+			console.log('CHECK IF ON NOTIFY GESTURE');
+			this.checkIfPointerIsOnSearchNotification(pointerX, pointerY, $('#mainPointer'));
+		}
+	}
+	else if(this.currentMode == 'VIDEO' || this.currentMode == 'SEARCH' || this.currentMode == 'TIMELINE')
+	{
+		//On vérifie si on veut sélectionner la TL.
+		if((this.currentMode != 'TIMELINE' || this.isTLRequested) && this.playerIsReady && !this.isTLSelectedBySecondPointer && !this.helpDisplayed)
+		{
+			// console.log('(1) SP : ' + this.isTLSelectedBySecondPointer + ' MP : ' + this.isTLSelectedByMainPointer);
+			if(this.isTLSelected(true, true) && !this.isTLRequested)
+			{
+				// console.log('(2) TIMELINE REQUESTED ' + this.date());
+				// $('.a').css('background-color', '#f00');
+				//On a demandé à aller dans la TL.
+				this.isTLRequested = true;
+				this.isTLSelectedByMainPointer = true;
+				this.isTLSelectedBySecondPointer = false;
+				// console.log('(1) SP : ' + this.isTLSelectedBySecondPointer + ' MP : ' + this.isTLSelectedByMainPointer);
+				this.currentMode = 'TIMELINE';
+				this.player.widgets[0].selectTimeline();
+				$('#mainPointer').css('background-image', 'url(./img/cursors/selector_gray.png)');
+				
+				//On met le spinner gif sur le pointeur.
+				var spinner = "<img id='spinner'></div>";
+				$('body').append(spinner);
+				$('#spinner').css(
+				{
+					position: 'absolute',
+					top: $('#mainPointer').position().top,
+					left: $('#mainPointer').position().left,
+					width: 85,
+					height: 85,
+					'z-index': 600
+				});
+				$('#spinner').attr('src', './img/cursors/selector_anim.gif');
+				
+				this.selectTLTimeout = setTimeout(function()
+				{
+					//On permet l'interaction après un laps de temps.
+					_this.canSlideInTL = true;
+					
+					$('.notifications').remove();
+					_this.timelineTimeline();
+					
+					// console.log('(4) TIMELINE SLIDE ' + _this.date());
+				}, this.config['timeoutSlideTL']);
+			}
+			else if(!this.isTLSelected(true, true) && this.isTLRequested)
+			{
+				// console.log('(3) TIMELINE ABORTED');
+				this.isTLRequested = false;
+				clearTimeout(this.selectTLTimeout);
+				//On déselectionne la TL.
+				this.exitTimeline('');
+			}
+		}
+		
+		if(this.isTLSelectedByMainPointer && !this.isTLSelected(false, true))
+		{
+			// console.log('(4) TIMELINE EXITED');
+			// $('.a').css('background-color', '#0f0');
+			
+			//On déselectionne la TL.
+			this.exitTimeline('');
+		}
+
+		// var zoomX = pointerX, zoomY = pointerY;
+		var zoomX = pointerX - this.notifyLeftVideo, zoomY = pointerY - this.notifyTopVideo;
+		
+		//Si on a sélectionné la TL et qu'on a le pointeur droit dessus, on peut modifier la position de lecture.
+		if(this.currentMode == 'TIMELINE' && this.playerIsReady && !this.isSecondPointerDisplayed && this.canSlideInTL)
+		{
+			var time, TL = $('.Ldt-Timeline'), P = $('.LdtPlayer');
+			
+			if(pointerX < P.position().left)
+			{
+				time = 0;
+				// console.log('trop à droite');
+			}
+			else if(pointerX > (+P.position().left + TL.width()))
+			{
+				time = this.player.widgets[0].source.getDuration().getSeconds();
+				// console.log('trop à gauche');
+				// time = 0;
+			}
+			else
+			{
+				time = this.player.widgets[0].scaleIntervals(P.position().left, (+P.position().left + TL.width()), 0, this.player.widgets[0].source.getDuration().getSeconds(), pointerX);
+				// console.log(time);
+			}
+			
+			this.player.popcorn.currentTime(time);
+		}
+		
+		
+		//Si on se trouve actuellement dans une recherche par gestures.
+		if(this.isCurrentlyInASearchByGesture)
+		{
+			this.checkIfPointerIsOnSearchNotification(pointerX, pointerY, $('#mainPointer'));
+		}
+		
+		//on vérifie si le pointeur est sur un snapshot zoomé.
+		snapshot = this.pointerPositionToSN(zoomX, zoomY, true);
+		if(snapshot == null)
+		{
+			$('#mainPointer').css('background-image', 'url(./img/cursors/pointer.png)');
+			snapshot = this.pointerPositionToAN(pointerX, pointerY);
+		}
+		
+		// console.log(snapshot);
+		
+		var intValueOfId;
+		//Si c'est le cas.
+		if(snapshot != null && snapshot.length > 0)
+		{
+			//S'il s'agit d'un voisin additionnel.
+			if(snapshot.attr('id').indexOf('borderNeighbour') != -1)
+			{
+				intValueOfId = parseInt(snapshot.attr('id').replace('borderNeighbour-', ''));
+			}
+			//Sinon si c'est un voisin normal.
+			else
+			{
+				intValueOfId = parseInt(snapshot.attr('id').replace('snapshotDiv-', ''));
+			}
+		}
+		else
+		{
+			intValueOfId = -2;
+		}
+		
+		//Si c'est un voisin additionnel.
+		if(snapshot != null && snapshot.attr('id').indexOf('borderNeighbour') != -1)
+		{
+			//S'il a été trouvé.
+			if(intValueOfId > -1 && intValueOfId < 5)
+			{
+				//On le sélectionne.
+				this.selectNeighbour(snapshot, $('#mainPointer'));
+				this.mainPointerExitBorder = true;
+				this.mainPointerNeighbourSelectedId = intValueOfId + this.config['imagesToShow'];
+			}
+			else
+			{
+				if(this.mainPointerNeighbourSelectedId != null && this.mainPointerNeighbourSelectedId > -1)
+				{
+					this.deselectNeighbour(this.mainPointerNeighbourSelectedId);
+				}
+			}
+		}
+		else
+		{
+			//Si c'est un voisin.
+			if(_.include(this.neighboursIds, intValueOfId))
+			{
+				//On le sélectionne.
+				this.selectNeighbour(snapshot, $('#mainPointer'));
+				clearTimeout(this.moveToNeighbourTimeout);
+				clearTimeout(this.mainPointerExitBorderTimeout);
+				this.mainPointerExitBorder = true;
+				this.mainPointerNeighbourSelectedId = intValueOfId;
+			}
+			else
+			{
+				if(this.mainPointerNeighbourSelectedId != null && this.mainPointerNeighbourSelectedId > -1)
+				{
+					this.deselectNeighbour(this.mainPointerNeighbourSelectedId);
+					
+					if(this.mainPointerExitBorder && !this.secondPointerExitBorder)
+					{
+						this.correctMoveToNeighbour(this.mainPointerNeighbourSelectedId, zoomX, zoomY);
+					}
+					
+					this.moveToNeighbourTimeout = setTimeout(function()
+					{
+						_this.canMoveToNeighbour = false;
+					}, this.config['timeoutMoveToNeighbour']);
+					
+					this.mainPointerExitBorderTimeout = setTimeout(function()
+					{
+						if(_this.mainPointerExitBorder)
+						{
+							// console.log('Main pointer left');
+						}
+						_this.mainPointerExitBorder = false;
+					}, this.config['timeoutUnzoom']);
+					
+					this.checkForDezoom();
+				}
+			}
+		}
+	}
+}
+
+mosaic.prototype.refreshSecondPointer = function(x, y)
+{
+	if(this.currentMode == "NO-USER" || this.currentMode.indexOf('INCOMING-') != -1)
+	{
+		return;
+	}
+	
+	if(!this.mouseInteractions)
+	{
+		x *= 7;
+		y *= 7;
+		x -= $(window).width() * 3 / 4;
+		y -= $(window).height() * 2 / 4;
+	}
+	
+	//Si le pointeur quitte la fenêtre en X, on ne le change pas.
+	if(x < 0 || x > $(window).width())
+	{
+		x = this.secondPointerLastX;
+	}
+	//Sinon, on le met à jour.
+	else
+	{
+		this.secondPointerLastX = x;
+	}
+	
+	//Si le pointeur quitte la fenêtre en Y, on ne le change pas.
+	if(y < 0 || y > $(window).height())
+	{
+		y = this.secondPointerLastY;
+	}
+	//Sinon, on le met à jour.
+	else
+	{
+		this.secondPointerLastY = y;
+	}
+	
+	var pointerX = x - $('#secondPointer').width()/2, pointerY = y - $('#secondPointer').height()/2;
+	var _this = this;
+	
+	$('#secondPointer').css(
+	{
+		top: pointerY,
+		left: pointerX
+	});
+	
+	var snapshot = null;
+	
+	if(this.currentMode == 'MOSAIC' || this.currentMode == 'FILTER' && this.isMosaicFiltered)
+	{
+		snapshot = this.pointerPositionToSN(pointerX, pointerY, false);
+		
+		if(this.previousZoomedSN != null)
+		{
+			var id = this.previousZoomedSN.attr('id').replace('snapshotDiv-', '');
+		}
+		
+		if(snapshot == null)
+		{
+			this.isOnASnapshot = false;
+			this.lastNonNullSN = this.previousZoomedSN;
+			this.preUnzoom();
+			
+			$('#secondPointer').css('background-image', 'url(./img/cursors/pointer2.png)');
+		}
+		
+		if(!this.isMainPointerDisplayed && snapshot != null && (this.previousZoomedSN != null && snapshot.attr('id') !== this.previousZoomedSN.attr('id') || this.lastNonNullSN != null && snapshot.attr('id') === this.lastNonNullSN.attr('id')) && !this.areBothPointersHere)
+		{
+			this.isOnASnapshot = true;
+			this.previousZoomedSN = snapshot;
+			this.lastNonNullSN = null;
+			this.preZoom(snapshot);
+			
+			$('#secondPointer').css('background-image', 'url(./img/cursors/selector_gray.png)');
+			// console.log(this.isMainPointerDisplayed + ' ' + this.isSecondPointerDisplayed);
+		}
+		
+		//Si on se trouve actuellement dans une recherche par gestures.
+		// /!\ // RAJOUTE EN ATTENDANT UN GESTE DE CANCEL.
+		if(this.isMosaicFiltered && !this.isMosaicFiltering)
+		{
+			this.checkIfPointerIsOnSearchNotification(pointerX, pointerY, $('#secondPointer'));
+		}
+	}
+	else if(this.currentMode == 'VIDEO' || this.currentMode == 'SEARCH' || this.currentMode == 'TIMELINE')
+	{
+		//On vérifie si on veut sélectionner la TL.
+		if((this.currentMode != 'TIMELINE' || this.isTLRequested) && this.playerIsReady && !this.isTLSelectedByMainPointer && !this.helpDisplayed)
+		{
+			// console.log('(1) SP : ' + this.isTLSelectedBySecondPointer + ' MP : ' + this.isTLSelectedByMainPointer);
+			if(this.isTLSelected(true, false) && !this.isTLRequested)
+			{
+				// console.log('(2) TIMELINE REQUESTED ' + this.date());
+				// $('.a').css('background-color', '#f00');
+				//On a demandé à aller dans la TL.
+				this.isTLRequested = true;
+				this.isTLSelectedBySecondPointer = true;
+				this.isTLSelectedByMainPointer = false;
+				// console.log('(1) SP : ' + this.isTLSelectedBySecondPointer + ' MP : ' + this.isTLSelectedByMainPointer);
+				this.currentMode = 'TIMELINE';
+				this.player.widgets[0].selectTimeline();
+				$('#secondPointer').css('background-image', 'url(./img/cursors/selector_gray.png)');
+				
+				//On met le spinner gif sur le pointeur.
+				var spinner = "<div id='spinner'></div>";
+				$('body').append(spinner);
+				$('#spinner').css(
+				{
+					position: 'absolute',
+					'background-repeat': 'no-repeat',
+					top: $('#mainPointer').position().top,
+					left: $('#mainPointer').position().left,
+					width: 85,
+					height: 85,
+					'z-index': 600
+				});
+				$('#spinner').attr('src', './img/cursors/selector_anim.gif');
+				
+				this.selectTLTimeout = setTimeout(function()
+				{
+					//On permet l'interaction après un laps de temps.
+					_this.canSlideInTL = true;
+					
+					$('.notifications').remove();
+					_this.timelineTimeline();
+					
+					// console.log('(4) TIMELINE SLIDE ' + _this.date());
+				}, this.config['timeoutSlideTL']);
+			}
+			else if(!this.isTLSelected(true, false) && this.isTLRequested)
+			{
+				// console.log('(3) TIMELINE ABORTED');
+				this.isTLRequested = false;
+				clearTimeout(this.selectTLTimeout);
+				//On déselectionne la TL.
+				this.exitTimeline('');
+			}
+		}
+		
+		if(this.isTLSelectedByMainPointer && !this.isTLSelected(false, false))
+		{
+			// console.log('(4) TIMELINE EXITED');
+			// $('.a').css('background-color', '#0f0');
+			
+			//On déselectionne la TL.
+			this.exitTimeline('');
+		}
+		
+		// var zoomX = pointerX, zoomY = pointerY;
+		var zoomX = pointerX - this.notifyLeftVideo, zoomY = pointerY - this.notifyTopVideo;
+		
+		//Si on a sélectionné la TL et qu'on a le pointeur droit dessus, on peut modifier la position de lecture.
+		if(this.currentMode == 'TIMELINE' && this.playerIsReady && !this.isMainPointerDisplayed && this.canSlideInTL)
+		{
+			var time, TL = $('.Ldt-Timeline'), P = $('.LdtPlayer');
+			
+			if(pointerX < P.position().left)
+			{
+				time = 0;
+				// console.log('trop à droite');
+			}
+			else if(pointerX > (+P.position().left + TL.width()))
+			{
+				time = this.player.widgets[0].source.getDuration().getSeconds();
+				// console.log('trop à gauche');
+				// time = 0;
+			}
+			else
+			{
+				time = this.player.widgets[0].scaleIntervals(P.position().left, (+P.position().left + TL.width()), 0, this.player.widgets[0].source.getDuration().getSeconds(), pointerX);
+				// console.log(time);
+			}
+			
+			this.player.popcorn.currentTime(time);
+		}
+		
+		//Si on se trouve actuellement dans une recherche par gestures.
+		if(this.isCurrentlyInASearchByGesture)
+		{
+			this.checkIfPointerIsOnSearchNotification(pointerX, pointerY, $('#secondPointer'));
+		}
+		
+		//on vérifie si le pointeur est sur un snapshot zoomé.
+		snapshot = this.pointerPositionToSN(zoomX, zoomY, false);
+		if(snapshot == null)
+		{
+			$('#secondPointer').css('background-image', 'url(./img/cursors/pointer2.png)');
+			snapshot = this.pointerPositionToAN(pointerX, pointerY);
+		}
+		
+		var intValueOfId;
+		//Si c'est le cas.
+		if(snapshot != null && snapshot.length > 0)
+		{
+			//S'il s'agit d'un voisin additionnel.
+			if(snapshot.attr('id').indexOf('borderNeighbour') != -1)
+			{
+				intValueOfId = parseInt(snapshot.attr('id').replace('borderNeighbour-', ''));
+			}
+			//Sinon si c'est un voisin normal.
+			else
+			{
+				intValueOfId = parseInt(snapshot.attr('id').replace('snapshotDiv-', ''));
+			}
+		}
+		else
+		{
+			intValueOfId = -2;
+		}
+		
+		//Si c'est un voisin additionnel.
+		if(snapshot != null && snapshot.attr('id').indexOf('borderNeighbour') != -1)
+		{
+			//S'il a été trouvé.
+			if(intValueOfId > -1 && intValueOfId < 5)
+			{
+				//On le sélectionne.
+				this.selectNeighbour(snapshot, $('#secondPointer'));
+				this.secondPointerExitBorder = true;
+				this.secondPointerNeighbourSelectedId = intValueOfId + this.config['imagesToShow'];
+			}
+			else
+			{
+				if(this.secondPointerNeighbourSelectedId != null && this.secondPointerNeighbourSelectedId > -1)
+				{
+					this.deselectNeighbour(this.secondPointerNeighbourSelectedId);
+					
+					/*this.secondPointerExitBorderTimeout = setTimeout(function()
+					{
+						if(_this.secondPointerExitBorder)
+						{
+							console.log('Second pointer left');
+						}
+						_this.secondPointerExitBorder = false;
+					}, this.config['timeoutUnzoom']);*/
+					
+					this.checkForDezoom();
+				}
+			}
+		}
+		else
+		{
+			//Si c'est un voisin.
+			if(_.include(this.neighboursIds, intValueOfId))
+			{
+				//On le sélectionne.
+				this.selectNeighbour(snapshot, $('#secondPointer'));
+				clearTimeout(this.moveToNeighbourTimeout);
+				clearTimeout(this.secondPointerExitBorderTimeout);
+				this.secondPointerExitBorder = true;
+				this.secondPointerNeighbourSelectedId = intValueOfId;
+			}
+			else
+			{
+				if(this.secondPointerNeighbourSelectedId != null && this.secondPointerNeighbourSelectedId > -1)
+				{
+					this.deselectNeighbour(this.secondPointerNeighbourSelectedId);
+					
+					if(!this.mainPointerExitBorder && this.secondPointerExitBorder)
+					{
+						this.correctMoveToNeighbour(this.secondPointerNeighbourSelectedId, zoomX, zoomY);
+					}
+					
+					this.moveToNeighbourTimeout = setTimeout(function()
+					{
+						_this.canMoveToNeighbour = false;
+					}, this.config['timeoutMoveToNeighbour']);
+					
+					this.secondPointerExitBorderTimeout = setTimeout(function()
+					{
+						if(_this.secondPointerExitBorder)
+						{
+							// console.log('Second pointer left');
+						}
+						_this.secondPointerExitBorder = false;
+					}, this.config['timeoutUnzoom']);
+					
+					this.checkForDezoom();
+				}
+			}
+		}
+	}
+}
+
+mosaic.prototype.detectIdlePointers = function()
+{
+	var mainPointer = $('#mainPointer');
+	var secondPointer = $('#secondPointer');
+	
+	//Si la position des pointeurs au début de l'analyse d'idle change de plus ou moins leur taille par rapport à leur position actuelle.
+	if(Math.abs(this.mainPointerIdleStartX - this.mainPointerLastX) > mainPointer.width() || Math.abs(this.mainPointerIdleStartY - this.mainPointerLastY) > mainPointer.height() ||
+	Math.abs(this.secondPointerIdleStartX - this.secondPointerLastX) > secondPointer.width() || Math.abs(this.secondPointerIdleStartY - this.secondPointerLastY) > secondPointer.height())
+	{
+		//On réinitialise les dernières positions connues.
+		this.mainPointerIdleStartX = this.mainPointerLastX;
+		this.mainPointerIdleStartY = this.mainPointerLastY;
+		this.secondPointerIdleStartX = this.secondPointerLastX;
+		this.secondPointerIdleStartY = this.secondPointerLastY;
+		
+		this.removeIdlePointers();
+		this.pointersIdleNeedLaunch = true;
+	}
+	
+	if(this.helpDisplayed)
+	{
+		this.removeHelp();
+	}
+	
+	if((this.currentMode == 'SEARCH' || this.currentMode == 'FILTER') && !this.isSearchByCurvesOn)
+	{
+		// this.isSearchByCurvesOn = true;
+		// this.startSearch();
+	}
+	// console.log('DETECT IDLE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
+}
+
+mosaic.prototype.removeIdlePointers = function()
+{
+	clearTimeout(this.pointersSearchIdleTimeout);
+	// console.log(this.date() + ' - ra');
+}
+
+mosaic.prototype.launchIdlePointers = function()
+{
+	var _this = this;
+	
+	//Si on est en mode TL, on ne peut pas effectuer de recherche.
+	if(this.currentMode == 'TIMELINE' || (!this.playerIsReady && (this.currentMode == 'VIDEO' || this.currentMode == 'SEARCH')))
+	{
+		return;
+	}
+	
+	if(this.currentMode == 'VIDEO')// || this.currentMode == 'SEARCH')
+	{
+		//On peut le faire que sur la video au dessus de la TL.
+		var mainPointer = $('#mainPointer'), secondPointer = $('#secondPointer'), TL = $('.Ldt-Timeline');
+		var TLwidth = TL.width(), TLheight = TL.height();
+		var Ptop = $('.LdtPlayer').position().top, Pleft = $('.LdtPlayer').position().left;
+		var Pheight = $('.LdtPlayer').height();
+		var MPx = mainPointer.position().left + mainPointer.width() / 2, MPy = mainPointer.position().top + mainPointer.height() / 2;
+		var SPx = secondPointer.position().left + secondPointer.width() / 2, SPy = secondPointer.position().top + secondPointer.height() / 2;
+		
+		if(MPx < Pleft || MPx > (+Pleft + TLwidth) || MPy < Ptop || MPy > (+Ptop + Pheight - TLheight) ||
+		SPx < Pleft || SPx > (+Pleft + TLwidth) || SPy < Ptop || SPy > (+Ptop + Pheight - TLheight))
+		{
+			return;
+		}
+	}
+	
+	//A la fin du timeout, si rien n'est venu l'interrompre, on entre en recherche/filtrage en fonction du mode dans lequel on se trouve.
+	this.pointersSearchIdleTimeout = setTimeout(function()
+	{
+		if(!_this.areBothPointersHere)
+		{
+			return;
+		}
+		
+		// console.log('rdy for idle');
+		
+		if(_this.currentMode == "MOSAIC")
+		{
+			_this.currentMode = "FILTER";
+			// _this.currentMode = "FILTR";
+			_this.isMosaicFiltered = true;
+			
+			console.log(_this.date() + ' - ENTRE EN MODE FILTRAGE');
+			
+			$('.notifications').remove();
+			_this.filterSearch();
+		}
+		else if(_this.currentMode == "VIDEO" || _this.currentMode == "TIMELINE")
+		{
+			_this.currentMode = "SEARCH";
+			
+			console.log(_this.date() + ' - ENTRE EN MODE RECHERCHE');
+			// console.log('');
+			
+			$('.notifications').remove();
+			_this.searchSearch();
+		}
+		
+		if(!_this.canNotifyHelp)
+		{
+			_this.canNotifyHelpTimeout = setTimeout(function()
+			{
+				// console.log(_this.date() + ' CAN NOTIFY HELP');
+				_this.canNotifyHelp = true;
+			}, _this.config['timeoutCanNotifyHelp']);
+		}
+		
+		//Si on est déjà en recherche, et que l'aide n'est pas encore affichée, on l'affiche.
+		/*if(_this.currentMode == 'SEARCH' && _this.canNotifyHelp)
+		{
+			_this.notifyHelp(false);
+		}
+		if(_this.currentMode == 'FILTER' && _this.canNotifyHelp)
+		{
+			_this.notifyHelp(true);
+		}*/
+		
+	}, this.config['timeoutPointersIdle']);
+}
+
+mosaic.prototype.checkForBothPointersHere = function()
+{
+	var _this = this;
+	
+	if(!this.areBothPointersTimeoutLaunched)
+	{
+		this.areBothPointersHereTimeout = setTimeout(function()
+		{
+			_this.areBothPointersHere = false;
+			/*if(_this.isSearchByCurvesOn)
+			{
+				_this.leaveSearch();
+			}*/
+		}, this.config['timeoutAreBothPointersHere']);
+		
+		this.areBothPointersHereTimeoutLaunched = true;
+	}
+}
+
+mosaic.prototype.removeCheckForBothPointersHere = function()
+{
+	// console.log('TRY QUIT');
+	
+	// if(this.areBothPointersTimeoutLaunched)
+	// {
+		clearTimeout(this.areBothPointersHereTimeout);
+		// console.log('QUIT');
+	// }
+	this.areBothPointersHereTimeoutLaunched = false;
+}
+
+/*
+ * Vérifie si on se trouve sur la notification de recherche par gesture.
+*/
+mosaic.prototype.checkIfPointerIsOnSearchNotification = function(x, y, pointer)
+{
+	var _this = this;
+	var notification_search = $('#notify_search_1gesture');
+	
+	//Si la notification de recherche existe (dans le player).
+	if(notification_search.length > 0)
+	{
+		//Pictogramme actuel de la notification.
+		var currentPicto = notification_search.css('background-image');
+
+		//y -= this.MPTop_margin;
+		
+		/*console.log('===================================');
+		console.log('x : ' + x + ' > ' + notification_search.position().left);
+		console.log('x : ' + x + ' < ' + (+notification_search.position().left + notification_search.width()));
+		console.log('y : ' + y + ' > ' + notification_search.position().top);
+		console.log('y : ' + y + ' < ' + (+notification_search.position().top + notification_search.height()));
+		console.log('===================================');*/
+		
+		//Si le pointeur est sur la notification.
+		if(x > notification_search.position().left && x < (+notification_search.position().left + notification_search.width()) && y > notification_search.position().top && y < (+notification_search.position().top + notification_search.height()))
+		{
+			// console.log('IN NOTIFICATION');
+			if(!this.alreadyOnNotification && $('#spinner').length == 0)
+			{
+				notification_search.css('background-image', currentPicto.replace('/big/valid/', '/big/hover/'));
+				
+				console.log(this.date() + ' try remove not');
+				//On met le spinner gif sur le pointeur.
+				var spinner = "<img id='spinner'></div>";
+				$('body').append(spinner);
+				$('#spinner').css(
+				{
+					position: 'absolute',
+					top: pointer.position().top,
+					left: pointer.position().left,
+					width: 85,
+					height: 85,
+					'z-index': 600
+				});
+				$('#spinner').attr('src', './img/cursors/selector_anim.gif');
+				/*this.arrowSpinnerTimeout = setTimeout(function()
+				{
+					
+				}, this.config['timeoutRemoveSpinner']);*/
+				
+				this.removeNotificationByGestureTimeout = setTimeout(function()
+				{
+					if(_this.currentMode == 'SEARCH')
+					{
+						_this.player.widgets[0].removeSearchByGesture();
+						_this.currentMode = 'VIDEO';
+					}
+					else if(_this.currentMode == 'TIMELINE')
+					{
+						_this.player.widgets[0].removeSearchByGesture();
+						_this.currentMode = 'TIMELINE';
+					}
+					else if(_this.currentMode == 'FILTER')
+					{
+						_this.removeFilter();
+					}
+					
+					_this.alreadyOnNotification = false;
+					_this.isCurrentlyInASearchByGesture = false;
+					_this.currentSearchGesture = '';
+					_this.canNotifyHelp = false;
+				}, this.config['timeoutRemoveNotificationByGesture']);
+				this.alreadyOnNotification = true;
+			}
+		}
+		else
+		{
+			if(this.alreadyOnNotification)
+			{
+				notification_search.css('background-image', currentPicto.replace('/big/hover/', '/big/valid/'));
+				clearTimeout(this.removeNotificationByGestureTimeout);
+				this.alreadyOnNotification = false;
+				$('#spinner').remove();
+			}
+		}
+	}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/front_idill/src/mosaic/js/search.js	Fri Jun 29 16:16:24 2012 +0200
@@ -0,0 +1,293 @@
+/*
+ * Lance une recherche par courbes.
+ */
+mosaic.prototype.startSearch = function()
+{
+	var _this = this;
+	
+	var top, left, width, height, margin_top, inMosaic;
+	//Si on est dans le cas d'un filtrage de mosaïque.
+	if(this.currentMode == "FILTER")
+	{
+		var mainPanel = $('#mainPanel');
+		top = mainPanel.position().top;
+		left = mainPanel.position().left;
+		width = mainPanel.width();
+		height = mainPanel.height();
+		margin_top = this.MPTop_margin;
+		inMosaic = true;
+	}
+	//Sinon si c'est une recherche dans la vidéo.
+	else if(this.currentMode == "SEARCH")
+	{
+		top = this.snTop;
+		left = this.snLeft;
+		width = this.snWidth;
+		height = this.snHeight;
+		margin_top = '0px';
+		inMosaic = false;
+	}
+	
+	this.searchCanvas = new searchCanvas(top, left, width, height, margin_top, this.timeSearchFade, inMosaic);
+	this.searchCanvas.create();
+	
+	/*$(window).mousedown(function(e)
+	{
+		console.log('DOWN');
+		_this.searchCanvas.onPointerIn(e.clientX, e.clientY);
+		$(window).mousemove(function(e2)
+		{
+			_this.searchCanvas.onPointerMove(e2.clientX, e2.clientY);
+		});
+	});
+	
+	$(window).mouseup(function(e)
+	{
+		console.log('UP');
+		_this.searchCanvas.onPointerOut(e.clientX, e.clientY);
+		$(window).unbind('mousemove');
+	});*/
+}
+
+mosaic.prototype.listenToPointers = function()
+{
+	if(this.searchCanvas)
+	{
+		
+	}
+}
+
+/*
+ * Quitte une recherche par courbes.
+ */
+mosaic.prototype.leaveSearch = function()
+{
+	this.searchCanvas.leaveSearch();
+	this.searchCanvas = null;
+}
+
+/*
+ * Affiche les types de marqueurs correspondants à ce qu'on a commencé à tracer lors d'une recherche.
+*/
+ mosaic.prototype.notifySearchMarkers = function(markersStr)
+{
+	if($('.notifications_inSearch_container').length > 0)
+	{
+		return;
+	}
+	
+	// console.log(markersStr);
+	
+	var markersList = markersStr.split(new RegExp(';'));
+	
+	var notification_search_markers = "<div class='notifications_inSearch_container'>";
+	
+	//On spécifie les notifications en div.
+	for(var i = 0 ; i < markersList.length ; i++)
+	{
+		notification_search_markers += "<div class='notifications_inSearch' style='background-image: url(./pictos/big/normal/" + markersList[i] + ".png);'></div>";
+	}
+	
+	notification_search_markers += "</div>";
+	
+	//On les ajoute à la mosaïque.
+	$('#mainPanel').append(notification_search_markers);
+	
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $('.notifications_inSearch_container').width(), notify_height = $('.notifications_inSearch_container').height();
+	var notify_margin = parseInt($('.notifications_inSearch').css('margin'));
+	var point_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
+	var point_top = 0;
+	
+	if(this.currentMode == "VIDEO" || this.currentMode == "SEARCH")
+	{
+		point_top = -this.notifyTopVideo,
+		point_left = -this.notifyLeftVideo + ($(window).width() - notify_width) / 2
+	}
+	
+	//On les positionne.
+	$('.notifications_inSearch_container').css(
+	{
+		left: point_left,
+		top: point_top
+	});
+	
+	//On les fait apparaître.
+	$('.notifications_inSearch').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Supprime la notification de maintient du pointage.
+*/
+mosaic.prototype.removeSearchMarkers = function()
+{	
+	$('.notifications_inSearch_container').remove();
+}
+
+/*
+ * Effectuer un filtrage de la mosaïque par rapport à un type de marqueurs.
+*/
+mosaic.prototype.searchFilter = function(type)
+{
+	var _this = this;
+	
+	if(this.currentMode == "FILTER")
+	{
+		this.filterSearchedType = type;
+		
+		// console.log('Annotations length : ' + this.annotations.length);
+		if(this.annotations.length > 0)
+		{
+			this.isMosaicFiltering = true;
+			
+			var gestureNumberByVideo = new Object();
+			var maxAnnotationNumber = 0;
+			// for(var i = 0 ; i < this.config['imagesToShow'] ; i++)
+			for(var i = 0 ; i < this.annotations.length ; i++)
+			{
+				var current = this.annotations[i];
+				// console.log(current.annotationType.contents.title + ' == ' + type);
+				if(current.annotationType.contents.title == type)
+				{
+					if(gestureNumberByVideo[current.source.url] == undefined || gestureNumberByVideo[current.source.url] == '')
+					{
+						gestureNumberByVideo[current.source.url] = 0;
+					}
+					
+					gestureNumberByVideo[current.source.url]++;
+				}
+			}
+			
+			for(var i = 0 ; i < this.config['imagesToShow'] ; i++)
+			{
+				if(gestureNumberByVideo[this.urls[i]] == undefined || gestureNumberByVideo[this.urls[i]] == '')
+				{
+					gestureNumberByVideo[this.urls[i]] = 0;
+				}
+			}
+			
+			//On récupère la vidéo qui score le nombre d'occurences de la gesture le plus haut.
+			for(i in gestureNumberByVideo)
+			{	
+				console.log(i + " " + gestureNumberByVideo[i] + ' ' + type);
+				if(maxAnnotationNumber < gestureNumberByVideo[i])
+				{
+					maxAnnotationNumber = gestureNumberByVideo[i];
+				}
+			}
+			
+			var snMargin = parseInt($('.snapshotDivs').css('margin'));
+			
+			//On affiche l'opacité résultante pour chaque vidéo.
+			for(var i = 0 ; i < this.config['imagesToShow'] ; i++)// in gestureNumberByVideo)
+			{
+				//Opacité conventionelle.
+				var opacity = gestureNumberByVideo[this.urls[i]] / maxAnnotationNumber;
+				// console.log('opacity b : ' + opacity + ' for ' + gestureNumberByVideo[i]);
+				//Ce qui est à zéro le restera (par conséquent le snapshot associé sera invisible).
+				if(opacity > 0)
+				{
+					//On réhausse l'opacité de 50%.
+					opacity = this.scaleIntervals(0., 1., 0.5, 1., opacity);	
+				}
+				this.opacities[i] = opacity;
+				
+				//var filterIndex = this.getIdxFromMetadata(i);
+				var filterIndex = i;
+				//if(filterIndex >= 0)
+				//{
+					// console.log('#snapshotDiv-' + filterIndex + " " + _this.config['timeFilterFade'] + " " + opacity);
+					$('#snapshotDiv-' + filterIndex).fadeTo(this.config['timeFilterFade'], opacity, function()
+					{
+						//Pour ne notifier qu'une fois.
+						if(_this.isMosaicFiltering)
+						{
+							_this.isMosaicFiltering = false;
+						}
+					});
+					
+					// console.log('filterIdx : ' + filterIndex);
+					
+					if(opacity == 0)
+					{
+						var filteredSnapshot = $('#snapshotDiv-' + filterIndex);
+						
+						if(filteredSnapshot.length > 0)
+						{
+							var hider = '<div id="filterHider-' + filterIndex + '" class="filterHiders"></div>';
+							$('#mainPanel').append(hider);
+							
+							$('#filterHider-' + filterIndex).css(
+							{
+								width: +filteredSnapshot.width() + 4 * snMargin,
+								height: +filteredSnapshot.height() + 4 * snMargin,
+								top: filteredSnapshot.position().top - snMargin,
+								left: filteredSnapshot.position().left - snMargin
+							});
+						}
+					}
+				//}
+			}
+			// for(var a = 0 ; a < this.config['imagesToShow'] ; a++)
+				// console.log('op : ' + ' ' + this.imgs[a] + ' \t ' + this.opacities[a]);
+			
+			this.isMosaicFiltered = true;
+		}
+	}
+}
+
+/*
+ * Passe une valeur de l'intervalle [A, B] à l'intervalle [C, D].
+*/
+mosaic.prototype.scaleIntervals = function(A, B, C, D, val)
+{
+	return (D - C + A) * val + (C - A);
+}
+
+/*
+ * Retourne l'index d'un snapshot en fonction de ses metadonnées.
+*/
+mosaic.prototype.getIdxFromMetadata = function(metadata)
+{
+	var _this = this;
+	
+	for(idx in this.urls)
+	{
+		if(this.urls[idx] == metadata)
+		{
+			for(id in this.ids)
+			{
+				if(this.ids[id] == idx)
+				{
+					return id;
+				}
+			}
+		}
+	}
+	
+	return -1;
+}
+
+/*
+ * Enlève une recherche par filtre.
+*/
+mosaic.prototype.removeFilter = function()
+{
+	if(this.currentMode == "FILTER")
+	{
+		this.currentMode = "MOSAIC";
+		
+		var _this = this;
+		
+		this.isMosaicFiltered = false;
+		this.filterSearchedType = '';
+		
+		$('#notify_search').remove();
+		$('#notify_search_1gesture').remove();
+		$('.filterHiders').remove();
+		$('.snapshotDivs').fadeTo(_this.config['timeFilterFade'], 1);
+	}
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/front_idill/src/mosaic/js/zoomInteractions.js	Fri Jun 29 16:16:24 2012 +0200
@@ -0,0 +1,510 @@
+/*
+ * Zoom sur la position d'une image, 1ère partie. Durant le laps de temps de time ms, l'utilisateur a le choix de zoomer sur une autre image.
+ * Après ce laps de temps, l'image zoom complétement et il n'est plus possible de sélectionner une autre image par pointage.
+ */
+mosaic.prototype.preZoom = function(snapshot)
+{
+	if(this.currentMode == "NO-USER" || this.currentMode.indexOf("INCOMING") > -1 || snapshot == null || this.helpDisplayed || this.isMosaicFiltering)
+	{
+		return;
+	}
+	
+    if(this.fullscreen)
+	{
+        return;
+	}
+	this.preUnzoom();
+	//On enlève les notifications initiales si elles existent.
+	this.removeSelectionSearchMosaicFull();
+	
+    //Mosaïque.
+    var _this = this;
+    //Dimensions de la mosaïque.
+    var h = this.height, w = this.width;
+    //Longueur en images, nombre d'images et taille de bordure de la mosaïque.
+    var len = this.config['length'], imgs = this.config['imagesToShow'], margin = this.marginWidth;
+    //Dimensions et position d'un snapshot dans la mosaïque.
+    var snHeight = this.snapshotHeight, snWidth = this.snapshotWidth;
+    var sTop = snapshot.position().top, sLeft = snapshot.position().left;
+    var prezoomPercentage = this.config['prezoomPercentage'];
+    
+    //ID de l'image actuelle.
+    var currentId = $('img', snapshot).attr('id');
+    
+    //Si un zoom est déjà en cours, on ne zoom sur rien d'autre en attendant que ce snapshot ai dézoomé en cas de mouseleave.
+    if(this.zoomed)
+	{
+		/*var currentSN = this.pointerPositionToSN(pointerX, pointerY);
+		if(currentSN != null && currentSN.attr('id') != snapshot.attr('id'))
+		{
+			this.preUnzoom();
+		}*/
+        // if($('#preZoomContainer-' + currentId) != $(this) && this.previousZoomedSN != '' && this.previousId != '')
+        /*if(this.previousZoomedSN.attr('id') !== snapshot.attr('id'))
+		{
+            this.preUnzoom();
+		}
+        else
+		{
+            return;
+		}*/
+		this.preUnzoom();
+		// return;
+	}
+    
+    //On indique qu'on a zoomé et on spécifie le snapshot sur lequel on a zoomé.
+    this.zoomed = true;
+    this.previousZoomedSN = snapshot;
+    this.previousId = currentId;
+    
+    //On récupère les attributs de l'image.
+    var fakeImg = $('img', snapshot);
+    //On forme la balise de la fausse image et on passe son url pour les grands snapshots.
+    fakeImg = '<img id="fake-' + currentId + '" class="snapshots" src="' + fakeImg.attr('src').replace('-little/', '/') + '" />';
+    //On génère un faux snapshot identique au précédent et qu'on va coller dessus.
+    var fakeSnapshot = '<div id="prezoomContainer-' + currentId + '" class="prezoomContainers"><div id="prezoomSnapshot-' + currentId + '" class="snapshotDivs">' + fakeImg + '</div></div>';
+    
+    //On l'ajoute à la mosaïque.
+    $('#mainPanel').append(fakeSnapshot);
+    //On modifie ses attributs.
+	// console.log('cid : ' + currentId, $('#fake-' + currentId).length);
+    $('#fake-' + currentId).load(function()
+    {
+	// snapshot.fadeTo(400, '0.5').delay(200).fadeTo(400, '1');
+		$('#prezoomContainer-' + currentId).css('display', 'block');
+        $('#prezoomContainer-' + currentId).css('top', sTop).css('left', sLeft).css('width', (snWidth + margin)).css('height', (snHeight + margin));
+        $('#prezoomSnapshot-' + currentId).css('width', (snWidth)).css('height', (snHeight));
+        
+        //Dimensions et coordonnées initiales du div sur lequel on zoom.
+        var initialDivWidth = $('#prezoomContainer-' + currentId).width(), initialDivHeight = $('#prezoomContainer-' + currentId).height();
+        var initialDivTop = $('#prezoomContainer-' + currentId).position().top, initialDivLeft = $('#prezoomContainer-' + currentId).position().left;
+        //Dimensions et coordonnées finales du div.
+        var finalDivWidth = initialDivWidth * (prezoomPercentage+1), diffWidth = finalDivWidth - initialDivWidth, finalDivHeight = initialDivHeight + diffWidth;
+        var finalDivTop = (initialDivTop - (finalDivHeight - snHeight)/2), finalDivLeft = (initialDivLeft - (finalDivWidth - snWidth)/2);
+        
+        //CAS PARTICULIER pour la position du snapshot zoomé : les bordures.
+        if(finalDivTop < 0)
+		{
+            finalDivTop = -margin;
+		}
+        if(finalDivTop + finalDivHeight > h)
+		{
+            finalDivTop = h - finalDivHeight;
+		}
+        if(finalDivLeft < 0)
+		{
+            finalDivLeft = 0;
+		}
+        if(finalDivLeft + finalDivWidth + margin*2 > w)
+		{
+            finalDivLeft = w - finalDivWidth - margin*2;
+		}
+        
+        ////Code de debug.
+        ////CAUTION////
+        /*var red = '<div id="red"></div>';
+        if($('#red') != null || $('#red') != undefined)
+            $('body').append(red);
+        $('#red').css('background-color', '#FF0000').css('position', 'absolute').css('top', '0px').css('left', '0px').css('width', '100px').css('height', '100px');
+        $('#red').css('top', finalDivTop).css('left', finalDivLeft).css('width', finalDivWidth).css('height', finalDivHeight);*/
+        //alert("initial : " + initialDivWidth + " " + initialDivHeight + " ; final : " + finalDivWidth + " " + finalDivHeight);
+        ////CAUTION////
+        
+        //On prézoom le div en le centrant sur le milieu du snapshot pointé.
+        $('#prezoomSnapshot-' + currentId).animate(
+        {
+            width: finalDivWidth + margin,
+            height: finalDivHeight - margin*2,
+            top: finalDivTop + margin,
+            left: finalDivLeft + margin
+        }, _this.config['timePrezoom']);
+        $('#prezoomContainer-' + currentId).animate(
+        {
+            width: finalDivWidth + margin*2,
+            height: finalDivHeight - margin,
+            top: finalDivTop + margin,
+            left: finalDivLeft
+        }, _this.config['timePrezoom'], function()
+		{
+			//On met le spinner gif sur le pointeur, s'il n'existe pas déjà.
+			if($('#spinner').length == 0)
+			{
+				//On repère le pointeur ayant provoqué le prezoom.
+				var prezoomPointer;
+				if(!this.isMainPointerDisplayed)
+				{
+					prezoomPointer = $('#secondPointer');
+				}
+				if(!this.isSecondPointerDisplayed)
+				{
+					prezoomPointer = $('#mainPointer');
+				}
+				
+				var spinner = "<img id='spinner'></div>";
+				$('body').append(spinner);
+				$('#spinner').css(
+				{
+					position: 'absolute',
+					top: prezoomPointer.position().top,
+					left: prezoomPointer.position().left,
+					width: 85,
+					height: 85,
+					'z-index': 600
+				});
+				$('#spinner').attr('src', './img/cursors/selector_anim_2.gif');
+			}
+			
+			if(_this.currentMode == 'MOSAIC')
+			{
+				$('.notifications').remove();
+				_this.mosaicSelection();
+			}
+			else if(_this.currentMode == 'FILTER' && !_this.filterSearchedType)
+			{
+				$('.notifications').remove();
+				_this.filterSearchAndSelection();
+			}
+			else if(_this.currentMode == 'FILTER' && _this.filterSearchedType)
+			{
+				$('.notifications').remove();
+				_this.filterGestureAndSelection(_this.filterSearchedType, 'valid');
+			}
+		});
+		
+		
+    });
+    
+	this.zoomTimeout = setTimeout(function()
+	{
+		_this.zoom();
+	}, this.config['timeoutZoom']);
+    //Si on clique sur le snapshot prézoomé, on enclenche un zoom total sur ce snapshot.
+    /*$('#prezoomContainer-' + currentId).click(function ()
+    {
+        if(this.previousZoomedSN != '')
+		{
+            _this.zoom();
+		}
+    });*/
+}
+
+/*
+ * Dézoome sur la position de l'image. Il est à noter que ce dézoome diffère du dézoom global dans la mesure où celui-ci ne concerne que l'image sur laquelle on a zoomé.
+ */
+mosaic.prototype.preUnzoom = function()
+{
+    //Si on n'a pas zoomé, on quitte la fonction.
+    /*if(!this.zoomed)
+	{
+        return;
+	}*/
+	
+	/*if(this.currentMode == "NO-USER" || this.currentMode.indexOf("INCOMING") > -1)
+	{
+		return;
+	}*/
+	
+	$('#spinner').remove();
+	
+	var _this = this;
+	
+	clearTimeout(this.zoomTimeout);
+	
+	if(this.currentMode == 'MOSAIC')
+	{
+		$('.notifications').remove();
+		this.mosaicSelectionAndSearch();
+	}
+	else if(_this.currentMode == 'FILTER' && !this.filterSearchedType)
+	{
+		$('.notifications').remove();
+		this.filterSearch();
+	}
+	else if(_this.currentMode == 'FILTER' && this.filterSearchedType)
+	{
+		$('.notifications').remove();
+		this.filterGesture(this.filterSearchedType, 'valid');
+	}
+	/*this.removePointMosaicPrezoom();
+	this.notifySelectionSearchMosaicFull();*/
+    
+    //On spécifie la marge afin de centrer le prédézoom.
+    var margin = this.marginWidth;
+    //ID du snapshot précédemment pointé.
+    var id = this.previousId;
+    //On ne zoom plus.
+    //this.zoomed = false;
+    //On rétrécit le snapshot de prézoom, puis on le supprime en donnant l'illusion qu'il s'agissait du véritable snapshot, alors qu'en fait c'était un clone.
+	for(var i = 0 ; i < this.config['imagesToShow'] ; i++)
+	{
+		if($('#prezoomContainer-snapshot-' + i).length > 0)
+		{
+			$('#prezoomContainer-snapshot-' + i).animate(
+			{
+				width: this.snapshotWidth + margin,
+				height: this.snapshotHeight + margin,
+				top: $('#snapshotDiv-' + i).position().top,//this.previousZoomedSN.position().top,
+				left: $('#snapshotDiv-' + i).position().left//this.previousZoomedSN.position().left
+			}, this.config['preUnzoomTime'], function(){ $(this).remove(); _this.zoomed = false; });
+			$('#prezoomSnapshot-snapshot-' + i).animate(
+			{
+				width: this.snapshotWidth,
+				height: this.snapshotHeight,
+				top: $('#snapshotDiv-' + i).position().top,//this.previousZoomedSN.position().top,
+				left: $('#snapshotDiv-' + i).position().left//this.previousZoomedSN.position().left
+			}, this.config['preUnzoomTime']);
+		}
+	}
+	
+    /*$('#prezoomSnapshot-' + id).animate(
+    {
+        width: this.snapshotWidth,
+        height: this.snapshotHeight,
+        top: this.previousZoomedSN.position().top,
+        left: this.previousZoomedSN.position().left
+    }, this.config['preUnzoomTime']);
+    $('#prezoomContainer-' + id).animate(
+    {
+        width: this.snapshotWidth + margin,
+        height: this.snapshotHeight + margin,
+        top: this.previousZoomedSN.position().top,
+        left: this.previousZoomedSN.position().left
+    }, this.config['preUnzoomTime'], function(){ $(this).remove(); _this.zoomed = false; });*/
+}
+
+
+/*
+ * Zoom d'un snapshot en plein écran.
+ */
+mosaic.prototype.zoom = function()
+{
+    var _this = this;
+    
+    //Si la mosaïque est en pleine écran, pas la peine de zoomer.
+    if(this.currentMode == "VIDEO" || this.currentMode == "SEARCH" || this.currentMode.indexOf("INCOMING") > -1 || this.helpDisplayed)
+	{
+        return;
+	}
+    
+    //On prend les attributs nécessaires au calculs.
+    var margin = this.marginWidth, len = this.config['length'], imgs = this.config['imagesToShow'], zoomedMargin = this.config['zoomedMargin'];
+	var zoomPercentage = this.config['zoomPercentage'];
+    var initMPWidth = this.previousZoomedSN.width() * len + margin*len, initMPHeight = this.previousZoomedSN.height() * (imgs / len) + margin*(imgs / len);
+    var newMPWidth = initMPWidth * len + zoomedMargin * (len), newMPHeight = initMPHeight * (imgs / len) + zoomedMargin * ((imgs / len));
+    var newPreMPWidth = initMPWidth * len * zoomPercentage + zoomedMargin * (len), newPreMPHeight = initMPHeight * (imgs / len) * zoomPercentage + zoomedMargin * ((imgs / len));
+    
+    //Dimensions et coordonnées initiales du div sur lequel on zoom.
+    var initialDivWidth = this.previousZoomedSN.width(), initialDivHeight = this.previousZoomedSN.height();
+    var initialDivTop = this.previousZoomedSN.position().top, initialDivLeft = this.previousZoomedSN.position().left;
+    //Dimensions et coordonnées finales du div.
+    var finalDivWidth = initialDivWidth * (zoomPercentage+1), finalDivHeight = initialDivHeight * (zoomPercentage+1);
+    var newZoomTop = -this.previousZoomedSN.position().top*(newPreMPHeight/initMPHeight) - zoomedMargin/2 + (initMPHeight - initMPHeight * zoomPercentage)/2, newZoomLeft = -this.previousZoomedSN.position().left*(newPreMPWidth/initMPWidth) - zoomedMargin/2 + (initMPWidth - initMPWidth * zoomPercentage)/2;
+    var newSnWidth = initMPWidth * zoomPercentage, newSnHeight = initMPHeight * zoomPercentage;
+    
+    this.preUnzoom(this);
+    /*SINGULARITE*/
+    this.fullscreen = true;
+    
+    //On passe l'image du snapshot pointé en HD.
+    var zoomedImg = $('img', this.previousZoomedSN);
+    var src = zoomedImg.attr('src');
+    zoomedImg.attr('src', src.replace('-little/', '/'));
+    
+    //On récupère son ID.
+    var tab, zoomedImgId;
+    tab = _this.previousId.split('-');
+    zoomedImgId = tab[1];
+	
+	//On donne les dimensions des snapshots.
+	$('.snapshotDivs').animate(
+	{
+		width: newSnWidth,
+		height: newSnHeight,
+		margin: zoomedMargin/2 + 'px',
+	}, this.config['zoomTime']);
+	
+	if(this.currentMode != 'NO-USER')
+	{
+		//Les snapshots baissent alors en opacité, donnant l'impression qu'ils sont grisés.
+		$('.snapshotDivs').animate(
+		{
+			opacity: '0.4'
+		}, this.config['zoomTime']);
+		//Le snapshot du milieu revient à une opacité optimale, ce qui attire l'attention de l'utilisateur.
+		$(this.previousZoomedSN).animate(
+		{
+			opacity: '1'
+		}, this.config['zoomTime']);
+	}
+	// console.log('BBB1 : ' + this.currentMode);
+    //On zoome sur la mosaïque.
+    $('#mainPanel').animate(
+    {
+        width: newPreMPWidth,
+        height: newPreMPHeight,
+        top: newZoomTop,
+        left: newZoomLeft
+    }, this.config['zoomTime'], function()
+    {
+        _this.snTop = (zoomedImg.position().top + newZoomTop + _this.MPTop_margin), _this.snLeft = (zoomedImg.position().left + newZoomLeft);
+		_this.snWidth = newSnWidth + 1, _this.snHeight = newSnHeight + 1;
+		
+		_this.notifyTopVideo = newZoomTop;
+		_this.notifyLeftVideo = newZoomLeft;
+		
+		//On charge les interactions avec les voisins.
+        _this.centerId = zoomedImgId;
+		// console.log('BBB2 : ' + _this.currentMode);
+		if(_this.currentMode != "NO-USER")
+		{
+			// console.log('PROBLEM');
+			_this.currentMode = 'VIDEO';
+			_this.listenToNeighbours();
+		}
+		
+		$('#spinner').remove();
+		$('#mainPointer').css('background-image', 'url(./img/cursors/pointer.png)');
+		$('#secondPointer').css('background-image', 'url(./img/cursors/pointer2.png)');
+		
+		// console.log('BBB3 : ' + _this.currentMode);
+		_this.loadPlayer(_this.snTop, _this.snLeft, _this.snWidth, _this.snHeight, newZoomTop, newZoomLeft, _this.timeToGoAt[_this.centerId]);
+    });
+}
+
+/*
+ * Retour à la taille normale de la mosaïque.
+ */
+mosaic.prototype.unzoom = function()
+{
+    //Si on n'est pas en plein écran, on quitte.
+	// console.log("'" + this.currentMode + "'");
+    if(this.currentMode != "SEARCH" && this.currentMode != "VIDEO" && this.currentMode != "NO-USER" && this.currentMode.indexOf("INCOMING") == -1)
+	{
+        return;
+	}
+	
+	this.canSwipe = false;
+	
+	//Si la TL avait été sélectionnée, on la déselectionne.
+	if(this.currentMode == 'TIMELINE')
+	{
+		this.exitTimeline('move');
+	}
+	
+	this.currentlyUnzooming = true;
+	
+	this.removeAdditionalNeighbours();
+	this.deselectAllNeighbours();
+	
+	this.snTop = 0;
+	this.snLeft = 0;
+	this.Width = 0;
+	this.snHeight = 0;
+    
+    //On charge les attributs nécessaires aux calculs.
+    var sWidth = this.snapshotWidth, sHeight = this.snapshotHeight;
+    var mpWidth = this.width, mpHeight = this.height;
+    var _this = this;
+    
+    //On passe le snapshot sur lequel on a zoomé en SD.
+    var zoomedImg = $('img', this.previousZoomedSN);
+    var src = zoomedImg.attr('src');
+    zoomedImg.attr('src', src.replace('snapshots/', 'snapshots-little/'));
+	
+	if(_this.player.widgets && _this.player.widgets[0])
+	{
+		// console.log(Math.floor(_this.player.popcorn.currentTime()));
+		_this.timeToGoAt[_this.centerId] = Math.floor(_this.player.popcorn.currentTime());
+		_this.player.widgets[0].freePlayer();
+	}
+	
+	_this.playerIsReady = false;
+	$('.LdtPlayer').remove();
+	$('body').append('<div class="LdtPlayer" id="LdtPlayer"></div>');
+	_this.reaffectKeyPress();
+    
+    //On rend leur opacité aux snapshots. Qui ne sont alors plus grisés.
+    $('.snapshotDivs').animate(
+    {
+        width: sWidth,
+        height: sHeight,
+        margin: this.marginWidth/2 + 'px'
+    }, this.config['unzoomTime'], function()
+	{
+		_this.neighboursIds.length = 0;
+		_this.currentlyUnzooming = false;
+	});
+	
+	if(this.currentMode != 'NO-USER')
+	{
+		if(this.currentMode.indexOf("INCOMING") == -1 && !this.isMosaicFiltered)
+		{
+			$('.snapshotDivs').animate(
+			{
+				opacity: '1'
+			}, this.config['unzoomTime']);
+		}
+		else if(this.currentMode.indexOf("INCOMING") == -1 && this.isMosaicFiltered)
+		{
+			for(var i = 0 ; i < this.config['imagesToShow'] ; i++)
+			{
+				$('#snapshotDiv-' + i).animate(
+				{
+					opacity: this.opacities[i]
+				}, this.config['unzoomTime']);
+			}
+		}
+	}
+	else
+	{
+		// console.log('init');
+		this.previousZoomedSN.fadeTo(this.config['unzoomTime'], 0, function()
+		{
+			_this.init();
+		});
+	}
+	
+    //On dézoom sur la mosaïque.
+    $('#mainPanel').animate(
+    {
+        width: mpWidth,
+        height: mpHeight,
+        top: '0px',
+        left: '0px'
+    }, this.config['unzoomTime'], function()
+    {
+        //On n'est plus en plein écran, et on ne peut plus se déplacer vers le prochain voisin.
+        _this.fullscreen = false;
+        _this.canMoveToNeighbour = false;
+		
+		if(_this.currentMode != 'NO-USER' && _this.currentMode.indexOf('INCOMING-') == -1)
+		{
+			if(_this.isMosaicFiltered)
+			{
+				//On revient en mode FILTER.
+				_this.currentMode = 'FILTER';
+			}
+			else
+			{
+				//On revient en mode MOSAIC.
+				_this.currentMode = 'MOSAIC';
+			}
+			
+			//On ne permet plus le déplacement vers les voisins.
+			/*$('.snapshotDivs').unbind('mouseover', function()
+			{
+				_this.selectNeighbour();
+			});*/
+			
+			//On remet les notifications initiales si on n'est pas dans une recherche par filtrage.
+			if(_this.currentMode == 'MOSAIC' && !_this.filterSearchedType)
+			{
+				$('.notifications').remove();
+				// _this.notifySelectionSearchMosaicFull();
+				_this.mosaicSelectionAndSearch();
+			}
+		}
+		
+		this.currentlyUnzooming = false;
+    });
+}
\ No newline at end of file
Binary file front_idill/src/pictos/big/hover/grand-jete.png has changed
Binary file front_idill/src/pictos/big/hover/knee-up.png has changed
Binary file front_idill/src/pictos/big/hover/no-motion.png has changed
Binary file front_idill/src/pictos/big/hover/up-down.png has changed
Binary file front_idill/src/pictos/big/normal/grand-jete.png has changed
Binary file front_idill/src/pictos/big/normal/knee-up.png has changed
Binary file front_idill/src/pictos/big/normal/no-motion.png has changed
Binary file front_idill/src/pictos/big/normal/right-angle.png has changed
Binary file front_idill/src/pictos/big/normal/up-down.png has changed
Binary file front_idill/src/pictos/big/valid/grand-jete.png has changed
Binary file front_idill/src/pictos/big/valid/knee-up.png has changed
Binary file front_idill/src/pictos/big/valid/no-motion.png has changed
Binary file front_idill/src/pictos/big/valid/right-angle.png has changed
Binary file front_idill/src/pictos/big/valid/up-down.png has changed
Binary file front_idill/src/pictos/help/arret.png has changed
Binary file front_idill/src/pictos/help/bend.png has changed
Binary file front_idill/src/pictos/help/breakdance.png has changed
Binary file front_idill/src/pictos/help/chute.png has changed
Binary file front_idill/src/pictos/help/contact.png has changed
Binary file front_idill/src/pictos/help/controles.png has changed
Binary file front_idill/src/pictos/help/deplacer.png has changed
Binary file front_idill/src/pictos/help/grandjete.png has changed
Binary file front_idill/src/pictos/help/group_spin.png has changed
Binary file front_idill/src/pictos/help/hello.png has changed
Binary file front_idill/src/pictos/help/img bak/arc.png has changed
Binary file front_idill/src/pictos/help/img bak/bend.png has changed
Binary file front_idill/src/pictos/help/img bak/circle.png has changed
Binary file front_idill/src/pictos/help/img bak/contact.png has changed
Binary file front_idill/src/pictos/help/img bak/controles big.png has changed
Binary file front_idill/src/pictos/help/img bak/fall.png has changed
Binary file front_idill/src/pictos/help/img bak/grand_jete.png has changed
Binary file front_idill/src/pictos/help/img bak/hello.png has changed
Binary file front_idill/src/pictos/help/img bak/jump.png has changed
Binary file front_idill/src/pictos/help/img bak/knee_up.png has changed
Binary file front_idill/src/pictos/help/img bak/no_motion.png has changed
Binary file front_idill/src/pictos/help/img bak/recherche big.png has changed
Binary file front_idill/src/pictos/help/img bak/right_angle.png has changed
Binary file front_idill/src/pictos/help/img bak/rythme.png has changed
Binary file front_idill/src/pictos/help/img bak/screw.png has changed
Binary file front_idill/src/pictos/help/img bak/selection.png has changed
Binary file front_idill/src/pictos/help/img bak/slow.png has changed
Binary file front_idill/src/pictos/help/img bak/up_down.png has changed
Binary file front_idill/src/pictos/help/img bak/wave.png has changed
Binary file front_idill/src/pictos/help/img bak/wheel.png has changed
Binary file front_idill/src/pictos/help/jump.png has changed
Binary file front_idill/src/pictos/help/knee_up.png has changed
Binary file front_idill/src/pictos/help/mosaique_horizontal.png has changed
Binary file front_idill/src/pictos/help/mosaique_vertical.png has changed
Binary file front_idill/src/pictos/help/move_down.png has changed
Binary file front_idill/src/pictos/help/move_left.png has changed
Binary file front_idill/src/pictos/help/move_right.png has changed
Binary file front_idill/src/pictos/help/move_up.png has changed
Binary file front_idill/src/pictos/help/port_de_bras.png has changed
Binary file front_idill/src/pictos/help/precedent.png has changed
Binary file front_idill/src/pictos/help/recherche.png has changed
Binary file front_idill/src/pictos/help/rythme.png has changed
Binary file front_idill/src/pictos/help/selection.png has changed
Binary file front_idill/src/pictos/help/slow.png has changed
Binary file front_idill/src/pictos/help/spin.png has changed
Binary file front_idill/src/pictos/help/suivant.png has changed
Binary file front_idill/src/pictos/help/up_down.png has changed
Binary file front_idill/src/pictos/help/volant.png has changed
Binary file front_idill/src/pictos/help/wave.png has changed
Binary file front_idill/src/pictos/notifications/deplacer.png has changed
Binary file front_idill/src/pictos/notifications/move_down.png has changed
Binary file front_idill/src/pictos/notifications/move_left.png has changed
Binary file front_idill/src/pictos/notifications/move_right.png has changed
Binary file front_idill/src/pictos/notifications/move_up.png has changed
Binary file front_idill/src/pictos/notifications/swipe_left.png has changed
Binary file front_idill/src/pictos/notifications/swipe_right.png has changed
Binary file front_idill/src/pictos/notifications/unzoom_horizontal.png has changed
Binary file front_idill/src/pictos/notifications/unzoom_vertical.png has changed
Binary file front_idill/src/pictos/small/arc.png has changed
Binary file front_idill/src/pictos/small/hello.png has changed
Binary file front_idill/src/pictos/small/no-motion.png has changed
Binary file front_idill/src/pictos/small/port_de_bras.png has changed
Binary file front_idill/src/pictos/small/rythme.png has changed
Binary file front_idill/src/pictos/small/slow.png has changed
Binary file front_idill/src/pictos/small/wave.png has changed
--- a/front_idill/src/player/json/local_videos.json	Fri Jun 29 15:46:34 2012 +0200
+++ b/front_idill/src/player/json/local_videos.json	Fri Jun 29 16:16:24 2012 +0200
@@ -2,7 +2,7 @@
 	"videos" : [
 		{
 			"metadata": "./player/json/metadata/ba4d888c-66b7-11e1-91ba-00145ea4a2be",
-			"snapshot": "50 shots.png",
+			"snapshot": "50 shots.jpg",
 			"gestures": [
 				{
 					"gesture_name": "bend",
@@ -16,7 +16,7 @@
 		},
 		{
 			"metadata": "./player/json/metadata/076230fe-66b9-11e1-80f6-00145ea4a2be",
-			"snapshot": "deep end dance.png",
+			"snapshot": "deep end dance.jpg",
 			"gestures": [
 				{
 					"gesture_name": "circle",
@@ -41,30 +41,8 @@
 			]
 		},
 		{
-			"metadata": "./player/json/metadata/f80bd9fe-66b6-11e1-91ba-00145ea4a2be",
-			"snapshot": "encontro cotidianos.png",
-			"gestures": [
-				{
-					"gesture_name": "contact",
-					"snapshot": ""
-				},
-				{
-					"gesture_name": "circle",
-					"snapshot": ""
-				},
-				{
-					"gesture_name": "screw",
-					"snapshot": ""
-				},
-				{
-					"gesture_name": "run",
-					"snapshot": ""
-				}
-			]
-		},
-		{
 			"metadata": "./player/json/metadata/f1cee904-66b7-11e1-80f6-00145ea4a2be",
-			"snapshot": "fenella.png",
+			"snapshot": "fenella.jpg",
 			"gestures": [
 				{
 					"gesture_name": "knee-up",
@@ -78,7 +56,7 @@
 		},
 		{
 			"metadata": "./player/json/metadata/98517ca6-66b8-11e1-80f6-00145ea4a2be",
-			"snapshot": "i am my mother.png",
+			"snapshot": "i am my mother.jpg",
 			"gestures": [
 				{
 					"gesture_name": "",
@@ -88,7 +66,7 @@
 		},
 		{
 			"metadata": "./player/json/metadata/d610e47e-66b7-11e1-80f6-00145ea4a2be",
-			"snapshot": "instrument.png",
+			"snapshot": "instrument.jpg",
 			"gestures": [
 				{
 					"gesture_name": "",
@@ -98,7 +76,7 @@
 		},
 		{
 			"metadata": "./player/json/metadata/e2b5b9e8-562c-11e1-b3c3-00145ea49a02",
-			"snapshot": "joudance 2 in asakusa_stage1.png",
+			"snapshot": "joudance 2 in asakusa_stage1.jpg",
 			"gestures": [
 				{
 					"gesture_name": "",
@@ -108,7 +86,7 @@
 		},
 		{
 			"metadata": "./player/json/metadata/23256da6-66b9-11e1-80f6-00145ea4a2be",
-			"snapshot": "mue.png",
+			"snapshot": "mue.jpg",
 			"gestures": [
 				{
 					"gesture_name": "",
@@ -118,7 +96,7 @@
 		},
 		{
 			"metadata": "./player/json/metadata/c66bfa64-66b6-11e1-91ba-00145ea4a2be",
-			"snapshot": "new under the sun.png",
+			"snapshot": "new under the sun.jpg",
 			"gestures": [
 				{
 					"gesture_name": "",
@@ -128,7 +106,7 @@
 		},
 		{
 			"metadata": "./player/json/metadata/cfd63004-66b8-11e1-80f6-00145ea4a2be",
-			"snapshot": "nid de lune.png",
+			"snapshot": "nid de lune.jpg",
 			"gestures": [
 				{
 					"gesture_name": "",
@@ -138,7 +116,7 @@
 		},
 		{
 			"metadata": "./player/json/metadata/2f8b92b6-66b7-11e1-91ba-00145ea4a2be",
-			"snapshot": "patria.png",
+			"snapshot": "patria.jpg",
 			"gestures": [
 				{
 					"gesture_name": "circle",
@@ -156,7 +134,7 @@
 		},
 		{
 			"metadata": "./player/json/metadata/294f727c-66b8-11e1-91ba-00145ea4a2be",
-			"snapshot": "sliced.png",
+			"snapshot": "sliced.jpg",
 			"gestures": [
 				{
 					"gesture_name": "",
@@ -166,7 +144,7 @@
 		},
 		{
 			"metadata": "./player/json/metadata/3f1f08e6-66b9-11e1-80f6-00145ea4a2be",
-			"snapshot": "stronger.png",
+			"snapshot": "stronger.jpg",
 			"gestures": [
 				{
 					"gesture_name": "jump",
@@ -188,7 +166,7 @@
 		},
 		{
 			"metadata": "./player/json/metadata/82cd7e30-66b7-11e1-80f6-00145ea4a2be",
-			"snapshot": "vrtti.png",
+			"snapshot": "vrtti.jpg",
 			"gestures": [
 				{
 					"gesture_name": "",
@@ -198,7 +176,7 @@
 		},
 		{
 			"metadata": "./player/json/metadata/60d03074-66b8-11e1-80f6-00145ea4a2be",
-			"snapshot": "you are you.png",
+			"snapshot": "you are you.jpg",
 			"gestures": [
 				{
 					"gesture_name": "",
@@ -208,7 +186,7 @@
 		},
 		{
 			"metadata": "./player/json/metadata/15a75eea-8870-11e1-9bba-00145ea4a2be",
-			"snapshot": "alger.png",
+			"snapshot": "alger.jpg",
 			"gestures": [
 				{
 					"gesture_name": "",
@@ -218,7 +196,7 @@
 		},
 		{
 			"metadata": "./player/json/metadata/ffbe189a-886e-11e1-9ee2-00145ea4a2be",
-			"snapshot": "animalz.png",
+			"snapshot": "animalz.jpg",
 			"gestures": [
 				{
 					"gesture_name": "",
@@ -228,7 +206,7 @@
 		},
 		{
 			"metadata": "./player/json/metadata/a52dc4c4-886f-11e1-9bba-00145ea4a2be",
-			"snapshot": "exotica.png",
+			"snapshot": "exotica.jpg",
 			"gestures": [
 				{
 					"gesture_name": "",
@@ -238,7 +216,7 @@
 		},
 		{
 			"metadata": "./player/json/metadata/8a29e4f0-886f-11e1-9ee2-00145ea4a2be",
-			"snapshot": "respire.png",
+			"snapshot": "respire.jpg",
 			"gestures": [
 				{
 					"gesture_name": "",
@@ -248,7 +226,7 @@
 		},
 		{
 			"metadata": "./player/json/metadata/2377411e-9f74-11e1-9f9f-00145ea4a2be",
-			"snapshot": "flying lesson.png",
+			"snapshot": "flying lesson.jpg",
 			"gestures": [
 				{
 					"gesture_name": "",
@@ -258,7 +236,7 @@
 		},
 		{
 			"metadata": "./player/json/metadata/e3d42dc4-9f73-11e1-9f9f-00145ea4a2be",
-			"snapshot": "aside.png",
+			"snapshot": "aside.jpg",
 			"gestures": [
 				{
 					"gesture_name": "",
@@ -268,7 +246,7 @@
 		},
 		{
 			"metadata": "./player/json/metadata/a98a7bc4-8870-11e1-9ee2-00145ea4a2be",
-			"snapshot": "the rat.png",
+			"snapshot": "the rat.jpg",
 			"gestures": [
 				{
 					"gesture_name": "",
@@ -278,7 +256,7 @@
 		},
 		{
 			"metadata": "./player/json/metadata/f47e1578-8870-11e1-9ee2-00145ea4a2be",
-			"snapshot": "tank man tango a tianmen memorial.png",
+			"snapshot": "tank man tango a tiananmen memorial.jpg",
 			"gestures": [
 				{
 					"gesture_name": "",
--- a/front_idill/src/player/metadataplayer/LdtPlayer-core.js	Fri Jun 29 15:46:34 2012 +0200
+++ b/front_idill/src/player/metadataplayer/LdtPlayer-core.js	Fri Jun 29 16:16:24 2012 +0200
@@ -1570,10 +1570,15 @@
 }
 
 IriSP.Widgets.Widget.prototype.functionWrapper = function(_name) {
+// console.log('marker');
     var _this = this,
         _function = this[_name];
+		
+		// console.log(_name, arguments);
+		// console.log(typeof _function);
     if (typeof _function !== "undefined") {
         return function() {
+		// console.log('marker ok');
             return _function.apply(_this, Array.prototype.slice.call(arguments, 0));
         }
     } else {
--- a/front_idill/src/player/metadataplayer/Timeline.css	Fri Jun 29 15:46:34 2012 +0200
+++ b/front_idill/src/player/metadataplayer/Timeline.css	Fri Jun 29 16:16:24 2012 +0200
@@ -1,5 +1,7 @@
 /* Timeline Widget */
 
+@charset "UTF-8";
+
 @font-face {
     font-family: "DINMedium";
     src: url("../../fonts/DINMedium.ttf") format("truetype");
@@ -82,10 +84,10 @@
 
 #MB_Text {
 	background-color: rgba(34, 34, 34, 1);
-	padding: 1px 5px 1px 5px;
+	padding: 8px 18px 8px 18px;
 	color: #FFFFFF;
 	//font-family: DIN-Medium, Fallback, sans-serif;
-	font-size: 10px;
+	font-size: 22px;
 }
 
 #MB_Spike {
--- a/front_idill/src/player/metadataplayer/Timeline.js	Fri Jun 29 15:46:34 2012 +0200
+++ b/front_idill/src/player/metadataplayer/Timeline.js	Fri Jun 29 16:16:24 2012 +0200
@@ -3,9 +3,11 @@
  */
 
 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;
@@ -21,8 +23,13 @@
 	this.imgDir = "player/img/";
 	this.markersDir = "pictos/small/";
 	this.player = player;
+	this.isCurrentlyInASearchByGesture = false;
 	
-	this.gestures = ["fall", "jump", "circle", "screw", "bend", "arc", "pendulum", "knee-up", "right-angle", "wave", "slow", "hello", "no-motion", "wheel", "contact", "run"];
+	//Id du marqueur enregistré.
+	this.currentMarkerId;
+	
+	this.gestures = ["fall", "jump", "circle", "screw", "bend", "arc", "knee-up", "right-angle", "wave", "slow", "hello", "no-motion", "contact"];
+	this.gesturesText = ["chute", "saut", "rotation", "rotation de groupe", "inclinaison", "port de bras", "levé de genou", "angle droit", "ondulation", "lent", "salut", "immobilité", "contact"];
 	
 	this.annotations = this.annotationsFilter(this.source.getAnnotations(), this.gestures, this.isGesture);
 	
@@ -37,6 +44,9 @@
 	return ($.inArray(element.annotationType.contents.title, array) > -1);
 }
 
+//Fonction associée à l'événement : les marqueurs sont prêts.
+IriSP.Widgets.Timeline.prototype.onMarkersReady = function() {}
+
 //Fonction de filtrage de tableaux
 IriSP.Widgets.Timeline.prototype.annotationsFilter = function(annotations, gestures, fun /*, thisp*/)
 {
@@ -61,9 +71,9 @@
 };
 
 IriSP.Widgets.Timeline.prototype.defaults = {
-    minimized_height : 44,
-    maximized_height : 44,
-	middle_height: 4,
+    minimized_height : 114,//44,
+    maximized_height : 114,
+	middle_height: 10,//4,
 	timelineBorderLength : 6,
     minimize_timeout : 1500 // time before minimizing timeline after mouseout
 };
@@ -93,22 +103,27 @@
         min: 0,
         max: this.source.getDuration().milliseconds,
         slide: function(event, ui) {
-            _this.player.popcorn.currentTime(Math.floor(ui.value/1000));
-            _this.player.popcorn.trigger("IriSP.Mediafragment.setHashToTime");
+			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();
+				// /!\ 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("#" + annotations[_this.previousMarkerIdx].id.replace(":", "_"));
+				var previousMarker = IriSP.jQuery("#" + _this.annotations[_this.previousMarkerIdx].id.replace(":", "_"));
 				_this.hideMarkerBig(previousMarker);
 				// console.log("EXT hide " + _this.previousMarkerIdx);
 			}
         }
     });
-    
+	
     this.$handle = this.$timeline.find('.ui-slider-handle');
     
     this.$handle.css(this.calculateHandleCss(this.minimized_height));
@@ -127,6 +142,7 @@
 */
 IriSP.Widgets.Timeline.prototype.ready = function() {
 	this.player.popcorn.play();
+	this.player.popcorn.mute();
 	this.processMarkers();
 }
 
@@ -168,6 +184,9 @@
  * Process the markers.
 */
 IriSP.Widgets.Timeline.prototype.processMarkers = function() {
+	console.trace();
+	console.log('PROCESSING MARKERS');
+	
 	var _this = this;
 	var markers = "";
 	var timelineMiddleTop = this.$timelineMiddle.position().top;
@@ -182,6 +201,8 @@
 	var markerHeight = IriSP.jQuery(".Ldt-Marker").height();
 	IriSP.jQuery(".Ldt-Marker").css("z-align", "150");
 	
+	console.log('IN PROCESSING');
+	
 	for(var i = 0 ; i < this.annotations.length ; i++)
 	{
 		IriSP.jQuery("#" + this.annotations[i].id.replace(":", "_")).css(
@@ -191,6 +212,47 @@
 			"margin-top": (-_this.$timeline.height()/2 - markerHeight/2) - this.top_epsilon + "px"
 		});
 	}
+	
+	console.log('MARKERS PROCESSED');
+	
+	//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');
+}
+
+/*
+ * Fonction de recherche par gesures.
+*/
+IriSP.Widgets.Timeline.prototype.searchByGesture = function(typeName)
+{
+	this.notifySearch1Gesture(typeName, "valid");
+		
+	if(typeName != '' || typeName != undefined)
+	{
+		if(_.include(this.gestures, typeName))
+		{
+			this.currentMode = "SEARCH";
+			this.hideMarkersSearch(typeName);
+			this.isCurrentlyInASearchByGesture = true;
+		}
+		else
+		{
+			// alert("Unknown gesture type. Operation aborted.");
+			this.removeSearch1Gesture();
+			this.notifySearch1Gesture(typeName, "none");
+		}
+	}
+}
+
+/*
+ * Fonction de suppression de recherche par gesures.
+*/
+IriSP.Widgets.Timeline.prototype.removeSearchByGesture = function()
+{
+	this.removeSearch1Gesture();
+	this.hideMarkersSearch();
+	this.isCurrentlyInASearchByGesture = false;
 }
 
 /*
@@ -496,47 +558,11 @@
     // this.player.popcorn.trigger("IriSP.Arrow.updatePosition",{widget: this.type, time: 1000 * _time});
 }
 
-IriSP.Widgets.Timeline.prototype.onMouseover = function() {
-    /*if (this.timeoutId) {
-        window.clearTimeout(this.timeoutId);
-        this.timeoutId = false;
-    }
-    if (!this.maximized) {
-       this.animateToHeight(this.maximized_height);
-       this.maximized = true;
-    }*/
-}
+IriSP.Widgets.Timeline.prototype.onMouseover = function() {}
 
-IriSP.Widgets.Timeline.prototype.onMouseout = function() {
-    /*if (this.timeoutId) {
-        window.clearTimeout(this.timeoutId);
-        this.timeoutId = false;
-    }
-    var _this = this;
-    this.timeoutId = window.setTimeout(function() {
-        if (_this.maximized) {
-            _this.animateToHeight(_this.minimized_height);
-            _this.maximized = false;
-        }
-        _this.timeoutId = false;
-    }, this.minimize_timeout);*/
-    
-}
+IriSP.Widgets.Timeline.prototype.onMouseout = function() {}
 
-IriSP.Widgets.Timeline.prototype.animateToHeight = function(_height) {
-    /*this.$timeline.stop().animate(
-        this.calculateTimelineCss(_height),
-        500,
-        function() {
-            IriSP.jQuery(this).css("overflow","visible");
-        });
-    this.$handle.stop().animate(
-        this.calculateHandleCss(_height),
-        500,
-        function() {
-            IriSP.jQuery(this).css("overflow","visible");
-        });*/
-}
+IriSP.Widgets.Timeline.prototype.animateToHeight = function(_height) {}
 
 IriSP.Widgets.Timeline.prototype.calculateTimelineCss = function(_size) {
 	var middleWidth = this.player.config.gui.width;
@@ -604,7 +630,7 @@
 	var markerWidth = marker.width(), markerHeight = marker.height();
 	
 	this.markerBigShown = true;
-	var markerBig = "<div class='TL_MarkersBig' id='MB_Text'>" + type + "<div class='TL_MarkersBig' id='MB_Spike'></div></div><div class='TL_MarkersBig' id='MB_Pic'></div>";
+	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");
@@ -632,7 +658,8 @@
 	{
 		"background-image": "url(" + this.markersDir + type + ".png)",
 		top: markerBigPicTop,
-		left: markerBigPicLeft
+		left: markerBigPicLeft,
+		"z-index": "400"
 	});
 	
 	IriSP.jQuery(".TL_MarkersBig").fadeTo(this.markerShowTime, "1");
@@ -732,7 +759,7 @@
 		return;
 	}
 	
-	console.log('(0)');
+	// console.log('(0)');
 	
 	var _this = this;
 	
@@ -751,7 +778,7 @@
 		}
 		else
 		{
-			console.log('(1)');
+			// console.log('(1)');
 			// console.log(_this.currentMode);
 			_this.showMarkersSearchByType(type);
 			_this.notifySearch1Gesture(type, "valid");
@@ -761,7 +788,7 @@
 	
 	if(IriSP.jQuery(".search_Marker").length == 0 && type != undefined)
 	{
-		console.log('(2)');
+		// console.log('(2)');
 		this.showMarkersSearchByType(type);
 		_this.removeSearch1Gesture();
 		
@@ -795,13 +822,19 @@
 		return;
 	}
 	
+	//Si on a effectué une demande de recherche auparavant, on supprime la notification de demande de recherche.
+	if(IriSP.jQuery('#notify_search').length > 0)
+	{
+		$('.notifications').remove();
+	}
+	
 	var _this = this;
 	
 	//On spécifie les notifications en div.
 	var notification_search_1gesture = "<div id='notify_search_1gesture' class='notifications'></div>";
 	
 	//On les ajoute à la mosaïque.
-	$('#mainPanel').append(notification_search_1gesture);
+	$('body').append(notification_search_1gesture);
 	
 	// console.log(this.player.config.gui.zoomTop + " " + this.player.config.gui.zoomLeft);
 	
@@ -821,7 +854,7 @@
 	
 	if(mode != 'none')
 	{
-		IriSP.jQuery('#notify_search_1gesture').mouseover(function()
+		/*IriSP.jQuery('#notify_search_1gesture').mouseover(function()
 		{
 			IriSP.jQuery(this).css('background-image', 'url("./pictos/big/hover/' + gestureName + '.png")');
 		}).mouseout(function()
@@ -831,7 +864,7 @@
 		{
 			_this.removeSearch1Gesture();
 			_this.hideMarkersSearch();
-		});
+		});*/
 	}
 	
 	var notifyTop = this.player.config.gui.zoomTop, notifyLeft = this.player.config.gui.zoomLeft;
@@ -839,8 +872,10 @@
 	//On les positionne.
 	$('#notify_search_1gesture').css(
 	{
-		top: -notifyTop,
-		left: -notifyLeft + (IriSP.jQuery(window).width() - notify_width) / 2
+		// top: -notifyTop,
+		top: 0,//-notifyTop,
+		// left: -notifyLeft + (IriSP.jQuery(window).width() - notify_width) / 2
+		left: (IriSP.jQuery(window).width() - notify_width) / 2
 	});
 	
 	//On les fait apparaître.
@@ -858,4 +893,222 @@
 	// console.log('R');
 	// console.trace();
 	IriSP.jQuery('#notify_search_1gesture').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.
+*/
+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;
+	
+	//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;
+		}
+	}
+	
+	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)
+	{
+		//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)
+			{
+				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))
+			{
+				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;
+			}
+		}
+	}*/
+}
+
+/*
+ * 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).
+*/
+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);
+		}
+	}
+}
+
+/*
+ * Renvoie vrai si il y a au moins une gesture de notre recherche dans les marqueurs de la video.
+*/
+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;
+		}
+	}
 }
\ No newline at end of file
--- a/front_idill/src/search/js/curve.js	Fri Jun 29 15:46:34 2012 +0200
+++ b/front_idill/src/search/js/curve.js	Fri Jun 29 16:16:24 2012 +0200
@@ -25,32 +25,38 @@
 	this.lastPoint;
 }
 
-curve.prototype.onMouseDown = function(event)
+curve.prototype.onPointerIn = function(pointerX, pointerY)
 {
 	this.pathStroke = new Path();
 	this.path = new Path();
 	
+	var point = new paper.Point(pointerX, pointerY);
+	
+	if(!this.lastPoint)
+	{
+		this.lastPoint = point;
+	}
+	
 	this.pathStroke.fillColor = '#366F7A';
 	this.path.fillColor = '#02FEFF';
-	
-	console.log('down');
 };
 
-curve.prototype.onMouseDrag = function(event)
+curve.prototype.onPointerMove = function(pointerX, pointerY)
 {
-	//if(event.point.x < 0 || event.point.x > canvasWidth || event.point.y < 0 || event.point.y > canvasHeight)
-		//return;
+	var point = new paper.Point(pointerX, pointerY);
 	
-	var step = event.delta / 5;
-	var stepStroke = event.delta / 3;
+	var delta = new paper.Point(this.lastPoint.x - point.x, this.lastPoint.y - point.y);
+	
+	var step = delta / 5;
+	var stepStroke = delta / 3;
 	step.angle += 90;
 	stepStroke.angle += 90;
 
-	var top = event.point + step;
-	var bottom = event.point - step;
+	var top = point + step;
+	var bottom = point - step;
 	
-	var topStroke = event.point + stepStroke;
-	var bottomStroke = event.point - stepStroke;
+	var topStroke = point + stepStroke;
+	var bottomStroke = point - stepStroke;
 
 	this.path.add(top);
 	this.path.insert(0, bottom);
@@ -60,10 +66,10 @@
 	this.pathStroke.insert(0, bottomStroke);
 	this.pathStroke.smooth();
 	
-	this.lastPoint = event.middlePoint;
+	this.lastPoint = point;
 };
 
-curve.prototype.onMouseUp = function(event)
+curve.prototype.onMouseUp = function(pointerX, pointerY)
 {
 	this.pathStroke.remove();
 	this.path.remove();
--- a/front_idill/src/search/js/searchCanvas.js	Fri Jun 29 15:46:34 2012 +0200
+++ b/front_idill/src/search/js/searchCanvas.js	Fri Jun 29 16:16:24 2012 +0200
@@ -8,9 +8,12 @@
 	this.margin_top = _margin_top;
 	
 	//tool.fixedDistance = 10;
-	this.path;
-	this.pathStroke;
-	this.lastPoint;
+	this.mainPath;
+	this.mainPathStroke;
+	this.mainLastPoint;
+	this.secondPath;
+	this.secondPathStroke;
+	this.secondLastPoint;
 	
 	this.inMosaic = _inMosaic;
 	
@@ -44,9 +47,9 @@
 	
 	paper.setup('paperCanvas');
 	
-	this.hitTool.onMouseDown = this.onMouseDown;
-	this.hitTool.onMouseDrag = this.onMouseDrag;
-	this.hitTool.onMouseUp = this.onMouseUp;
+	this.hitTool.onMouseDown = this.onPointerIn;
+	this.hitTool.onMouseDrag = this.onPointerMove;
+	this.hitTool.onMouseUp = this.onPointerOut;
 	this.hitTool.onKeyDown = this.onKeyDown;
 };
 
@@ -58,43 +61,96 @@
 	});
 };
 
-searchCanvas.prototype.onMouseDown = function(event)
+searchCanvas.prototype.onPointerIn = function(mainPointerX, mainPointerY, secondPointerX, secondPointerY)
 {
-	this.pathStroke = new paper.Path();
-	this.path = new paper.Path();
+	this.mainPathStroke = new paper.Path();
+	this.mainPath = new paper.Path();
+	this.secondPathStroke = new paper.Path();
+	this.secondPath = new paper.Path();
+	
+	this.mainPathStroke.fillColor = '#366F7A';
+	this.mainPath.fillColor = '#02FEFF';
+	this.secondPathStroke.fillColor = '#366F7A';
+	this.secondPath.fillColor = '#02FEFF';
+	
+	// var pointerX = e.point.x, pointerY = e.point.y;
 	
-	this.pathStroke.fillColor = '#366F7A';
-	this.path.fillColor = '#02FEFF';
+	console.log('IN');
+	
+	var mainPoint = new paper.Point(mainPointerX, mainPointerY);
+	var secondPoint = new paper.Point(secondPointerX, secondPointerY);
 	
-	this.pathStroke.add(event.point);
+	if(!this.mainLastPoint)
+	{
+		this.mainLastPoint = mainPoint;
+	}
+	if(!this.secondLastPoint)
+	{
+		this.secondLastPoint = secondPoint;
+	}
 };
 
-searchCanvas.prototype.onMouseDrag = function(event)
+searchCanvas.prototype.onPointerMove = function(mainPointerX, mainPointerY, secondPointerX, secondPointerY)
 {
-	var step = event.delta.divide(new paper.Point(4, 4));
-	var stepStroke = event.delta.divide(new paper.Point(2, 2));
-	step.angle += 90;
-	stepStroke.angle += 90;
-
-	var top = event.middlePoint.add(step);
-	var bottom = event.middlePoint.add(step.negate());
+	// var pointerX = e.point.x, pointerY = e.point.y;
+	
+	var mainPoint = new paper.Point(mainPointerX, mainPointerY);
+	var secondPoint = new paper.Point(secondPointerX, secondPointerY);
+	// var delta = new paper.Point(point.x - this.lastPoint.x, point.y - this.lastPoint.y);
+	var mainDelta = new paper.Point(15, 15);
+	var secondDelta = new paper.Point(15, 15);
+	
+	this.mainLastPoint = mainPoint;
+	this.secondLastPoint = secondPoint;
+	
+	var mainStep = mainDelta.divide(new paper.Point(4, 4));
+	var secondStep = secondDelta.divide(new paper.Point(4, 4));
+	
+	var mainStepStroke = mainDelta.divide(new paper.Point(2, 2));
+	mainStep.angle += 90;
+	mainStepStroke.angle += 90;
+	var secondStepStroke = secondDelta.divide(new paper.Point(2, 2));
+	secondStep.angle += 90;
+	secondStepStroke.angle += 90;
 
-	var topStroke = event.middlePoint.add(stepStroke);
-	var bottomStroke = event.middlePoint.add(stepStroke.negate());
+	var mainTop = mainPoint.add(mainStep);
+	var mainBottom = mainPoint.add(mainStep.negate());
+	var secondTop = secondPoint.add(secondStep);
+	var secondBottom = secondPoint.add(secondStep.negate());
+
+	var mainTopStroke = mainPoint.add(mainStepStroke);
+	var mainBottomStroke = mainPoint.add(mainStepStroke.negate());
+	var secondTopStroke = secondPoint.add(secondStepStroke);
+	var secondBottomStroke = secondPoint.add(secondStepStroke.negate());
 
-	this.path.add(top);
-	this.path.insert(0, bottom);
-    this.path.smooth();
+	this.mainPath.add(mainTop);
+	this.mainPath.insert(0, mainBottom);
+    this.mainPath.smooth();
+    
+	this.secondPath.add(secondTop);
+	this.secondPath.insert(0, secondBottom);
+	this.secondPath.smooth();
 	
-	this.pathStroke.add(topStroke);
-	this.pathStroke.insert(0, bottomStroke);
-    this.pathStroke.smooth();
+	this.mainPathStroke.add(mainTopStroke);
+	this.mainPathStroke.insert(0, mainBottomStroke);
+    this.mainPathStroke.smooth();
+	
+	this.secondPathStroke.add(secondTopStroke);
+	this.secondPathStroke.insert(0, secondBottomStroke);
+    this.secondPathStroke.smooth();
+	
+	paper.view.draw();
 };
 
-searchCanvas.prototype.onMouseUp = function(event)
+searchCanvas.prototype.onPointerOut = function()
 {
-	this.pathStroke.remove();
-	this.path.remove();
+	this.mainPathStroke.remove();
+	this.mainPath.remove();
+	this.mainLastPoint = null;
+	
+	this.secondPathStroke.remove();
+	this.secondPath.remove();
+	this.secondLastPoint = null;
 };
 
 searchCanvas.prototype.onKeyDown = function(event)