front_idill/src/mosaic/js/pointers.js
changeset 44 8393d3473b98
child 45 0e29ae4568a0
--- /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