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