front_idill/src/mosaic/js/pointers.js
changeset 44 8393d3473b98
child 45 0e29ae4568a0
equal deleted inserted replaced
43:cefce0845ac5 44:8393d3473b98
       
     1 /*
       
     2  * Affiche les pointeurs.
       
     3 */
       
     4 mosaic.prototype.addPointers = function()
       
     5 {
       
     6 	var mainPointer = '<div id="mainPointer" class="pointers"></div>';
       
     7 	var secondPointer = '<div id="secondPointer" class="pointers"></div>';
       
     8 	$('body').append(mainPointer + secondPointer);
       
     9 	
       
    10 	$('#secondPointer').css(
       
    11 	{
       
    12 		top: $(window).height() / 2 - $('#secondPointer').height() / 2,
       
    13 		left: $(window).width() / 4 - $('#secondPointer').width() / 2
       
    14 	});
       
    15 	
       
    16 	this.secondPointerLastX = $(window).width() / 4 - $('#secondPointer').width() / 2;
       
    17 	this.secondPointerLastY = $(window).height() / 2 - $('#secondPointer').height() / 2;
       
    18 	
       
    19 	$('#mainPointer').css(
       
    20 	{
       
    21 		top: $(window).height() / 2 - $('#mainPointer').height() / 2,
       
    22 		left: $(window).width() * 3 / 4 - $('#mainPointer').width() / 2
       
    23 	});
       
    24 
       
    25 	this.mainPointerLastX = $(window).width() * 3 / 4 - $('#mainPointer').width() / 2;
       
    26 	this.mainPointerLastY = $(window).height() / 2 - $('#mainPointer').height() / 2;
       
    27 	
       
    28 	this.mainPointerIdleStartX = this.mainPointerLastX;
       
    29 	this.mainPointerIdleStartY = this.mainPointerLastY;
       
    30 	this.secondPointerIdleStartX = this.secondPointerLastX;
       
    31 	this.secondPointerIdleStartY = this.secondPointerLastY;
       
    32 }
       
    33 
       
    34 /*
       
    35  * Affiche/Masque le pointeur principal.
       
    36  * Main est un booléen valant vrai s'il faut afficher le pointeur.
       
    37 */
       
    38 mosaic.prototype.mainPointerDisplay = function(main)
       
    39 {
       
    40 	var _this = this;
       
    41 	
       
    42 	//On n'affiche pas les pointeurs dans le mode sans utilisateur ni utilisateur en phase d'approche.
       
    43 	if(this.currentMode != 'NO-USER' && this.currentMode.indexOf('INCOMING-') == -1)
       
    44 	{
       
    45 		if(main)
       
    46 		{
       
    47 			clearTimeout(this.arrowSpinnerTimeout);
       
    48 			
       
    49 			$('#mainPointer').fadeTo(this.config['timeFilling'], '1');
       
    50 			
       
    51 			//Si on a un seul pointeur, on affiche la mire.
       
    52 			if(!this.areBothPointersHere)
       
    53 			{
       
    54 				// console.log('ONE');
       
    55 				/*$('#mainPointer').css(
       
    56 				{
       
    57 					'background-image': 'url(./img/cursors/selector_gray.png)',
       
    58 					width: 85,
       
    59 					height: 85
       
    60 				});*/
       
    61 			}
       
    62 		}
       
    63 	}
       
    64 	
       
    65 	//Si le booléen est à faux, on masque le pointeur.
       
    66 	if(!main)
       
    67 	{
       
    68 		$('#spinner').remove();
       
    69 		
       
    70 		$('#mainPointer').fadeTo(this.config['timeFilling'], '0');
       
    71 		if(this.mainPointerNeighbourSelectedId != null)
       
    72 		{
       
    73 			// this.deselectNeighbour(this.mainPointerNeighbourSelectedId);
       
    74 		}
       
    75 		
       
    76 		//Si on a zoomé sur une vidéo.
       
    77 		if(this.currentMode == 'VIDEO' || this.currentMode == 'SEARCH')
       
    78 		{
       
    79 			//On annule aussi la TL s'il y a lieu.
       
    80 			if(this.isTLSelected())
       
    81 			{
       
    82 				this.isTLRequested = false;
       
    83 				clearTimeout(this.selectTLTimeout);
       
    84 			}
       
    85 		}
       
    86 		
       
    87 		if(this.isTLSelectedByMainPointer)
       
    88 		{
       
    89 			//On déselectionne la TL.
       
    90 			this.exitTimeline('');
       
    91 		}
       
    92 	}
       
    93 }
       
    94 /*
       
    95  * Affiche/Masque le pointeur secondaire.
       
    96  * Main est un booléen valant vrai s'il faut afficher le pointeur.
       
    97 */
       
    98 mosaic.prototype.secondPointerDisplay = function(second)
       
    99 {
       
   100 	//On n'affiche pas les pointeurs dans le mode sans utilisateur ni utilisateur en phase d'approche.
       
   101 	if(this.currentMode != 'NO-USER' && this.currentMode.indexOf('INCOMING-') == -1)
       
   102 	{
       
   103 		if(second)
       
   104 		{
       
   105 			clearTimeout(this.arrowSpinnerTimeout);
       
   106 			
       
   107 			$('#secondPointer').fadeTo(this.config['timeFilling'], '1');
       
   108 			
       
   109 			//Si on a un seul pointeur, on affiche la mire.
       
   110 			if(!this.areBothPointersHere)
       
   111 			{
       
   112 				// console.log('ONE');
       
   113 				/*$('#secondPointer').css(
       
   114 				{
       
   115 					'background-image': 'url(./img/cursors/selector_gray.png)',
       
   116 					width: 85,
       
   117 					height: 85
       
   118 				});*/
       
   119 			}
       
   120 		}
       
   121 	}
       
   122 	
       
   123 	//Si le booléen est à faux, on masque le pointeur.
       
   124 	if(!second)
       
   125 	{
       
   126 		$('#spinner').remove();
       
   127 		
       
   128 		$('#secondPointer').fadeTo(this.config['timeFilling'], '0');
       
   129 		if(this.secondPointerNeighbourSelectedId != null)
       
   130 		{
       
   131 			// this.deselectNeighbour(this.secondPointerNeighbourSelectedId);
       
   132 		}
       
   133 		
       
   134 		if(this.isTLSelectedBySecondPointer)
       
   135 		{
       
   136 			//On déselectionne la TL.
       
   137 			this.exitTimeline('');
       
   138 		}
       
   139 	}
       
   140 }
       
   141 
       
   142 /*
       
   143  * Raffraîchit la position des pointeurs.
       
   144 */
       
   145 mosaic.prototype.refreshMainPointer = function(x, y)
       
   146 {
       
   147 	// console.log('                                    DEBUG MP');
       
   148 	if(this.currentMode == "NO-USER" || this.currentMode.indexOf('INCOMING-') != -1)
       
   149 	{
       
   150 		return;
       
   151 	}
       
   152 	
       
   153 	if(!this.mouseInteractions)
       
   154 	{
       
   155 		x *= 7;
       
   156 		y *= 7;
       
   157 		x -= $(window).width() * 3 / 4;
       
   158 		y -= $(window).height() * 2 / 4;
       
   159 	}
       
   160 	
       
   161 	//Si le pointeur quitte la fenêtre en X, on ne le change pas.
       
   162 	// console.log('x : ' + x + ' mplx : ' + this.mainPointerLastX);
       
   163 	if(x < 0 || x > $(window).width())
       
   164 	{
       
   165 		x = this.mainPointerLastX;
       
   166 	}
       
   167 	//Sinon, on le met à jour.
       
   168 	else
       
   169 	{
       
   170 		this.mainPointerLastX = x;
       
   171 	}
       
   172 	
       
   173 	//Si le pointeur quitte la fenêtre en Y, on ne le change pas.
       
   174 	if(y < 0 || y > $(window).height())
       
   175 	{
       
   176 		y = this.mainPointerLastY;
       
   177 	}
       
   178 	//Sinon, on le met à jour.
       
   179 	else
       
   180 	{
       
   181 		this.mainPointerLastY = y;
       
   182 	}
       
   183 	
       
   184 	var pointerX = x - $('#mainPointer').width()/2, pointerY = y - $('#mainPointer').height()/2;
       
   185 	var _this = this;
       
   186 	
       
   187 	$('#mainPointer').css(
       
   188 	{
       
   189 		top: pointerY,
       
   190 		left: pointerX
       
   191 	});
       
   192 	
       
   193 	if($('#spinner').length > 0)
       
   194 	{
       
   195 		$('#spinner').css(
       
   196 		{
       
   197 			top: pointerY,
       
   198 			left: pointerX
       
   199 		});
       
   200 	}
       
   201 	
       
   202 	var snapshot = null;
       
   203 	
       
   204 	if(this.currentMode == 'MOSAIC' || this.currentMode == 'FILTER' && this.isMosaicFiltered)
       
   205 	{
       
   206 		snapshot = this.pointerPositionToSN(pointerX, pointerY, true);
       
   207 		
       
   208 		if(this.previousZoomedSN != null)
       
   209 		{
       
   210 			var id = this.previousZoomedSN.attr('id').replace('snapshotDiv-', '');
       
   211 		}
       
   212 		
       
   213 		if(snapshot == null)
       
   214 		{
       
   215 			this.isOnASnapshot = false;
       
   216 			this.lastNonNullSN = this.previousZoomedSN;
       
   217 			this.preUnzoom();
       
   218 			
       
   219 			$('#mainPointer').css('background-image', 'url(./img/cursors/pointer.png)');
       
   220 		}
       
   221 		
       
   222 		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)
       
   223 		{
       
   224 			this.isOnASnapshot = true;
       
   225 			this.previousZoomedSN = snapshot;
       
   226 			this.lastNonNullSN = null;
       
   227 			this.preZoom(snapshot);
       
   228 			
       
   229 			$('#mainPointer').css('background-image', 'url(./img/cursors/selector_gray.png)');
       
   230 			// console.log(this.isMainPointerDisplayed + ' ' + this.isSecondPointerDisplayed);
       
   231 		}
       
   232 		
       
   233 		//Si on se trouve actuellement dans une recherche par gestures.
       
   234 		// /!\ // RAJOUTE EN ATTENDANT UN GESTE DE CANCEL.
       
   235 		if(this.isMosaicFiltered && !this.isMosaicFiltering)
       
   236 		{
       
   237 			console.log('CHECK IF ON NOTIFY GESTURE');
       
   238 			this.checkIfPointerIsOnSearchNotification(pointerX, pointerY, $('#mainPointer'));
       
   239 		}
       
   240 	}
       
   241 	else if(this.currentMode == 'VIDEO' || this.currentMode == 'SEARCH' || this.currentMode == 'TIMELINE')
       
   242 	{
       
   243 		//On vérifie si on veut sélectionner la TL.
       
   244 		if((this.currentMode != 'TIMELINE' || this.isTLRequested) && this.playerIsReady && !this.isTLSelectedBySecondPointer && !this.helpDisplayed)
       
   245 		{
       
   246 			// console.log('(1) SP : ' + this.isTLSelectedBySecondPointer + ' MP : ' + this.isTLSelectedByMainPointer);
       
   247 			if(this.isTLSelected(true, true) && !this.isTLRequested)
       
   248 			{
       
   249 				// console.log('(2) TIMELINE REQUESTED ' + this.date());
       
   250 				// $('.a').css('background-color', '#f00');
       
   251 				//On a demandé à aller dans la TL.
       
   252 				this.isTLRequested = true;
       
   253 				this.isTLSelectedByMainPointer = true;
       
   254 				this.isTLSelectedBySecondPointer = false;
       
   255 				// console.log('(1) SP : ' + this.isTLSelectedBySecondPointer + ' MP : ' + this.isTLSelectedByMainPointer);
       
   256 				this.currentMode = 'TIMELINE';
       
   257 				this.player.widgets[0].selectTimeline();
       
   258 				$('#mainPointer').css('background-image', 'url(./img/cursors/selector_gray.png)');
       
   259 				
       
   260 				//On met le spinner gif sur le pointeur.
       
   261 				var spinner = "<img id='spinner'></div>";
       
   262 				$('body').append(spinner);
       
   263 				$('#spinner').css(
       
   264 				{
       
   265 					position: 'absolute',
       
   266 					top: $('#mainPointer').position().top,
       
   267 					left: $('#mainPointer').position().left,
       
   268 					width: 85,
       
   269 					height: 85,
       
   270 					'z-index': 600
       
   271 				});
       
   272 				$('#spinner').attr('src', './img/cursors/selector_anim.gif');
       
   273 				
       
   274 				this.selectTLTimeout = setTimeout(function()
       
   275 				{
       
   276 					//On permet l'interaction après un laps de temps.
       
   277 					_this.canSlideInTL = true;
       
   278 					
       
   279 					$('.notifications').remove();
       
   280 					_this.timelineTimeline();
       
   281 					
       
   282 					// console.log('(4) TIMELINE SLIDE ' + _this.date());
       
   283 				}, this.config['timeoutSlideTL']);
       
   284 			}
       
   285 			else if(!this.isTLSelected(true, true) && this.isTLRequested)
       
   286 			{
       
   287 				// console.log('(3) TIMELINE ABORTED');
       
   288 				this.isTLRequested = false;
       
   289 				clearTimeout(this.selectTLTimeout);
       
   290 				//On déselectionne la TL.
       
   291 				this.exitTimeline('');
       
   292 			}
       
   293 		}
       
   294 		
       
   295 		if(this.isTLSelectedByMainPointer && !this.isTLSelected(false, true))
       
   296 		{
       
   297 			// console.log('(4) TIMELINE EXITED');
       
   298 			// $('.a').css('background-color', '#0f0');
       
   299 			
       
   300 			//On déselectionne la TL.
       
   301 			this.exitTimeline('');
       
   302 		}
       
   303 
       
   304 		// var zoomX = pointerX, zoomY = pointerY;
       
   305 		var zoomX = pointerX - this.notifyLeftVideo, zoomY = pointerY - this.notifyTopVideo;
       
   306 		
       
   307 		//Si on a sélectionné la TL et qu'on a le pointeur droit dessus, on peut modifier la position de lecture.
       
   308 		if(this.currentMode == 'TIMELINE' && this.playerIsReady && !this.isSecondPointerDisplayed && this.canSlideInTL)
       
   309 		{
       
   310 			var time, TL = $('.Ldt-Timeline'), P = $('.LdtPlayer');
       
   311 			
       
   312 			if(pointerX < P.position().left)
       
   313 			{
       
   314 				time = 0;
       
   315 				// console.log('trop à droite');
       
   316 			}
       
   317 			else if(pointerX > (+P.position().left + TL.width()))
       
   318 			{
       
   319 				time = this.player.widgets[0].source.getDuration().getSeconds();
       
   320 				// console.log('trop à gauche');
       
   321 				// time = 0;
       
   322 			}
       
   323 			else
       
   324 			{
       
   325 				time = this.player.widgets[0].scaleIntervals(P.position().left, (+P.position().left + TL.width()), 0, this.player.widgets[0].source.getDuration().getSeconds(), pointerX);
       
   326 				// console.log(time);
       
   327 			}
       
   328 			
       
   329 			this.player.popcorn.currentTime(time);
       
   330 		}
       
   331 		
       
   332 		
       
   333 		//Si on se trouve actuellement dans une recherche par gestures.
       
   334 		if(this.isCurrentlyInASearchByGesture)
       
   335 		{
       
   336 			this.checkIfPointerIsOnSearchNotification(pointerX, pointerY, $('#mainPointer'));
       
   337 		}
       
   338 		
       
   339 		//on vérifie si le pointeur est sur un snapshot zoomé.
       
   340 		snapshot = this.pointerPositionToSN(zoomX, zoomY, true);
       
   341 		if(snapshot == null)
       
   342 		{
       
   343 			$('#mainPointer').css('background-image', 'url(./img/cursors/pointer.png)');
       
   344 			snapshot = this.pointerPositionToAN(pointerX, pointerY);
       
   345 		}
       
   346 		
       
   347 		// console.log(snapshot);
       
   348 		
       
   349 		var intValueOfId;
       
   350 		//Si c'est le cas.
       
   351 		if(snapshot != null && snapshot.length > 0)
       
   352 		{
       
   353 			//S'il s'agit d'un voisin additionnel.
       
   354 			if(snapshot.attr('id').indexOf('borderNeighbour') != -1)
       
   355 			{
       
   356 				intValueOfId = parseInt(snapshot.attr('id').replace('borderNeighbour-', ''));
       
   357 			}
       
   358 			//Sinon si c'est un voisin normal.
       
   359 			else
       
   360 			{
       
   361 				intValueOfId = parseInt(snapshot.attr('id').replace('snapshotDiv-', ''));
       
   362 			}
       
   363 		}
       
   364 		else
       
   365 		{
       
   366 			intValueOfId = -2;
       
   367 		}
       
   368 		
       
   369 		//Si c'est un voisin additionnel.
       
   370 		if(snapshot != null && snapshot.attr('id').indexOf('borderNeighbour') != -1)
       
   371 		{
       
   372 			//S'il a été trouvé.
       
   373 			if(intValueOfId > -1 && intValueOfId < 5)
       
   374 			{
       
   375 				//On le sélectionne.
       
   376 				this.selectNeighbour(snapshot, $('#mainPointer'));
       
   377 				this.mainPointerExitBorder = true;
       
   378 				this.mainPointerNeighbourSelectedId = intValueOfId + this.config['imagesToShow'];
       
   379 			}
       
   380 			else
       
   381 			{
       
   382 				if(this.mainPointerNeighbourSelectedId != null && this.mainPointerNeighbourSelectedId > -1)
       
   383 				{
       
   384 					this.deselectNeighbour(this.mainPointerNeighbourSelectedId);
       
   385 				}
       
   386 			}
       
   387 		}
       
   388 		else
       
   389 		{
       
   390 			//Si c'est un voisin.
       
   391 			if(_.include(this.neighboursIds, intValueOfId))
       
   392 			{
       
   393 				//On le sélectionne.
       
   394 				this.selectNeighbour(snapshot, $('#mainPointer'));
       
   395 				clearTimeout(this.moveToNeighbourTimeout);
       
   396 				clearTimeout(this.mainPointerExitBorderTimeout);
       
   397 				this.mainPointerExitBorder = true;
       
   398 				this.mainPointerNeighbourSelectedId = intValueOfId;
       
   399 			}
       
   400 			else
       
   401 			{
       
   402 				if(this.mainPointerNeighbourSelectedId != null && this.mainPointerNeighbourSelectedId > -1)
       
   403 				{
       
   404 					this.deselectNeighbour(this.mainPointerNeighbourSelectedId);
       
   405 					
       
   406 					if(this.mainPointerExitBorder && !this.secondPointerExitBorder)
       
   407 					{
       
   408 						this.correctMoveToNeighbour(this.mainPointerNeighbourSelectedId, zoomX, zoomY);
       
   409 					}
       
   410 					
       
   411 					this.moveToNeighbourTimeout = setTimeout(function()
       
   412 					{
       
   413 						_this.canMoveToNeighbour = false;
       
   414 					}, this.config['timeoutMoveToNeighbour']);
       
   415 					
       
   416 					this.mainPointerExitBorderTimeout = setTimeout(function()
       
   417 					{
       
   418 						if(_this.mainPointerExitBorder)
       
   419 						{
       
   420 							// console.log('Main pointer left');
       
   421 						}
       
   422 						_this.mainPointerExitBorder = false;
       
   423 					}, this.config['timeoutUnzoom']);
       
   424 					
       
   425 					this.checkForDezoom();
       
   426 				}
       
   427 			}
       
   428 		}
       
   429 	}
       
   430 }
       
   431 
       
   432 mosaic.prototype.refreshSecondPointer = function(x, y)
       
   433 {
       
   434 	if(this.currentMode == "NO-USER" || this.currentMode.indexOf('INCOMING-') != -1)
       
   435 	{
       
   436 		return;
       
   437 	}
       
   438 	
       
   439 	if(!this.mouseInteractions)
       
   440 	{
       
   441 		x *= 7;
       
   442 		y *= 7;
       
   443 		x -= $(window).width() * 3 / 4;
       
   444 		y -= $(window).height() * 2 / 4;
       
   445 	}
       
   446 	
       
   447 	//Si le pointeur quitte la fenêtre en X, on ne le change pas.
       
   448 	if(x < 0 || x > $(window).width())
       
   449 	{
       
   450 		x = this.secondPointerLastX;
       
   451 	}
       
   452 	//Sinon, on le met à jour.
       
   453 	else
       
   454 	{
       
   455 		this.secondPointerLastX = x;
       
   456 	}
       
   457 	
       
   458 	//Si le pointeur quitte la fenêtre en Y, on ne le change pas.
       
   459 	if(y < 0 || y > $(window).height())
       
   460 	{
       
   461 		y = this.secondPointerLastY;
       
   462 	}
       
   463 	//Sinon, on le met à jour.
       
   464 	else
       
   465 	{
       
   466 		this.secondPointerLastY = y;
       
   467 	}
       
   468 	
       
   469 	var pointerX = x - $('#secondPointer').width()/2, pointerY = y - $('#secondPointer').height()/2;
       
   470 	var _this = this;
       
   471 	
       
   472 	$('#secondPointer').css(
       
   473 	{
       
   474 		top: pointerY,
       
   475 		left: pointerX
       
   476 	});
       
   477 	
       
   478 	var snapshot = null;
       
   479 	
       
   480 	if(this.currentMode == 'MOSAIC' || this.currentMode == 'FILTER' && this.isMosaicFiltered)
       
   481 	{
       
   482 		snapshot = this.pointerPositionToSN(pointerX, pointerY, false);
       
   483 		
       
   484 		if(this.previousZoomedSN != null)
       
   485 		{
       
   486 			var id = this.previousZoomedSN.attr('id').replace('snapshotDiv-', '');
       
   487 		}
       
   488 		
       
   489 		if(snapshot == null)
       
   490 		{
       
   491 			this.isOnASnapshot = false;
       
   492 			this.lastNonNullSN = this.previousZoomedSN;
       
   493 			this.preUnzoom();
       
   494 			
       
   495 			$('#secondPointer').css('background-image', 'url(./img/cursors/pointer2.png)');
       
   496 		}
       
   497 		
       
   498 		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)
       
   499 		{
       
   500 			this.isOnASnapshot = true;
       
   501 			this.previousZoomedSN = snapshot;
       
   502 			this.lastNonNullSN = null;
       
   503 			this.preZoom(snapshot);
       
   504 			
       
   505 			$('#secondPointer').css('background-image', 'url(./img/cursors/selector_gray.png)');
       
   506 			// console.log(this.isMainPointerDisplayed + ' ' + this.isSecondPointerDisplayed);
       
   507 		}
       
   508 		
       
   509 		//Si on se trouve actuellement dans une recherche par gestures.
       
   510 		// /!\ // RAJOUTE EN ATTENDANT UN GESTE DE CANCEL.
       
   511 		if(this.isMosaicFiltered && !this.isMosaicFiltering)
       
   512 		{
       
   513 			this.checkIfPointerIsOnSearchNotification(pointerX, pointerY, $('#secondPointer'));
       
   514 		}
       
   515 	}
       
   516 	else if(this.currentMode == 'VIDEO' || this.currentMode == 'SEARCH' || this.currentMode == 'TIMELINE')
       
   517 	{
       
   518 		//On vérifie si on veut sélectionner la TL.
       
   519 		if((this.currentMode != 'TIMELINE' || this.isTLRequested) && this.playerIsReady && !this.isTLSelectedByMainPointer && !this.helpDisplayed)
       
   520 		{
       
   521 			// console.log('(1) SP : ' + this.isTLSelectedBySecondPointer + ' MP : ' + this.isTLSelectedByMainPointer);
       
   522 			if(this.isTLSelected(true, false) && !this.isTLRequested)
       
   523 			{
       
   524 				// console.log('(2) TIMELINE REQUESTED ' + this.date());
       
   525 				// $('.a').css('background-color', '#f00');
       
   526 				//On a demandé à aller dans la TL.
       
   527 				this.isTLRequested = true;
       
   528 				this.isTLSelectedBySecondPointer = true;
       
   529 				this.isTLSelectedByMainPointer = false;
       
   530 				// console.log('(1) SP : ' + this.isTLSelectedBySecondPointer + ' MP : ' + this.isTLSelectedByMainPointer);
       
   531 				this.currentMode = 'TIMELINE';
       
   532 				this.player.widgets[0].selectTimeline();
       
   533 				$('#secondPointer').css('background-image', 'url(./img/cursors/selector_gray.png)');
       
   534 				
       
   535 				//On met le spinner gif sur le pointeur.
       
   536 				var spinner = "<div id='spinner'></div>";
       
   537 				$('body').append(spinner);
       
   538 				$('#spinner').css(
       
   539 				{
       
   540 					position: 'absolute',
       
   541 					'background-repeat': 'no-repeat',
       
   542 					top: $('#mainPointer').position().top,
       
   543 					left: $('#mainPointer').position().left,
       
   544 					width: 85,
       
   545 					height: 85,
       
   546 					'z-index': 600
       
   547 				});
       
   548 				$('#spinner').attr('src', './img/cursors/selector_anim.gif');
       
   549 				
       
   550 				this.selectTLTimeout = setTimeout(function()
       
   551 				{
       
   552 					//On permet l'interaction après un laps de temps.
       
   553 					_this.canSlideInTL = true;
       
   554 					
       
   555 					$('.notifications').remove();
       
   556 					_this.timelineTimeline();
       
   557 					
       
   558 					// console.log('(4) TIMELINE SLIDE ' + _this.date());
       
   559 				}, this.config['timeoutSlideTL']);
       
   560 			}
       
   561 			else if(!this.isTLSelected(true, false) && this.isTLRequested)
       
   562 			{
       
   563 				// console.log('(3) TIMELINE ABORTED');
       
   564 				this.isTLRequested = false;
       
   565 				clearTimeout(this.selectTLTimeout);
       
   566 				//On déselectionne la TL.
       
   567 				this.exitTimeline('');
       
   568 			}
       
   569 		}
       
   570 		
       
   571 		if(this.isTLSelectedByMainPointer && !this.isTLSelected(false, false))
       
   572 		{
       
   573 			// console.log('(4) TIMELINE EXITED');
       
   574 			// $('.a').css('background-color', '#0f0');
       
   575 			
       
   576 			//On déselectionne la TL.
       
   577 			this.exitTimeline('');
       
   578 		}
       
   579 		
       
   580 		// var zoomX = pointerX, zoomY = pointerY;
       
   581 		var zoomX = pointerX - this.notifyLeftVideo, zoomY = pointerY - this.notifyTopVideo;
       
   582 		
       
   583 		//Si on a sélectionné la TL et qu'on a le pointeur droit dessus, on peut modifier la position de lecture.
       
   584 		if(this.currentMode == 'TIMELINE' && this.playerIsReady && !this.isMainPointerDisplayed && this.canSlideInTL)
       
   585 		{
       
   586 			var time, TL = $('.Ldt-Timeline'), P = $('.LdtPlayer');
       
   587 			
       
   588 			if(pointerX < P.position().left)
       
   589 			{
       
   590 				time = 0;
       
   591 				// console.log('trop à droite');
       
   592 			}
       
   593 			else if(pointerX > (+P.position().left + TL.width()))
       
   594 			{
       
   595 				time = this.player.widgets[0].source.getDuration().getSeconds();
       
   596 				// console.log('trop à gauche');
       
   597 				// time = 0;
       
   598 			}
       
   599 			else
       
   600 			{
       
   601 				time = this.player.widgets[0].scaleIntervals(P.position().left, (+P.position().left + TL.width()), 0, this.player.widgets[0].source.getDuration().getSeconds(), pointerX);
       
   602 				// console.log(time);
       
   603 			}
       
   604 			
       
   605 			this.player.popcorn.currentTime(time);
       
   606 		}
       
   607 		
       
   608 		//Si on se trouve actuellement dans une recherche par gestures.
       
   609 		if(this.isCurrentlyInASearchByGesture)
       
   610 		{
       
   611 			this.checkIfPointerIsOnSearchNotification(pointerX, pointerY, $('#secondPointer'));
       
   612 		}
       
   613 		
       
   614 		//on vérifie si le pointeur est sur un snapshot zoomé.
       
   615 		snapshot = this.pointerPositionToSN(zoomX, zoomY, false);
       
   616 		if(snapshot == null)
       
   617 		{
       
   618 			$('#secondPointer').css('background-image', 'url(./img/cursors/pointer2.png)');
       
   619 			snapshot = this.pointerPositionToAN(pointerX, pointerY);
       
   620 		}
       
   621 		
       
   622 		var intValueOfId;
       
   623 		//Si c'est le cas.
       
   624 		if(snapshot != null && snapshot.length > 0)
       
   625 		{
       
   626 			//S'il s'agit d'un voisin additionnel.
       
   627 			if(snapshot.attr('id').indexOf('borderNeighbour') != -1)
       
   628 			{
       
   629 				intValueOfId = parseInt(snapshot.attr('id').replace('borderNeighbour-', ''));
       
   630 			}
       
   631 			//Sinon si c'est un voisin normal.
       
   632 			else
       
   633 			{
       
   634 				intValueOfId = parseInt(snapshot.attr('id').replace('snapshotDiv-', ''));
       
   635 			}
       
   636 		}
       
   637 		else
       
   638 		{
       
   639 			intValueOfId = -2;
       
   640 		}
       
   641 		
       
   642 		//Si c'est un voisin additionnel.
       
   643 		if(snapshot != null && snapshot.attr('id').indexOf('borderNeighbour') != -1)
       
   644 		{
       
   645 			//S'il a été trouvé.
       
   646 			if(intValueOfId > -1 && intValueOfId < 5)
       
   647 			{
       
   648 				//On le sélectionne.
       
   649 				this.selectNeighbour(snapshot, $('#secondPointer'));
       
   650 				this.secondPointerExitBorder = true;
       
   651 				this.secondPointerNeighbourSelectedId = intValueOfId + this.config['imagesToShow'];
       
   652 			}
       
   653 			else
       
   654 			{
       
   655 				if(this.secondPointerNeighbourSelectedId != null && this.secondPointerNeighbourSelectedId > -1)
       
   656 				{
       
   657 					this.deselectNeighbour(this.secondPointerNeighbourSelectedId);
       
   658 					
       
   659 					/*this.secondPointerExitBorderTimeout = setTimeout(function()
       
   660 					{
       
   661 						if(_this.secondPointerExitBorder)
       
   662 						{
       
   663 							console.log('Second pointer left');
       
   664 						}
       
   665 						_this.secondPointerExitBorder = false;
       
   666 					}, this.config['timeoutUnzoom']);*/
       
   667 					
       
   668 					this.checkForDezoom();
       
   669 				}
       
   670 			}
       
   671 		}
       
   672 		else
       
   673 		{
       
   674 			//Si c'est un voisin.
       
   675 			if(_.include(this.neighboursIds, intValueOfId))
       
   676 			{
       
   677 				//On le sélectionne.
       
   678 				this.selectNeighbour(snapshot, $('#secondPointer'));
       
   679 				clearTimeout(this.moveToNeighbourTimeout);
       
   680 				clearTimeout(this.secondPointerExitBorderTimeout);
       
   681 				this.secondPointerExitBorder = true;
       
   682 				this.secondPointerNeighbourSelectedId = intValueOfId;
       
   683 			}
       
   684 			else
       
   685 			{
       
   686 				if(this.secondPointerNeighbourSelectedId != null && this.secondPointerNeighbourSelectedId > -1)
       
   687 				{
       
   688 					this.deselectNeighbour(this.secondPointerNeighbourSelectedId);
       
   689 					
       
   690 					if(!this.mainPointerExitBorder && this.secondPointerExitBorder)
       
   691 					{
       
   692 						this.correctMoveToNeighbour(this.secondPointerNeighbourSelectedId, zoomX, zoomY);
       
   693 					}
       
   694 					
       
   695 					this.moveToNeighbourTimeout = setTimeout(function()
       
   696 					{
       
   697 						_this.canMoveToNeighbour = false;
       
   698 					}, this.config['timeoutMoveToNeighbour']);
       
   699 					
       
   700 					this.secondPointerExitBorderTimeout = setTimeout(function()
       
   701 					{
       
   702 						if(_this.secondPointerExitBorder)
       
   703 						{
       
   704 							// console.log('Second pointer left');
       
   705 						}
       
   706 						_this.secondPointerExitBorder = false;
       
   707 					}, this.config['timeoutUnzoom']);
       
   708 					
       
   709 					this.checkForDezoom();
       
   710 				}
       
   711 			}
       
   712 		}
       
   713 	}
       
   714 }
       
   715 
       
   716 mosaic.prototype.detectIdlePointers = function()
       
   717 {
       
   718 	var mainPointer = $('#mainPointer');
       
   719 	var secondPointer = $('#secondPointer');
       
   720 	
       
   721 	//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.
       
   722 	if(Math.abs(this.mainPointerIdleStartX - this.mainPointerLastX) > mainPointer.width() || Math.abs(this.mainPointerIdleStartY - this.mainPointerLastY) > mainPointer.height() ||
       
   723 	Math.abs(this.secondPointerIdleStartX - this.secondPointerLastX) > secondPointer.width() || Math.abs(this.secondPointerIdleStartY - this.secondPointerLastY) > secondPointer.height())
       
   724 	{
       
   725 		//On réinitialise les dernières positions connues.
       
   726 		this.mainPointerIdleStartX = this.mainPointerLastX;
       
   727 		this.mainPointerIdleStartY = this.mainPointerLastY;
       
   728 		this.secondPointerIdleStartX = this.secondPointerLastX;
       
   729 		this.secondPointerIdleStartY = this.secondPointerLastY;
       
   730 		
       
   731 		this.removeIdlePointers();
       
   732 		this.pointersIdleNeedLaunch = true;
       
   733 	}
       
   734 	
       
   735 	if(this.helpDisplayed)
       
   736 	{
       
   737 		this.removeHelp();
       
   738 	}
       
   739 	
       
   740 	if((this.currentMode == 'SEARCH' || this.currentMode == 'FILTER') && !this.isSearchByCurvesOn)
       
   741 	{
       
   742 		// this.isSearchByCurvesOn = true;
       
   743 		// this.startSearch();
       
   744 	}
       
   745 	// console.log('DETECT IDLE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!');
       
   746 }
       
   747 
       
   748 mosaic.prototype.removeIdlePointers = function()
       
   749 {
       
   750 	clearTimeout(this.pointersSearchIdleTimeout);
       
   751 	// console.log(this.date() + ' - ra');
       
   752 }
       
   753 
       
   754 mosaic.prototype.launchIdlePointers = function()
       
   755 {
       
   756 	var _this = this;
       
   757 	
       
   758 	//Si on est en mode TL, on ne peut pas effectuer de recherche.
       
   759 	if(this.currentMode == 'TIMELINE' || (!this.playerIsReady && (this.currentMode == 'VIDEO' || this.currentMode == 'SEARCH')))
       
   760 	{
       
   761 		return;
       
   762 	}
       
   763 	
       
   764 	if(this.currentMode == 'VIDEO')// || this.currentMode == 'SEARCH')
       
   765 	{
       
   766 		//On peut le faire que sur la video au dessus de la TL.
       
   767 		var mainPointer = $('#mainPointer'), secondPointer = $('#secondPointer'), TL = $('.Ldt-Timeline');
       
   768 		var TLwidth = TL.width(), TLheight = TL.height();
       
   769 		var Ptop = $('.LdtPlayer').position().top, Pleft = $('.LdtPlayer').position().left;
       
   770 		var Pheight = $('.LdtPlayer').height();
       
   771 		var MPx = mainPointer.position().left + mainPointer.width() / 2, MPy = mainPointer.position().top + mainPointer.height() / 2;
       
   772 		var SPx = secondPointer.position().left + secondPointer.width() / 2, SPy = secondPointer.position().top + secondPointer.height() / 2;
       
   773 		
       
   774 		if(MPx < Pleft || MPx > (+Pleft + TLwidth) || MPy < Ptop || MPy > (+Ptop + Pheight - TLheight) ||
       
   775 		SPx < Pleft || SPx > (+Pleft + TLwidth) || SPy < Ptop || SPy > (+Ptop + Pheight - TLheight))
       
   776 		{
       
   777 			return;
       
   778 		}
       
   779 	}
       
   780 	
       
   781 	//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.
       
   782 	this.pointersSearchIdleTimeout = setTimeout(function()
       
   783 	{
       
   784 		if(!_this.areBothPointersHere)
       
   785 		{
       
   786 			return;
       
   787 		}
       
   788 		
       
   789 		// console.log('rdy for idle');
       
   790 		
       
   791 		if(_this.currentMode == "MOSAIC")
       
   792 		{
       
   793 			_this.currentMode = "FILTER";
       
   794 			// _this.currentMode = "FILTR";
       
   795 			_this.isMosaicFiltered = true;
       
   796 			
       
   797 			console.log(_this.date() + ' - ENTRE EN MODE FILTRAGE');
       
   798 			
       
   799 			$('.notifications').remove();
       
   800 			_this.filterSearch();
       
   801 		}
       
   802 		else if(_this.currentMode == "VIDEO" || _this.currentMode == "TIMELINE")
       
   803 		{
       
   804 			_this.currentMode = "SEARCH";
       
   805 			
       
   806 			console.log(_this.date() + ' - ENTRE EN MODE RECHERCHE');
       
   807 			// console.log('');
       
   808 			
       
   809 			$('.notifications').remove();
       
   810 			_this.searchSearch();
       
   811 		}
       
   812 		
       
   813 		if(!_this.canNotifyHelp)
       
   814 		{
       
   815 			_this.canNotifyHelpTimeout = setTimeout(function()
       
   816 			{
       
   817 				// console.log(_this.date() + ' CAN NOTIFY HELP');
       
   818 				_this.canNotifyHelp = true;
       
   819 			}, _this.config['timeoutCanNotifyHelp']);
       
   820 		}
       
   821 		
       
   822 		//Si on est déjà en recherche, et que l'aide n'est pas encore affichée, on l'affiche.
       
   823 		/*if(_this.currentMode == 'SEARCH' && _this.canNotifyHelp)
       
   824 		{
       
   825 			_this.notifyHelp(false);
       
   826 		}
       
   827 		if(_this.currentMode == 'FILTER' && _this.canNotifyHelp)
       
   828 		{
       
   829 			_this.notifyHelp(true);
       
   830 		}*/
       
   831 		
       
   832 	}, this.config['timeoutPointersIdle']);
       
   833 }
       
   834 
       
   835 mosaic.prototype.checkForBothPointersHere = function()
       
   836 {
       
   837 	var _this = this;
       
   838 	
       
   839 	if(!this.areBothPointersTimeoutLaunched)
       
   840 	{
       
   841 		this.areBothPointersHereTimeout = setTimeout(function()
       
   842 		{
       
   843 			_this.areBothPointersHere = false;
       
   844 			/*if(_this.isSearchByCurvesOn)
       
   845 			{
       
   846 				_this.leaveSearch();
       
   847 			}*/
       
   848 		}, this.config['timeoutAreBothPointersHere']);
       
   849 		
       
   850 		this.areBothPointersHereTimeoutLaunched = true;
       
   851 	}
       
   852 }
       
   853 
       
   854 mosaic.prototype.removeCheckForBothPointersHere = function()
       
   855 {
       
   856 	// console.log('TRY QUIT');
       
   857 	
       
   858 	// if(this.areBothPointersTimeoutLaunched)
       
   859 	// {
       
   860 		clearTimeout(this.areBothPointersHereTimeout);
       
   861 		// console.log('QUIT');
       
   862 	// }
       
   863 	this.areBothPointersHereTimeoutLaunched = false;
       
   864 }
       
   865 
       
   866 /*
       
   867  * Vérifie si on se trouve sur la notification de recherche par gesture.
       
   868 */
       
   869 mosaic.prototype.checkIfPointerIsOnSearchNotification = function(x, y, pointer)
       
   870 {
       
   871 	var _this = this;
       
   872 	var notification_search = $('#notify_search_1gesture');
       
   873 	
       
   874 	//Si la notification de recherche existe (dans le player).
       
   875 	if(notification_search.length > 0)
       
   876 	{
       
   877 		//Pictogramme actuel de la notification.
       
   878 		var currentPicto = notification_search.css('background-image');
       
   879 
       
   880 		//y -= this.MPTop_margin;
       
   881 		
       
   882 		/*console.log('===================================');
       
   883 		console.log('x : ' + x + ' > ' + notification_search.position().left);
       
   884 		console.log('x : ' + x + ' < ' + (+notification_search.position().left + notification_search.width()));
       
   885 		console.log('y : ' + y + ' > ' + notification_search.position().top);
       
   886 		console.log('y : ' + y + ' < ' + (+notification_search.position().top + notification_search.height()));
       
   887 		console.log('===================================');*/
       
   888 		
       
   889 		//Si le pointeur est sur la notification.
       
   890 		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()))
       
   891 		{
       
   892 			// console.log('IN NOTIFICATION');
       
   893 			if(!this.alreadyOnNotification && $('#spinner').length == 0)
       
   894 			{
       
   895 				notification_search.css('background-image', currentPicto.replace('/big/valid/', '/big/hover/'));
       
   896 				
       
   897 				console.log(this.date() + ' try remove not');
       
   898 				//On met le spinner gif sur le pointeur.
       
   899 				var spinner = "<img id='spinner'></div>";
       
   900 				$('body').append(spinner);
       
   901 				$('#spinner').css(
       
   902 				{
       
   903 					position: 'absolute',
       
   904 					top: pointer.position().top,
       
   905 					left: pointer.position().left,
       
   906 					width: 85,
       
   907 					height: 85,
       
   908 					'z-index': 600
       
   909 				});
       
   910 				$('#spinner').attr('src', './img/cursors/selector_anim.gif');
       
   911 				/*this.arrowSpinnerTimeout = setTimeout(function()
       
   912 				{
       
   913 					
       
   914 				}, this.config['timeoutRemoveSpinner']);*/
       
   915 				
       
   916 				this.removeNotificationByGestureTimeout = setTimeout(function()
       
   917 				{
       
   918 					if(_this.currentMode == 'SEARCH')
       
   919 					{
       
   920 						_this.player.widgets[0].removeSearchByGesture();
       
   921 						_this.currentMode = 'VIDEO';
       
   922 					}
       
   923 					else if(_this.currentMode == 'TIMELINE')
       
   924 					{
       
   925 						_this.player.widgets[0].removeSearchByGesture();
       
   926 						_this.currentMode = 'TIMELINE';
       
   927 					}
       
   928 					else if(_this.currentMode == 'FILTER')
       
   929 					{
       
   930 						_this.removeFilter();
       
   931 					}
       
   932 					
       
   933 					_this.alreadyOnNotification = false;
       
   934 					_this.isCurrentlyInASearchByGesture = false;
       
   935 					_this.currentSearchGesture = '';
       
   936 					_this.canNotifyHelp = false;
       
   937 				}, this.config['timeoutRemoveNotificationByGesture']);
       
   938 				this.alreadyOnNotification = true;
       
   939 			}
       
   940 		}
       
   941 		else
       
   942 		{
       
   943 			if(this.alreadyOnNotification)
       
   944 			{
       
   945 				notification_search.css('background-image', currentPicto.replace('/big/hover/', '/big/valid/'));
       
   946 				clearTimeout(this.removeNotificationByGestureTimeout);
       
   947 				this.alreadyOnNotification = false;
       
   948 				$('#spinner').remove();
       
   949 			}
       
   950 		}
       
   951 	}
       
   952 }