/*
* This file is part of the TraKERS\Front IDILL package.
*
* (c) IRI <http://www.iri.centrepompidou.fr/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

/*
 * Projet : TraKERS
 * Module : Front IDILL
 * Fichier : notifications.js
 * 
 * Auteur : alexandre.bastien@iri.centrepompidou.fr
 * 
 * Fonctionnalités : Définit les fonctions de notification (images apparaissant en haut de la fenêtre).
 */

/*
 * Affiche l'aide.
 * Est appelé dans les fichiers :
 * mosaic > fonctions manageControlEvents et onMouseDown.
 * curvesDetector > fonction updateDists.
*/
Mosaic.prototype.notifyHelp = function(inMosaic)
{
    //Si elle est déjà affichée on quitte.
    if(this.helpDisplayed)
    {
        return;
    }
	
	//Tous les noms d'images des gestes de recherche.
	var all_gestures_img = ['arret', 'chute', 'contact', 'group_spin', 'bend', 'knee_up', 'port_de_bras', 'grandjete', 'jump', 'spin', 'up_down', 'wave'];
	
	//Emplacement des images pour l'aide.
	var imgPath = './pictos/help/';
	
    //On enlève les autres notifications.
    this.removeNotifications();
    
    //On indique qu'elle est affiché.
    this.helpDisplayed = true;
    
    //Section des courbes de recherche.
    var search_2hands_tab;
    var search_2hands_tab_text;
    //Section des recherches corporelles.
    var search_body_tab;
    var search_body_tab_text;
    //Section des actions de contrôle sur l'interface.
    var controls_1hand_tab;
    var controls_1hand_tab_text;
    //Opacités (indique si elles sont actuellement implémentées).
    var search_2hands_tab_opacities;
    var search_body_tab_opacities;
    var controls_1hand_tab_opacities;
    var controls_1hand_tab_opacities;
    
    //Dossier contenant les images.
    var img_directory = './pictos/help/';
    
    //Si on est en mode d'intéraction souris, la recherche corporelle se fait par des courbes. On les regroupes donc dans la section des courbes.
    if(this.config.mouseInteractions)
    {
        search_2hands_tab = ['arret', 'contact', 'grandjete', 'group_spin', 'port_de_bras', 'spin', 'up_down', 'wave', 'chute', 'knee_up', 'jump', 'bend'];
        search_2hands_tab_text = ['no-motion', 'contact', 'grand-jete', 'screw', 'arc', 'circle', 'up-down', 'wave', 'fall', 'knee-up', 'jump', 'bend'];
        search_2hands_tab_opacities = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1];
    }
    else
    {
        search_2hands_tab = ['arret', 'contact', 'grandjete', 'group_spin', 'port_de_bras', 'spin', 'up_down', 'wave'];
        search_2hands_tab_text = ['no-motion', 'contact', 'grand-jete', 'screw', 'arc', 'circle', 'up-down', 'wave'];
        search_body_tab = ['chute', 'knee_up', 'jump', 'bend'];
        search_body_tab_text = ['fall', 'knee-up', 'jump', 'bend'];
        search_2hands_tab_opacities = [1, 1, 1, 1, 1, 1, 1, 1];
        search_body_tab_opacities = [1, 1, 1, 1];
    }
    
    //Dans la mosaique, on ne peut que sélectionner un snapshot.
    if(inMosaic)
    {
        controls_1hand_tab = ['selection'];
        controls_1hand_tab_text = ['controls_selection'];
        controls_1hand_tab_opacities = [1];
    }
    //Dans une vidéo, on peut aller d'un voisin à l'autre, bouger dans la timeline, dézoomer et swiper d'un marqueur à l'autre.
    else
    {
		if(this.config.mouseInteractions)
		{
			controls_1hand_tab = ['deplacer', 'move_down', 'move_up', 'move_right', 'move_left'];
			controls_1hand_tab_text = ['controls_timeline', 'controls_move_down', 'controls_move_up', 'controls_move_right', 'controls_move_left'];
			controls_1hand_tab_opacities = [1, 1, 1, 1, 1];
		}
		else
		{
			controls_1hand_tab = ['deplacer', 'precedent', 'suivant', 'mosaique_horizontal', 'mosaique_vertical', 'move_down', 'move_up', 'move_right', 'move_left'];
			controls_1hand_tab_text = ['controls_timeline', 'controls_previous', 'controls_next', 'controls_mos_horizontal', 'controls_mos_vertical', 'controls_move_down', 'controls_move_up', 'controls_move_right', 'controls_move_left'];
			controls_1hand_tab_opacities = [1, 1, 1, 1, 1, 1, 1, 1, 1];
		}
    }
    
    //Colonne de recherche.
    //Titre de la colonne de recherche.
    var search_title = "<div id='search_title'></div>";
    //Image de la colonne.
    var search_img = "<div id='search_img' class='notify_imgs'></div>";
    //Sous-titre.
    var search_2hands_text = "<div id='search_2hands_text'></div>";
    //Images de recherche par courbes.
    var search_2hands_imgs = "<div id='search_2hands_imgs' class='notify_imgs_big'>";
    
    //On crée les images.
    for(var i = 0 ; i < search_2hands_tab.length ; i++)
    {
        search_2hands_imgs += "<div id='2hands_" + search_2hands_tab[i] + "' class='notify_imgs_small' style='opacity: " + search_2hands_tab_opacities[i] + ";'></div>";
    }
    search_2hands_imgs += "</div>";
    
    //Sous-titre de la zone de recherche corporelle.
    var search_body_text;
    //Images de recherche corporelle.
    var search_body_imgs;
    
    //Si on est en mode Kinect.
    if(!this.config.mouseInteractions)
    {
        //On crée le texte et les images de la recherche corporelle.
        search_body_text = "<div id='search_body_text'></div>";
        search_body_imgs = "<div id='search_body_imgs' class='notify_imgs'>"
        
        for(var i = 0 ; i < search_body_tab.length ; i++)
        {
            search_body_imgs += "<div id='body_" + search_body_tab[i] + "' class='notify_imgs_small' style='opacity: " + search_body_tab_opacities[i] + ";'></div>";
        }
        search_body_imgs += "</div>";
		
		//On ajoute ce qu'il faut pour quitter l'aide.
		
    }
    
    //Titre de la colonne des actions de contrôle.
    var controls_title = "<div id='controls_title'></div>";
    //Image de la colonne.
    var controls_img = "<div id='controls_img' class='notify_imgs'></div>";
    //Sous-titre de la zone de contrôle de l'interface.
    var controls_1hand_text = "<div id='controls_1hand_text'></div>";
    //Images des actions de contrôle de l'interface.
    var controls_1hand_imgs;
    
    controls_1hand_imgs = "<div id='controls_1hand_imgs' class='notify_imgs'>";
    for(var i = 0 ; i < controls_1hand_tab.length ; i++)
    {
        controls_1hand_imgs += "<div id='1hand_" + controls_1hand_tab[i] + "' class='notify_imgs_small' style='opacity: " + controls_1hand_tab_opacities[i] + ";'></div>";
    }
    controls_1hand_imgs += "</div>";
    
    //Colonne de recherche du panneau d'aide.
    var help_search;
    
    //Dans le mode d'intéraction souris, les gestures de recherche corporelles ont été intégrées aux courbes.
    if(this.config.mouseInteractions)
    {
        help_search = "<div id='help_search'>" + search_title + search_img + search_2hands_text + search_2hands_imgs + "</div>";
    }
    else
    {
        help_search = "<div id='help_search'>" + search_title + search_img + search_2hands_text + search_2hands_imgs + search_body_text + search_body_imgs + "</div>";
    }
    
    //Colonne de contrôle du panneau d'aide.
    var help_controls;

    help_controls = "<div id='help_controls'>" + controls_title + controls_img + controls_1hand_text + controls_1hand_imgs + "</div>";
    
    //Panneau d'aide.
	//On crée les flèches au niveau du panneau d'aide.
    var notification_help = "<div id='notify_help'><div id='help_details_upArrow' class='help_details_arrows'></div>" + help_search + "<div id='help_sep'></div>" + help_controls + "<div id='help_details_downArrow' class='help_details_arrows'></div></div>";
    
    //On les ajoute à la mosaïque.
    $('body').append(notification_help);
	
	var notify_help = $('#notify_help');
    
	var notify_imgs_width = $('#notify_imgs_small').css('margin-leftf')
	
	$('.notify_imgs').css(
	{
		width: $('#notify_imgs_small')
	});
	
	if(this.isTablet)
	{
		//On rétrécit certaines images si on est sur une tablette.
		$('#search_img, #controls_img').css(
		{
			height: 150,
			'background-size': '150px 150px'
		});
		
		$('.notify_imgs_small').css(
		{
			height: 80,
			width: 80,
			'background-size': '80px 80px'
		});
		
		//On ajoute l'icone de sortie.
		this.exitIcon();
	}
	
    //On calcule leurs coordonnées et dimensions.
    var notify_width = $(window).width(), notify_height = $(window).height();
    var notify_margin = parseInt($('#notify_help').css('margin-left'));
    var notify_border = parseInt($('#notify_help').css('border-width'));
    //var notify_ = 10;
    
    //On les positionne.
    notify_help.css(
    {
        left: "0px",
        top: "0px",
        width: notify_width - notify_margin * 2,
        height: notify_height - notify_margin * 2,
        'z-index': 1000
    });
    
    //Position horizontale du séparateur de colonnes.
    var sep_left = $('#help_sep').position().left;
    //Marge du panneau d'aide.
    var help_margin = parseInt(notify_help.css('margin-left'));
    //On calcule la taille d'une zone de recherche (une des deux parties).
    var help_column_width = sep_left - help_margin;
	
    //Taille des marges des images.
    var margins = parseInt($('.notify_imgs_small').css('margin-left'));
    //Largeur des images.
    var widths = help_column_width / 5 - 4 * margins * 2;// $('.notify_imgs_small').width();
    //Hauteur des images.
    var heights = widths;//$('.notify_imgs_small').height();
    
	$('.notify_imgs_small').css(
	{
		width: widths,
		height: heights,
		'background-size': widths + 'px ' + heights + 'px',
		'font-size': widths / 5 + 'px',
		'padding-left': '0px'
	});
	
    //Longueur d'une image.
    var img_width = (margins * 2 + widths);
    
    //On récupère le nombre d'images affichables horizontalement pour les gestures de recherche à deux mains dans une des parties de l'aide.
    var search_2hands_n_imgs = Math.floor(help_column_width / img_width);
    //Calcul du padding-left de cette section.
    var search_2hands_padding_left = (help_column_width - search_2hands_n_imgs * img_width) / 2;
    
    //On positionne la section de recherche par courbes.
    $('#search_2hands_imgs').css(
    {
        'padding-left': search_2hands_padding_left,
        'height': ($('.notify_imgs_small').height() * 2 + parseInt($('.notify_imgs_small').css('margin-left')))
    });
    
    //On récupère le nombre d'images affichables horizontalement pour les gestures de recherche corporelles dans une des parties de l'aide.
    var search_body_n_imgs = Math.floor(help_column_width / img_width);
    //Calcul du padding-left de cette section.
    var search_body_padding_left = (help_column_width - search_body_n_imgs * img_width) / 2;
    
    //On positionne la section de recherche par gestures corporelles.
    $('#search_body_imgs').css(
    {
        'padding-left': search_body_padding_left,
        'height': ($('.notify_imgs_small').height() * 2 + parseInt($('.notify_imgs_small').css('margin-left')))
    });
    
    //On récupère le nombre d'images affichables horizontalement pour les gestures de controle dans une des parties de l'aide.
    var controls_1hand_n_imgs = Math.floor(help_column_width / img_width);
    //Calcul du padding-left de cette section.
    var controls_1hand_padding_left = (help_column_width - controls_1hand_n_imgs * img_width) / 2;
    
    //On potisionne la section des actions de contrôle de l'interface.
    $('#controls_1hand_imgs').css(
    {
        'padding-left': controls_1hand_padding_left,
        'height': ($('.notify_imgs_small').height())
    });
    
    //Longueur de la colonne de recherche.
    var search_width = $('#help_search').width();
    
    $('#search_title').html(this.helpText.search_title);
    var MI = '';
    
    //Le texte de recherche et les images changent en fonction du mode d'intéraction (souris/Kinect).
    if(this.config.mouseInteractions)
    {
		if(this.isTablet)
		{
			$('#search_2hands_text').html(this.helpText.search_touch_text);
		}
		else
		{
			$('#search_2hands_text').html(this.helpText.search_mouse_text);
		}
        MI = 'MI/';
    }
    else
    {
        $('#search_2hands_text').html(this.helpText.search_2hands_text);
    }
    
    //On affecte les images pour la recherche par courbes.
    for(var i = 0 ; i < search_2hands_tab.length ; i++)
    {
        $("#2hands_" + search_2hands_tab[i]).css("background-image", "url('" + img_directory + MI + search_2hands_tab[i] + ".png')");
		$("#2hands_" + search_2hands_tab[i]).html(this.notificationStrings[search_2hands_tab_text[i]]);
    }
    
    //Si on est en mode Kinect, on affecte les images de recherche corporelle.
    if(!this.config.mouseInteractions)
    {
        $('#search_body_text').html(this.helpText.search_body_text);
        
        for(var i = 0 ; i < search_body_tab.length ; i++)
        {
            $("#body_" + search_body_tab[i]).css("background-image", "url('" + img_directory + search_body_tab[i] + ".png')");
			$("#body_" + search_body_tab[i]).html(this.notificationStrings[search_body_tab_text[i]]);
        }
    }
    
    //Actions de contrôle de l'interface.
    $('#controls_title').html(this.helpText.controls_title);
	
	if(this.config.mouseInteractions)
	{
		if(this.isTablet)
		{
			$('#controls_1hand_text').html(this.helpText.controls_touch_text);
		}
		else
		{
			$('#controls_1hand_text').html(this.helpText.controls_mouse_text);
		}
	}
	else
	{
		$('#controls_1hand_text').html(this.helpText.controls_1hand_text);
	}
    
	//On affecte les images des actions de contrôle de l'interface.
	for(var i = 0 ; i < controls_1hand_tab.length ; i++)
	{
		$("#1hand_" + controls_1hand_tab[i]).css("background-image", "url('" + img_directory + controls_1hand_tab[i] + ".png')");
		$("#1hand_" + controls_1hand_tab[i]).html(this.helpText[controls_1hand_tab_text[i]]);
	}
	
    //On les fait apparaître.
    notify_help.css(
    {
        opacity: "1"
    });
    
    $('.notify_imgs_big').css(
    {
        opacity: "1"
    });
	
	//Si on est en mode d'interaction souris, on rajoute les détails.
	if(this.config.mouseInteractions)
	{
		//Dimensions des flèches.
		var arrowWidth = 50, arrowHeight = 50;
		
		//Nombre d'éléments présents dans les 2 divs de stockage des détails de l'aide.
		var helpDetailsLeftContainerLength = Math.ceil(this.helpDetailsGestures.length / 2), helpDetailsRightContainerLength = Math.floor(this.helpDetailsGestures.length / 2);
		
		//On ajoute les gestes des détails de l'aide.
		//On remplit les divs gauche et droite des détails par les éléments.
		var help_details_gestures = "<div id='help_details_left_container' class='help_details_containers'>";
		
		var i = 0;
		for(i ; i < helpDetailsLeftContainerLength ; i++)
		{
			//On récupère l'usage pour kinect/souris.
			var usage;
			if(this.config.mouseInteractions)
			{
				usage = this.helpDetailsGestures[i].usage_MI;
			}
			else
			{
				usage = this.helpDetailsGestures[i].usage_KI;
			}
			
			help_details_gestures += "<div><table border='0'><tr><td rowspan='4'><img class='helpDetailsImgs' src='" + imgPath + MI + all_gestures_img[i] + ".png' /></td><td><b>" +
			this.helpDetailsGesturesMetadata.name + '</b> : ' + this.helpDetailsGestures[i].name + "</td></tr><tr><td><b>" +
			this.helpDetailsGesturesMetadata.usage + '</b> : ' + usage + "</td></tr><tr><td><b>" +
			this.helpDetailsGesturesMetadata.desc + '</b> : ' + this.helpDetailsGestures[i].desc + "</td></tr></table></div>";
		}
		help_details_gestures += "</div><div id='help_details_right_container' class='help_details_containers'>";
		for(i ; i < this.helpDetailsGestures.length ; i++)
		{
			//On récupère l'usage pour kinect/souris.
			var usage;
			if(this.config.mouseInteractions)
			{
				usage = this.helpDetailsGestures[i].usage_MI;
			}
			else
			{
				usage = this.helpDetailsGestures[i].usage_KI;
			}
			
			help_details_gestures += "<div><table border='0'><tr><td rowspan='4'><img class='helpDetailsImgs' src='" + imgPath + MI + all_gestures_img[i] + ".png' /></td><td><b>" +
			this.helpDetailsGesturesMetadata.name + '</b> : ' + this.helpDetailsGestures[i].name + "</td></tr><tr><td><b>" +
			this.helpDetailsGesturesMetadata.usage + '</b> : ' + usage + "</td></tr><tr><td><b>" +
			this.helpDetailsGesturesMetadata.desc + '</b> : ' + this.helpDetailsGestures[i].desc + "</td></tr></table></div>";
		}
		
		help_details_gestures += "</div>";
		
		notify_help.append(help_details_gestures);
		
		//Hauteur totale de la plus longue colonne.
		var helpDetailsMaxContainerHeight = $('#help_details_left_container').height();
		
		//On positionne les flèches même si elles sont invisibles pour l'instant.
		$('#help_details_upArrow').css(
		{
			top: 0,
			left: notify_help.width() / 2 - arrowWidth / 2
		});
		$('#help_details_downArrow').css(
		{
			top: notify_help.height() - arrowHeight,
			left: notify_help.width() / 2 - arrowWidth / 2
		});
		
		$('.helpDetailsImg').css(
		{
			
		});
		
		var helpDetailsColumnWidth = (notify_help.width() - 2 * notify_margin) / 2 - 100;
		
		//On spécifie les colonnes.
		$('.help_details_containers').css(
		{
			position: 'absolute',
			width: notify_help.width() / 2 - notify_margin * 2 - notify_border * 2
	    });
		$('#help_details_left_container').css(
		{
			top: 0,
			left: 0
		});
		$('#help_details_right_container').css(
		{
			top: 0,
			left: notify_help.width() / 2
		});
		
		//Hauteur du panneau d'aide moins la hauteur des flèches.
		var notify_help_height_without_arrows = notify_help.height() - notify_margin * 2 - notify_border * 2 - $('.help_details_arrows').height() * 2;
		//On rajoute la page de départ de l'aide aux pages des détails de l'aide.
		this.helpDetailsPageLength = Math.ceil(helpDetailsMaxContainerHeight / notify_help_height_without_arrows) + 1;
		
		//On ajoute les flèches à l'interface.
		$('#help_details_upArrow').css(
		{
			top: 0,
			left: notify_help.width() / 2 - arrowWidth / 2
		});
		$('#help_details_downArrow').css(
		{
			top: notify_help.height() - arrowHeight,
			left: notify_help.width() / 2 - arrowWidth / 2
		});

		//Si on est sur la première page de l'aide.
		if(this.helpDetailsPageNumber == 0)
		{
			//On ne laisse pas la place du haut pour la flèche haut puisqu'on est sur la première page.
			$('.help_details_containers').css(
			{
				//top: 0,
				top: $('#notify_help').height(),
				// height: notify_help.height() - arrowHeight
			});
			//$('#notify_help').css('padding-bottom', arrowHeight);
			$('#help_details_downArrow').css('opacity', '1');
			
			//$('.help_details_containers').css('opacity', '0');
		}
		//Sinon si on est sur la dernière page de l'aide.
		else if(this.helpDetailsPageNumber + 1 == this.helpDetailsPageLength)
		{
			$('#help_details_downArrow').css('opacity', '0');
		}
		//Sinon on laisse la place pour revenir en arrière ou en avant.
		else
		{
			$('.help_details_containers').css(
			{
				top: arrowHeight,
				// height: notify_help.height() - arrowHeight * 2,
			});
		}
	}
}

/*
 * Supprime l'aide.
 * Est appelé dans les fichiers :
 * pointers > fonction detectIdlePointers.
 * mosaic > fonction manageControlEvents et onClick.
 * curvesDetector > fonction updateDists.
*/
Mosaic.prototype.removeHelp = function()
{
	// console.trace();
	
    //Si l'aide n'est pas affichée, on part.
    if(!this.helpDisplayed)
    {
        return;
    }
    
    var _this = this;
    
    //On fait disparaître l'aide.
    $('#notify_help').fadeOut(this.timeNotifyFade, function()
    {
        //On indique que l'aide n'est plus affichée, et on détruit le panneau.
        _this.helpDisplayed = false;
        _this.canNotifyHelp = true;
        $('#notify_help').remove();
		//On réinitialise la page.
		_this.helpDetailsPageNumber = 0;
    });
}

/*
 * Affichage de la notification de sélection & recherche dans la mosaïque.
 * Est appelé dans les fichiers :
 * zoomInteractions > fonctions preUnzoom et unzoom.
 * mosaic > fonction showNImages.
*/
Mosaic.prototype.mosaicSelectionAndSearch = function()
{
    //Si on n'est pas en mode mosaic, on part.
    if(this.currentMode != 'MOSAIC')
    {
        return;
    }
    
    //On spécifie les notifications en div.
    var notification_selection = "<div id='notify_selection' class='notifications'></div>";
    var notification_search = "<div id='notify_search' class='notifications'></div>";
    
	//On calcule leurs dimensions.
	var notify_width, notify_height, notify_margin;
	var selection_left, search_left;
	
	if(this.config.mouseInteractions)
	{
		//On ajoute à la mosaïque seulement la recherche.
		$('body').append(notification_search);
		notify_margin = parseInt($('.notifications').css('margin-left'));
		notify_width = $('.notifications').width();
		notify_height = $('.notifications').height();
		//On calcule leurs coordonnées.
		search_left = ($(window).width() / 2 - notify_width / 2 - notify_margin);
		var img = $('#notify_search').css('background-image');
		if(this.isTablet)
		{
			$('#notify_search').css('background-image', img.replace('notifications/', 'notifications/TI/'));
		}
		else
		{
			$('#notify_search').css('background-image', img.replace('notifications/', 'notifications/MI/'));
		}
	}
	else
	{
		//On les ajoute à la mosaïque.
		$('body').append(notification_selection + notification_search);
		notify_margin = parseInt($('.notifications').css('margin-left'));
		notify_width = $('.notifications').width();
		notify_height = $('.notifications').height();
		//On calcule leurs coordonnées.
		selection_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
		search_left = selection_left + notify_width + notify_margin;
		
		this.putText($('#notify_selection'), this.notificationStrings.select);
		
		$('#notify_selection').css(
		{
			left: selection_left
		});
	}
	
	this.putText($('#notify_search'), this.notificationStrings.search);
    
    //On les positionne.
    $('#notify_search').css(
    {
        left: search_left
    });
    
    //On les fait apparaître.
    $('.notifications').css(
    {
        opacity: "0.9"
    });
}

/*
 * Affichage de la notification de sélection dans la mosaïque.
 * Est appelé dans le fichier :
 * zoomInteractions > fonction preZoom.
*/
Mosaic.prototype.mosaicSelection = function()
{
    //Si on n'est pas en mode mosaic, on part.
    if(this.currentMode != 'MOSAIC')
    {
        return;
    }
    
    //On spécifie la notification en div.
    var notification_selection = "<div id='notify_selection' class='notifications'></div>";
    
    //On l'ajoute à la mosaïque.
    $('body').append(notification_selection);

    //On calcule ses coordonnées et dimensions.
    var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
    var notify_margin = parseInt($('.notifications').css('margin-left'));
    var selection_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
    
	if(this.config.mouseInteractions)
	{
		var img = $('#notify_selection').css('background-image');
		$('#notify_selection').css('background-image', img.replace('notifications/', 'notifications/MI/'));
	}
	
	this.putText($('#notify_selection'), this.notificationStrings.confirm);
	
    //On les positionne.
    $('#notify_selection').css(
    {
        left: selection_left
    });
    
    //On les fait apparaître.
    $('.notifications').css(
    {
        opacity: "0.9"
    });
}

/*
 * Affichage de la notification de recherche dans une demande de filtrage de la mosaïque.
 * Est appelé dans les fichiers :
 * pointers > fonction launchIdlePointers.
 * zoomInteractions > fonction preUnzoom.
*/
Mosaic.prototype.filterSearch = function()
{
    //Si on n'est pas en mode filtrage ou qu'aucune recherche n'est affectée au filtrage, on part.
    if(this.currentMode != 'FILTER' || this.filterSearchedType)
    {
        return;
    }
    
    //On spécifie la notification en div.
    var notification_search = "<div id='notify_search' class='notifications'></div>";
    
    //On l'ajoute à la mosaïque.
    $('body').append(notification_search);

    //On calcule ses coordonnées et dimensions.
    var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
    var notify_margin = parseInt($('.notifications').css('margin-left'));
    var search_left = $(window).width() / 2 - notify_width / 2 - notify_margin;
    
	if(this.config.mouseInteractions)
	{
		var img = $('#notify_search').css('background-image');
		
		if(this.isTablet)
		{
			$('#notify_search').css('background-image', img.replace('notifications/', 'notifications/TI/'));
		}
		else
		{
			$('#notify_search').css('background-image', img.replace('notifications/', 'notifications/MI/'));
		}
	}
	
	this.putText($('#notify_search'), this.notificationStrings.search);
	
    //On la positionne.
    $('#notify_search').css(
    {
        left: search_left
    });
    
    //On la fait apparaître.
    $('.notifications').css(
    {
        opacity: "0.9"
    });
}

/*
 * Affichage de la notification de recherche & sélection dans une demande de filtrage de la mosaïque.
 * Est appelé dans le fichier :
 * zoomInteractions > fonction preZoom.
*/
Mosaic.prototype.filterSearchAndSelection = function()
{
    //Si on n'est pas en mode filtrage ou qu'aucune recherche n'est affectée au filtrage, on part.
    if(this.currentMode != 'FILTER' || this.filterSearchedType)
    {
        return;
    }
    
    //On spécifie les notifications en div.
    var notification_selection = "<div id='notify_selection' class='notifications'></div>";
    var notification_search = "<div id='notify_search' class='notifications'></div>";
	
	//On les ajoute à la mosaïque.
	$('body').append(notification_selection + notification_search);
	
	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height(), notify_margin = parseInt($('.notifications').css('margin-left'));
	
	//On calcule leurs coordonnées.
	var selection_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
	var search_left = selection_left + notify_width + notify_margin;
	
	if(this.config.mouseInteractions)
	{
		var imgSel = $('#notify_selection').css('background-image');
		$('#notify_selection').css('background-image', imgSel.replace('notifications/', 'notifications/MI/'));
		
		var imgSearch = $('#notify_search').css('background-image');
		
		if(this.isTablet)
		{
			$('#notify_search').css('background-image', imgSearch.replace('notifications/', 'notifications/TI/'));
		}
		else
		{
			$('#notify_search').css('background-image', imgSearch.replace('notifications/', 'notifications/MI/'));
		}
	}
	
	this.putText($('#notify_selection'), this.notificationStrings.confirm);
	this.putText($('#notify_search'), this.notificationStrings.search);
	
    //On les positionne.
    $('#notify_selection').css(
    {
        left: selection_left
    });
    $('#notify_search').css(
    {
        left: search_left
    });
    
    //On les fait apparaître.
    $('.notifications').css(
    {
        opacity: "0.9"
    });
}

/*
 * Affichage de la notification de résultat de gesture dans la mosaïque filtrée.
 * Est appelé dans les fichiers :
 * zoomInteractions > fonction preUnzoom.
 * mosaic > onMouseUp et manageControlEvents.
 * curvesDetector > updateDists.
*/
Mosaic.prototype.filterGesture = function(gestureName, mode)
{
    //Si on n'est pas en mode filtrage ou qu'aucune recherche n'est affectée au filtrage, on part.
    if(this.currentMode != 'FILTER' || !this.filterSearchedType)
    {
        return;
    }
	
    var _this = this;
    
    //On spécifie les notifications en div.
    var notification_search_1gesture = "<div id='notify_search_1gesture' class='notifications'></div>";
    
    //On les ajoute à la mosaïque.
    $('body').append(notification_search_1gesture);
    
    //On calcule leurs coordonnées et dimensions.
    var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
    var notify_margin = parseInt($('.notifications').css('margin-left'));
    var point_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
    
    if(_.include(this.gestures, gestureName))
    {
        $('#notify_search_1gesture').css('background-image', 'url("./pictos/big/' + (this.config.mouseInteractions ? 'MI/' : '') + (this.gestureDelRequested ? 'hover' : 'valid') + '/' + gestureName + '.png")');
    }
    else if(mode == 'none')
    {
        $('#notify_search_1gesture').css('background-image', 'url("./pictos/big/normal/inconnu.png")');
    }
    
	this.putText($('#notify_search_1gesture'), this.notificationStrings[gestureName]);
	
    //On les positionne.
    $('#notify_search_1gesture').css(
    {
        top: 0,
        left: ($(window).width() - notify_width) / 2
    });
    
    //On les fait apparaître.
    $('.notifications').css(
    {
        opacity: "0.9"
    });
	
	if(this.isTablet)
	{
		this.searchExitIcon();
	}
}

/*
 * Affichage de la notification de résultat de gesture & de sélection dans la mosaïque filtrée.
 * Est appelé dans le fichier :
 * zoomInteractions > fonction preZoom.
*/
Mosaic.prototype.filterGestureAndSelection = function(gestureName, mode)
{
    //Si on n'est pas en mode filtrage ou qu'aucune recherche n'est affectée au filtrage, on part.
    if(this.currentMode != 'FILTER' || !this.filterSearchedType)
    {
        return;
    }
    
    //On spécifie les notifications en div.
    var notification_search_1gesture = "<div id='notify_search_1gesture' class='notifications'></div>";
    var notification_selection = "<div id='notify_selection' class='notifications'></div>";
    
    //On les ajoute à la mosaïque.
    $('body').append(notification_search_1gesture + notification_selection);

    //On calcule leurs coordonnées et dimensions.
    var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
    var notify_margin = parseInt($('.notifications').css('margin-left'));
    var search_1gesture_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
    var selection_left = search_1gesture_left + notify_width + notify_margin;
    
    if(_.include(this.gestures, gestureName))
    {
        $('#notify_search_1gesture').css('background-image', 'url("./pictos/big/' + (this.config.mouseInteractions ? 'MI/' : '') + mode + '/' + gestureName + '.png")');
    }
    else if(mode == 'none')
    {
        $('#notify_search_1gesture').css('background-image', 'url("./pictos/big/normal/inconnu.png")');
    }
	
	if(this.config.mouseInteractions)
	{
		var img = $('#notify_selection').css('background-image');
		$('#notify_selection').css('background-image', img.replace('notifications/', 'notifications/MI/'));
	}
	
	this.putText($('#notify_selection'), this.notificationStrings.confirm);
    this.putText($('#notify_search_1gesture'), this.notificationStrings[gestureName]);
	
    //On les positionne.
    $('#notify_search_1gesture').css(
    {
        left: search_1gesture_left
    });
    $('#notify_selection').css(
    {
        left: selection_left
    });
    
    //On les fait apparaître.
    $('.notifications').css(
    {
        opacity: "0.9"
    });
}

/*
 * Affiche la notification de dezoom.
 * Direction vaut left ou right.
 * Est appelé dans le fichier :
 * mosaic > fonction manageControlEvents.
*/
Mosaic.prototype.videoSwipe = function(direction)
{
    //Si on n'est pas en mode video ou qu'on n'est pas en train d'effectuer un swipe, on part.
    if(this.currentMode != 'VIDEO' || !this.isSwipe)
    {
        return;
    }
    
    var _this = this;
    
    //On spécifie les notifications en div.
    var notification_swipe = "<div id='notify_swipe' class='notifications'></div>";
    
    //On les ajoute à la mosaïque.
    $('body').append(notification_swipe);
    
    //On calcule leurs coordonnées et dimensions.
    var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
    var notify_margin = parseInt($('.notifications').css('margin-left'));
    var point_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
    
    var notifyTop = 0, notifyLeft = 0;
    
	if(direction == "left")
	{
		this.putText($('#notify_swipe'), this.notificationStrings.next);
	}
	else
	{
		this.putText($('#notify_swipe'), this.notificationStrings.previous);
	}
	
    //On les positionne.
    $('#notify_swipe').css(
    {
        top: -notifyTop,
        left: -notifyLeft + ($(window).width() - notify_width - notify_margin) / 2,
        'background-image': 'url(./pictos/notifications/swipe_' + direction + '.png)'
    });
	
    //On les fait apparaître.
    $('.notifications').css(
    {
        opacity: "0.9"
    });
}

/*
 * Affichage de la notification de résultat de move vers un voisin.
 * Est appelé dans le fichier :
 * neighbours > fonction selectNeighbour.
*/
Mosaic.prototype.videoMove = function(targetId)
{
    //Si on n'est pas en mode video, on part.
    if(this.currentMode != 'VIDEO')
    {
        return;
    }
    
    var _this = this;
    
    //On spécifie les notifications en div.
    var notification_move = "<div id='notify_move' class='notifications'></div>";
    
    //On les ajoute à la mosaïque.
    $('body').append(notification_move);
    
    //On calcule leurs coordonnées et dimensions.
    var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
    var notify_margin = parseInt($('.notifications').css('margin-left'));
    var move_left = $(window).width() / 2 - (notify_width) / 2 + notify_margin;
    
    var side = $.inArray(parseInt(targetId), this.neighboursIds);
    
    if(side == -1)
    {
        return;
    }
    
    var sides = ['left', 'right', 'up', 'down'];
    
    var notifyTop = 0, notifyLeft = 0;
    
	this.putText($('#notify_move'), this.notificationStrings.move);
	
    //On les positionne.
    $('#notify_move').css(
    {
        top: -notifyTop,
        left: -notifyLeft + move_left,
        'background-image': 'url(./pictos/notifications/move_' + sides[side] + '.png)'
    });
    
    //On les fait apparaître.
    $('.notifications').css(
    {
        opacity: "0.9"
    });
}

/*
 * Affichage de la notification de résultat de move vers un voisin & de dézoom dans une vidéo.
 * Est appelé dans le fichier :
 * neighbours > fonction selectNeighbour.
*/
Mosaic.prototype.videoMoveAndUnzoom = function(targetId)
{
    //Si on n'est pas en mode video, on part.
    if(this.currentMode != 'VIDEO')
    {
        return;
    }
    
    var _this = this;
    
    //On spécifie les notifications en div.
    var notification_move = "<div id='notify_move' class='notifications'></div>";
    var notification_unzoom = "<div id='notify_unzoom' class='notifications'></div>";
    
    //On les ajoute à la mosaïque.
    $('body').append(notification_move + notification_unzoom);
    
    //On calcule leurs coordonnées et dimensions.
    var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
    var notify_margin = parseInt($('.notifications').css('margin-left'));
    var move_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
    var unzoom_left = move_left + notify_width + notify_margin;
    
    var side = $.inArray(parseInt(targetId), this.neighboursIds);
    
    if(side == -1)
    {
        return;
    }
    
    var sides = ['left', 'right', 'up', 'down'];
    var unzooms = ['horizontal', 'vertical'];
    
    var notifyTop = 0, notifyLeft = 0;
    
	this.putText($('#notify_move'), this.notificationStrings.move);
	this.putText($('#notify_unzoom'), this.notificationStrings.unzoom);
	
    //On les positionne.
    $('#notify_move').css(
    {
        top: -notifyTop,
        left: -notifyLeft + move_left,
        'background-image': 'url(./pictos/notifications/move_' + sides[side] + '.png)'
    });
    
    $('#notify_unzoom').css(
    {
        top: -notifyTop,
        left: -notifyLeft + unzoom_left,
        'background-image': 'url(./pictos/notifications/unzoom_' + unzooms[Math.floor(side / 2)] + '.png)'
    });
    
    //On les fait apparaître.
    $('.notifications').css(
    {
        opacity: "0.9"
    });
}

/*
 * Affichage de la notification de résultat de dézoom dans une vidéo.
 * Est appelé dans le fichier :
 * neighbours > fonction selectNeighbour.
*/
Mosaic.prototype.videoUnzoom = function(targetId)
{
    //Si on n'est pas en mode video, on part.
    if(this.currentMode != 'VIDEO')
    {
        return;
    }
    
    var _this = this;
    
    //On spécifie la notifications en div.
    var notification_unzoom = "<div id='notify_unzoom' class='notifications'></div>";
    
    //On l'ajoute à la mosaïque.
    $('body').append(notification_unzoom);
    
    //On calcule ses coordonnées et dimensions.
    var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
    var notify_margin = parseInt($('.notifications').css('margin-left'));
    var unzoom_left = $(window).width() / 2 - notify_width / 2 - notify_margin;
    
    var side = $.inArray(parseInt(targetId), this.neighboursIds);
    if(side == -1)
    {
        return;
    }
    
    var unzooms = ['horizontal', 'vertical'];
    
    var notifyTop = 0, notifyLeft = 0;
    
	this.putText($('#notify_unzoom'), this.notificationStrings.unzoom);
	
    //On la positionne.
    $('#notify_unzoom').css(
    {
        top: -notifyTop,
        left: -notifyLeft + unzoom_left,
        'background-image': 'url(./pictos/notifications/unzoom_' + unzooms[Math.floor(side / 2)] + '.png)'
    });
    
    //On les fait apparaître.
    $('.notifications').css(
    {
        opacity: "0.9"
    });
}

/*
 * Affichage de la notification de timeline dans une vidéo/recherche.
 * Est appelé dans le fichier :
 * pointers > fonction pointersTimelineSelection.
*/
Mosaic.prototype.timelineTimeline = function()
{
    //Si on n'est pas en mode timeline, on part.
    if(this.currentMode != 'TIMELINE')
    {
        return;
    }
    
    var _this = this;
    
    //On spécifie la notifications en div.
    var notification_timeline = "<div id='notify_timeline' class='notifications'></div>";
    
    //On l'ajoute à la mosaïque.
    $('body').append(notification_timeline);
    
    //On calcule ses coordonnées et dimensions.
    var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
    var notify_margin = parseInt($('.notifications').css('margin-left'));
    var timeline_left = $(window).width() / 2 - notify_width / 2 - notify_margin;
    
    var notifyTop = 0, notifyLeft = 0;
    
	this.putText($('#notify_timeline'), this.notificationStrings.timeline);
	
    //On la positionne.
    $('#notify_timeline').css(
    {
        top: -notifyTop,
        left: -notifyLeft + timeline_left
    });
    
    //On les fait apparaître.
    $('.notifications').css(
    {
        opacity: "0.9"
    });
}

/*
 * Affichage de la notification de recherche dans une vidéo de recherche.
 * Est appelé dans les fichiers :
 * neighbours > fonction deselectNeighbour.
 * pointers > fonction launchIdlePointers.
 * mosaic > fonction manageControlEvents.
*/
Mosaic.prototype.searchSearch = function()
{
    //Si on n'est pas en mode recherche dans une video ou qu'aucune recherche n'est effectuée, on part.
    if(this.currentMode != 'SEARCH' || this.isCurrentlyInASearchByGesture)
    {
        return;
    }
    
    var _this = this;
    
    //On spécifie la notifications en div.
    var notification_search = "<div id='notify_search' class='notifications'></div>";
    
    //On l'ajoute à la mosaïque.
    $('body').append(notification_search);
    
    //On calcule ses coordonnées et dimensions.
    var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
    var notify_margin = parseInt($('.notifications').css('margin-left'));
    var search_left = $(window).width() / 2 - notify_width / 2 - notify_margin;
    
    var notifyTop = 0, notifyLeft = 0;
    
	this.putText($('#notify_search'), this.notificationStrings.search);
	
    //On la positionne.
    $('#notify_search').css(
    {
        top: -notifyTop,
        left: -notifyLeft + search_left
    });
    
    //On les fait apparaître.
    $('.notifications').css(
    {
        opacity: "0.9"
    });
}

/*
 * Affichage de la notification de recherche & de swipe dans une vidéo de recherche.
 * Est appelé dans le fichier :
 * mosaic > fonction manageControlEvents.
*/
Mosaic.prototype.searchSearchAndSwipe = function(direction)
{
    //Si on n'est pas en mode recherche dans une video ou qu'aucune recherche n'est effectuée ou qu'on n'est pas en train de faire un swipe, on part.
    if(this.currentMode != 'SEARCH' || this.isCurrentlyInASearchByGesture || !this.isSwipe)
    {
        return;
    }
    
    var _this = this;
    
    //On spécifie les notifications en div.
    var notification_search = "<div id='notify_search' class='notifications'></div>";
    var notification_swipe = "<div id='notify_swipe' class='notifications'></div>";
    
    //On les ajoute à la mosaïque.
    $('body').append(notification_search + notification_swipe);
    
    //On calcule leurs coordonnées et dimensions.
    var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
    var notify_margin = parseInt($('.notifications').css('margin-left'));
    var search_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
    var swipe_left = search_left + notify_width + notify_margin;
    
    var notifyTop = 0, notifyLeft = 0;
    
	this.putText($('#notify_search'), this.notificationStrings.search);
	if(direction == "left")
	{
		this.putText($('#notify_swipe'), this.notificationStrings.next);
	}
	else
	{
		this.putText($('#notify_swipe'), this.notificationStrings.previous);
	}
	
    //On les positionne.
    $('#notify_search').css(
    {
        top: -notifyTop,
        left: -notifyLeft + search_left
    });
    $('#notify_swipe').css(
    {
        top: -notifyTop,
        left: -notifyLeft + swipe_left,
        'background-image': 'url(./pictos/notifications/swipe_' + direction + '.png)'
    });
    
    //On les fait apparaître.
    $('.notifications').css(
    {
        opacity: "0.9"
    });
}

/*
 * Affichage de la notification de recherche, de move vers un voisin.
 * Est appelé dans le fichier :
 * neighbours > fonction selectNeighbour.
*/
Mosaic.prototype.searchSearchAndMove = function(targetId)
{
    //Si on n'est pas en mode recherche dans une video ou qu'aucune recherche n'est effectuée, on part.
    if(this.currentMode != 'SEARCH' || this.isCurrentlyInASearchByGesture)
    {
        return;
    }
    
    //On spécifie les notifications en div.
    var notification_search = "<div id='notify_search' class='notifications'></div>";
    var notification_move = "<div id='notify_move' class='notifications'></div>";
    
    //On les ajoute à la mosaïque.
    $('body').append(notification_search + notification_move);
    
    //On calcule leurs coordonnées et dimensions.
    var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
    var notify_margin = parseInt($('.notifications').css('margin-left'));
    var search_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
    var move_left = search_left + notify_width + notify_margin;
    
    var side = $.inArray(parseInt(targetId), this.neighboursIds);
    
    if(side == -1)
    {
        return;
    }
    
    var sides = ['left', 'right', 'up', 'down'];
    
    var notifyTop = 0, notifyLeft = 0;
    
	this.putText($('#notify_search'), this.notificationStrings.search);
	this.putText($('#notify_move'), this.notificationStrings.move);
	
    //On les positionne.
    $('#notify_search').css(
    {
        top: -notifyTop,
        left: -notifyLeft + search_left
    });
    $('#notify_move').css(
    {
        top: -notifyTop,
        left: -notifyLeft + move_left,
        'background-image': 'url(./pictos/notifications/move_' + sides[side] + '.png)'
    });
    
    //On les fait apparaître.
    $('.notifications').css(
    {
        opacity: "0.9"
    });
}

/*
 * Affichage de la notification de recherche, de move vers un voisin & de dézoom dans une vidéo de recherche.
 * Est appelé dans le fichier :
 * neighbours > fonction selectNeighbour.
*/
Mosaic.prototype.searchSearchAndMoveAndUnzoom = function(targetId)
{
    //Si on n'est pas en mode recherche dans une video ou qu'aucune recherche n'est effectuée, on part.
    if(this.currentMode != 'SEARCH' || this.isCurrentlyInASearchByGesture)
    {
        return;
    }
    
    //On spécifie les notifications en div.
    var notification_search = "<div id='notify_search' class='notifications'></div>";
    var notification_move = "<div id='notify_move' class='notifications'></div>";
    var notification_unzoom = "<div id='notify_unzoom' class='notifications'></div>";
    
    //On les ajoute à la mosaïque.
    $('body').append(notification_search + notification_move + notification_unzoom);
    
    //On calcule leurs coordonnées et dimensions.
    var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
    var notify_margin = parseInt($('.notifications').css('margin-left'));
    var search_left = $(window).width() / 2 - (notify_width * 3 + notify_margin * 4) / 2;
    var move_left = search_left + notify_width + notify_margin;
    var unzoom_left = move_left + notify_width + notify_margin;
    
    var side = $.inArray(parseInt(targetId), this.neighboursIds);
    
    if(side == -1)
    {
        return;
    }
    
    var sides = ['left', 'right', 'up', 'down'];
    var unzooms = ['horizontal', 'vertical'];
    
    var notifyTop = 0, notifyLeft = 0;
    
	this.putText($('#notify_search'), this.notificationStrings.search);
	this.putText($('#notify_move'), this.notificationStrings.move);
	this.putText($('#notify_unzoom'), this.notificationStrings.unzoom);
	
    //On les positionne.
    $('#notify_search').css(
    {
        top: -notifyTop,
        left: -notifyLeft + search_left
    });
    $('#notify_move').css(
    {
        top: -notifyTop,
        left: -notifyLeft + move_left,
        'background-image': 'url(./pictos/notifications/move_' + sides[side] + '.png)'
    });
    $('#notify_unzoom').css(
    {
        top: -notifyTop,
        left: -notifyLeft + unzoom_left,
        'background-image': 'url(./pictos/notifications/unzoom_' + unzooms[Math.floor(side / 2)] + '.png)'
    });
    
    //On les fait apparaître.
    $('.notifications').css(
    {
        opacity: "0.9"
    });
}

/*
 * Affichage de la notification de recherche & de dézoom dans une vidéo de recherche.
 * Est appelé dans le fichier :
*/
Mosaic.prototype.searchSearchAndUnzoom = function()
{
    //Si on n'est pas en mode recherche dans une video ou qu'aucune recherche n'est effectuée, on part.
    if(this.currentMode != 'SEARCH' || this.isCurrentlyInASearchByGesture)
    {
        return;
    }
    
    var _this = this;
    
    //On spécifie les notifications en div.
    var notification_search = "<div id='notify_search' class='notifications'></div>";
    var notification_unzoom = "<div id='notify_unzoom' class='notifications'></div>";
    
    //On les ajoute à la mosaïque.
    $('body').append(notification_search + notification_unzoom);
    
    //On calcule leurs coordonnées et dimensions.
    var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
    var notify_margin = parseInt($('.notifications').css('margin-left'));
    var search_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
    var unzoom_left = search_left + notify_width + notify_margin;
    
    var side = $.inArray(parseInt(targetId), this.neighboursIds);
    
    if(side == -1)
    {
        return;
    }
    
    var unzooms = ['horizontal', 'vertical'];
    
    var notifyTop = 0, notifyLeft = 0;
    
	this.putText($('#notify_search'), this.notificationStrings.search);
	this.putText($('#notify_unzoom'), this.notificationStrings.unzoom);
	
    //On les positionne.
    $('#notify_move').css(
    {
        top: -notifyTop,
        left: -notifyLeft + search_left
    });
    
    $('#notify_unzoom').css(
    {
        top: -notifyTop,
        left: -notifyLeft + unzoom_left,
        'background-image': 'url(./pictos/notifications/unzoom_' + unzooms[Math.floor(side / 2)] + '.png)'
    });
    
    //On les fait apparaître.
    $('.notifications').css(
    {
        opacity: "0.9"
    });
}

/*
 * Affichage de la notification de résultat dans une vidéo de recherche.
 * Est appelé dans les fichiers :
 * neighbours > fonctions deselectNeighbour et moveToNeighbour.
 * playerControl > fonction exitTimeline.
 * zoomInteractions > fonction zoom.
 * mosaic > fonctions onMouseUp et manageControlEvents.
 * curvesDetector > fonction updateDists.
*/
Mosaic.prototype.searchGesture = function(gestureName, mode)
{
    //Si on n'est pas en mode recherche dans une video ou qu'aucune recherche n'est reconnue, on part.
    if(this.currentMode != 'SEARCH' || this.currentSearchGesture[this.centerId] == '')
    {
        return;
    }
    
    var _this = this;
    
    //On spécifie les notifications en div.
    var notification_search_1gesture = "<div id='notify_search_1gesture' class='notifications'></div>";
    
    //On les ajoute à la mosaïque.
    $('body').append(notification_search_1gesture);
	
    //On calcule leurs coordonnées et dimensions.
    var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
    var notify_margin = parseInt($('.notifications').css('margin-left'));
    var point_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
    
    if(_.include(this.gestures, gestureName))
    {
        $('#notify_search_1gesture').css('background-image', 'url("./pictos/big/' + (this.config.mouseInteractions ? 'MI/' : '') + mode + '/' + gestureName + '.png")');
    }
    else if(mode == 'none')
    {
        $('#notify_search_1gesture').css('background-image', 'url("./pictos/big/normal/inconnu.png")');
    }
    
	this.putText($('#notify_search_1gesture'), this.notificationStrings[gestureName]);
	
    //On les positionne.
    $('#notify_search_1gesture').css(
    {
        top: 0,
        left: ($(window).width() - notify_width) / 2
    });
    
    //On les fait apparaître.
    $('.notifications').css(
    {
        opacity: "0.9"
    });
	
	if(this.isTablet)
	{
		this.searchExitIcon();
	}
}

/*
 * Affichage de la notification de résultat & de swipe dans une vidéo de recherche.
 * Est appelé dans le fichier :
 * mosaic > fonction manageControlEvents.
*/
Mosaic.prototype.searchGestureAndSwipe = function(gestureName, mode, direction)
{
    //Si on n'est pas en mode recherche dans une video ou qu'aucune recherche n'est reconnue ou on ne fait pas de swipe, on part.
    if(this.currentMode != 'SEARCH' || this.currentSearchGesture[this.centerId] == '' || !this.isSwipe)
    {
        return;
    }
    
    var _this = this;
    
    //On spécifie les notifications en div.
    var notification_search_1gesture = "<div id='notify_search_1gesture' class='notifications'></div>";
    var notification_swipe = "<div id='notify_swipe' class='notifications'></div>";
    
    //On les ajoute à la mosaïque.
    $('body').append(notification_search_1gesture + notification_swipe);
	
    //On calcule leurs coordonnées et dimensions.
    var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
    var notify_margin = parseInt($('.notifications').css('margin-left'));
    var search_1gesture_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
    var swipe_left = search_1gesture_left + notify_width + notify_margin;
    
    if(_.include(this.gestures, gestureName))
    {
        $('#notify_search_1gesture').css('background-image', 'url("./pictos/big/' + (this.config.mouseInteractions ? 'MI/' : '') + mode + '/' + gestureName + '.png")');
    }
    else if(mode == 'none')
    {
        $('#notify_search_1gesture').css('background-image', 'url("./pictos/big/normal/inconnu.png")');
    }
	
	if(direction == "left")
	{
		this.putText($('#notify_swipe'), this.notificationStrings.next);
	}
	else
	{
		this.putText($('#notify_swipe'), this.notificationStrings.previous);
	}
    
	this.putText($('#notify_search_1gesture'), this.notificationStrings[gestureName]);
	
    //On les positionne.
    $('#notify_search_1gesture').css(
    {
        left: search_1gesture_left
    });
    $('#notify_swipe').css(
    {
        left: swipe_left,
        'background-image': 'url(./pictos/notifications/swipe_' + direction + '.png)'
    });
    
    //On les fait apparaître.
    $('.notifications').css(
    {
        opacity: "0.9"
    });
}

/*
 * Affichage de la notification de résultat, de move vers un voisin.
 * Est appelé dans le fichier :
 * neighbours > fonction selectNeighbour.
*/
Mosaic.prototype.searchGestureAndMove = function(gestureName, mode, targetId)
{
    //Si on n'est pas en mode recherche dans une video ou qu'aucune recherche n'est reconnue, on part.
    if(this.currentMode != 'SEARCH' || this.currentSearchGesture[this.centerId] == '')
    {
        return;
    }
    
    var _this = this;
    
    //On spécifie les notifications en div.
    var notification_search_1gesture = "<div id='notify_search_1gesture' class='notifications'></div>";
    var notification_move = "<div id='notify_move' class='notifications'></div>";
    
    //On les ajoute à la mosaïque.
    $('body').append(notification_search_1gesture + notification_move);
	
    //On calcule leurs coordonnées et dimensions.
    var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
    var notify_margin = parseInt($('.notifications').css('margin-left'));
    var search_1gesture_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
    var move_left = search_1gesture_left + notify_width + notify_margin;
    
    if(_.include(this.gestures, gestureName))
    {
        $('#notify_search_1gesture').css('background-image', 'url("./pictos/big/' + (this.config.mouseInteractions ? 'MI/' : '') + mode + '/' + gestureName + '.png")');
    }
    else if(mode == 'none')
    {
        $('#notify_search_1gesture').css('background-image', 'url("./pictos/big/normal/inconnu.png")');
    }
    
    var side = $.inArray(parseInt(targetId), this.neighboursIds);
    
    if(side == -1)
    {
        return;
    }
    
    var sides = ['left', 'right', 'up', 'down'];
    
	this.putText($('#notify_move'), this.notificationStrings.move);
	this.putText($('#notify_search_1gesture'), this.notificationStrings[gestureName]);
	
    //On les positionne.
    $('#notify_search_1gesture').css(
    {
        left: search_1gesture_left
    });
    $('#notify_move').css(
    {
        left: move_left,
        'background-image': 'url(./pictos/notifications/move_' + sides[side] + '.png)'
    });
    
    //On les fait apparaître.
    $('.notifications').css(
    {
        opacity: "0.9"
    });
	
	if(this.isTablet)
	{
		this.searchExitIcon();
	}
}

/*
 * Affichage de la notification de résultat, de move vers un voisin & de dézoom dans une vidéo de recherche.
 * Est appelé dans le fichier :
 * neighbours > fonction selectNeighbour.
*/
Mosaic.prototype.searchGestureAndMoveAndUnzoom = function(gestureName, mode, targetId)
{
    //Si on n'est pas en mode recherche dans une video ou qu'aucune recherche n'est reconnue, on part.
    if(this.currentMode != 'SEARCH' || this.currentSearchGesture[this.centerId] == '')
    {
        return;
    }
    
    var _this = this;
    
    //On spécifie les notifications en div.
    var notification_search_1gesture = "<div id='notify_search_1gesture' class='notifications'></div>";
    var notification_move = "<div id='notify_move' class='notifications'></div>";
    var notification_unzoom = "<div id='notify_unzoom' class='notifications'></div>";
    
    //On les ajoute à la mosaïque.
    $('body').append(notification_search_1gesture + notification_move + notification_unzoom);
    
    //On calcule leurs coordonnées et dimensions.
    var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
    var notify_margin = parseInt($('.notifications').css('margin-left'));
    var search_1gesture_left = $(window).width() / 2 - (notify_width * 3 + notify_margin * 4) / 2;
    var move_left = search_1gesture_left + notify_width + notify_margin;
    var unzoom_left = move_left + notify_width + notify_margin;
    
    if(_.include(this.gestures, gestureName))
    {
        $('#notify_search_1gesture').css('background-image', 'url("./pictos/big/' + (this.config.mouseInteractions ? 'MI/' : '') + mode + '/' + gestureName + '.png")');
    }
    else if(mode == 'none')
    {
        $('#notify_search_1gesture').css('background-image', 'url("./pictos/big/normal/inconnu.png")');
    }
    
    var side = $.inArray(parseInt(targetId), this.neighboursIds);
    
    if(side == -1)
    {
        return;
    }
    
    var sides = ['left', 'right', 'up', 'down'];
    var unzooms = ['horizontal', 'vertical'];
    
	this.putText($('#notify_move'), this.notificationStrings.move);
	this.putText($('#notify_unzoom'), this.notificationStrings.unzoom);
	this.putText($('#notify_search_1gesture'), this.notificationStrings[gestureName]);
	
    //On les positionne.
    $('#notify_search_1gesture').css(
    {
        left: search_1gesture_left
    });
    $('#notify_move').css(
    {
        left: move_left,
        'background-image': 'url(./pictos/notifications/move_' + sides[side] + '.png)'
    });
    $('#notify_unzoom').css(
    {
        left: unzoom_left,
        'background-image': 'url(./pictos/notifications/unzoom_' + unzooms[Math.floor(side / 2)] + '.png)'
    });
    
    //On les fait apparaître.
    $('.notifications').css(
    {
        opacity: "0.9"
    });
	
	if(this.isTablet)
	{
		this.searchExitIcon();
	}
}

/*
 * Affichage de la notification de résultat & de dézoom dans une vidéo de recherche.
 * Est appelé dans le fichier :
*/
Mosaic.prototype.searchGestureAndUnzoom = function(gestureName, mode, targetId)
{
    //Si on n'est pas en mode recherche dans une video ou qu'aucune recherche n'est reconnue, on part.
    if(this.currentMode != 'SEARCH' || this.currentSearchGesture[this.centerId] == '')
    {
        return;
    }
    
    var _this = this;
    
    //On spécifie les notifications en div.
    var notification_search_1gesture = "<div id='notify_search_1gesture' class='notifications'></div>";
    var notification_unzoom = "<div id='notify_unzoom' class='notifications'></div>";
    
    //On les ajoute à la mosaïque.
    $('body').append(notification_search_1gesture + notification_unzoom);
    
    //On calcule leurs coordonnées et dimensions.
    var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
    var notify_margin = parseInt($('.notifications').css('margin-left'));
    var search_1gesture_left = $(window).width() / 2 - (notify_width * 2 + notify_margin * 3) / 2;
    var unzoom_left = search_1gesture_left + notify_width + notify_margin;
    
    if(_.include(this.gestures, gestureName))
    {
        $('#notify_search_1gesture').css('background-image', 'url("./pictos/big/' + (this.config.mouseInteractions ? 'MI/' : '') + mode + '/' + gestureName + '.png")');
    }
    else if(mode == 'none')
    {
        $('#notify_search_1gesture').css('background-image', 'url("./pictos/big/normal/inconnu.png")');
    }
    
    var side = $.inArray(parseInt(targetId), this.neighboursIds);
    
    if(side == -1)
    {
        return;
    }
    
    var unzooms = ['horizontal', 'vertical'];
    
	this.putText($('#notify_unzoom'), this.notificationStrings.unzoom);
	this.putText($('#notify_search_1gesture'), this.notificationStrings[gestureName]);
	
    //On les positionne.
    $('#notify_search_1gesture').css(
    {
        left: search_1gesture_left
    });
    $('#notify_unzoom').css(
    {
        left: unzoom_left,
        'background-image': 'url(./pictos/notifications/unzoom_' + unzooms[Math.floor(side / 2)] + '.png)'
    });
    
    //On les fait apparaître.
    $('.notifications').css(
    {
        opacity: "0.9"
    });
}

/*
 * Affichage des notifications de gestures trouvées dans une recherche par courbes.
 * Est appelé dans le fichier :
 * curvesDetector > fonction updateDists.
*/
Mosaic.prototype.curvesGestures = function(gestures)
{
    //S'il n'y a pas de gestures à afficher.
    if(gestures.length == 0)
    {
        //On ajoute une seule notification.
        var notification_curves = "<div class='notifications' id='notify_curves'></div>";
        $('body').append(notification_curves);
        
        //On calcule leurs dimensions et coordonnées.
        var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
        var notify_margin = parseInt($('.notifications').css('margin-left'));
        var curves_left = $(window).width() / 2 - (notify_width + notify_margin * 2) / 2;
        
        $('#notify_curves').css(
        {
            left: curves_left,
            'background-image': 'url("./pictos/big/normal/inconnu.png")',
            opacity: '0.9'
        });
		
		this.putText($('#notify_curves'), this.notificationStrings["unknown"]);
		
        return;
    }
    
    //Sinon, on les met dans un tableau.
    var gestures_tab = gestures.split(';');
    
    var notifications_curves_gestures = "<div id='notify_curves_container'>";
    
    //On crée autant de notifications qu'il y a de gestures.
    for(var i = 0 ; i < gestures_tab.length ; i++)
    {
        notifications_curves_gestures += "<div class='notification_curves' id='notify_curves_" + gestures_tab[i] + "'></div>";
    }
	
	notifications_curves_gestures += "</div>";
    
    //On les ajoute à la mosaïque.
    $('body').append(notifications_curves_gestures);
    
    //On calcule leurs dimensions.
    var notify_width = $('.notification_curves').width(), notify_height = $('.notification_curves').height();
    var notify_margin = parseInt($('.notification_curves').css('margin-left'));
	
	//Nombre de notifications dans une ligne.
	var notify_in_a_row = Math.floor($(window).width() / (+notify_width + 2 * notify_margin));
	//Notifications sur la première ligne.
	var notify_in_first_row = (gestures_tab.length > notify_in_a_row) ? notify_in_a_row : gestures_tab.length;
	//Espace libre restant sur la ligne.
	var free_space = $(window).width() - notify_in_first_row * (+notify_width + 2 * notify_margin);
	
	//On met à jour le container.
	$('#notify_curves_container').css(
	{
		height: Math.ceil(gestures_tab.length * (+notify_width + 2 * notify_margin) / $(window).width()),
		'margin-left': free_space / 2,
		'margin-right': free_space / 2
	});
	
    //On calcule leurs dimensions et leur backgrounds.
	for(var i = 0 ; i < gestures_tab.length ; i++)
    {
        //On va chercher leurs backgrounds.
        $('#notify_curves_' + gestures_tab[i]).css('background-image', 'url("./pictos/big/' + (this.config.mouseInteractions ? 'MI/' : '') + 'normal/' + gestures_tab[i] + '.png")');
        
		this.putText($('#notify_curves_' + gestures_tab[i]), this.notificationStrings[gestures_tab[i]]);
    }
    
    //On les fait apparaître.
    $('.notification_curves').css(
    {
        opacity: "0.9"
    });
}

/*
 * Efface les notifications. Précède chaque notification.
 * Est appelé dans les fichiers :
 * neighbours > fonctions listenToNeighbours, selectNeighbour, deselectNeighbour et moveToNeighbour.
 * notifications > fonction notifyHelp.
 * playerControl > fonction exitTimeline.
 * pointers > fonctions pointersTimelineSelection, launchIdlePointers et removeSearchNotificationIfOnIt.
 * search > fonction removeFilter.
 * zoomInteractions > fonctions preZoom, preUnzoom, zoom et unzoom.
 * mosaic > fonctions onMouseUp, showNImages et manageControlEvents.
 * curvesDetector > fonction updateDists.
*/
Mosaic.prototype.removeNotifications = function()
{
    $('.notifications').remove();
    $('#notify_curves_container').remove();
    $('.notification_curves').remove();
}

/*
 * Place un texte sur la notification.
 * Est appelé dans chaque fonction servant à notifier dans le fichier de notification.
*/
Mosaic.prototype.putText = function(notification, text)
{
	notification.html(text);
}

/*
 * Affiche l'icone d'aide.
 * Est appelé dans les fichiers :
 * mosaic > fonction loadMosaic.
 * zoomInteractions > fonctions zoom et unzoom.
*/
Mosaic.prototype.helpIcon = function()
{
	this.removeHelpIcon();
	//On construit le div.
	var helpIcon = "<img id='helpIcon' src='./img/helpIcon.png' />";
	//On l'ajoute.
	$('body').append(helpIcon);
	//On spécifie ses coordonnées.
	$('#helpIcon').css(
	{
		top: 0,
		left: $(window).width() - $('#helpIcon').width() - 2 * parseInt($('#helpIcon').css('margin-left'))
	});
}

/*
 * Supprime l'icone d'aide.
 * Est appelé dans les fichiers :
 * zoomInteractions > fonctions zoom et unzoom.
 * notifications > fonction helpIcon.
*/
Mosaic.prototype.removeHelpIcon = function()
{
	this.isHelpIconZooming = false;
	this.isHelpIconZoomed = false;
	$('#helpIcon').remove();
}

/*
 * Agrandit l'icone d'aide.
 * Est appelé dans le fichier :
 * mosaic > fonction onMouseMove.
*/
Mosaic.prototype.showBigHelp = function()
{
	//Si on a déjà zoomé on quitte.
	if(this.isHelpIconZoomed || this.isHelpIconZooming)
	{
		return;
	}
	
	this.isHelpIconZooming = true;
	
	var _this = this;
	
	$('#helpIcon').animate(
	{
		width: 100,
		height: 100,
		left: $(window).width() - 100 - 2 * parseInt($('#helpIcon').css('margin-left'))
	}, this.config.timeShowBigHelp, function()
	{
		_this.isHelpIconZoomed = true;
		_this.isHelpIconZooming = false;
	});
}

/*
 * Rétrecit l'icone d'aide.
 * Est appelé dans le fichier :
 * mosaic > fonction onMouseMove.
*/
Mosaic.prototype.showSmallHelp = function()
{
	//Si on n'a pas zoomé on quitte.
	if(!this.isHelpIconZoomed || this.isHelpIconZooming)
	{
		return;
	}
	
	this.isHelpIconZooming = true;
	
	var _this = this;
	
	var helpIconWidth = $('#helpIcon').width();
	
	$('#helpIcon').animate(
	{
		width: 50,
		height: 50,
		left: $(window).width() - 50 - 2 * parseInt($('#helpIcon').css('margin-left'))
	}, this.config.timeShowBigHelp, function()
	{
		_this.isHelpIconZoomed = false;
		_this.isHelpIconZooming = false;
	});
}

/*
 * Affiche l'icone de sortie pour tablettes.
*/
Mosaic.prototype.exitIcon = function()
{
	this.removeExitIcon();
	//On construit le div.
	var exitIcon = "<img id='exitIcon' src='./img/exitIcon.png' />";
	//On l'ajoute.
	$('body').append(exitIcon);
	//On spécifie ses coordonnées.
	$('#exitIcon').css(
	{
		top: 0,
		left: $(window).width() - $('#exitIcon').width() - 2 * parseInt($('#exitIcon').css('margin-left')),
		'z-index': 1000
	});
}

/*
 * Supprime l'icone de sortie pour tablettes.
*/
Mosaic.prototype.removeExitIcon = function()
{
	$('#exitIcon').remove();
}

/*
 * Affiche l'icone de retour à la mosaïque pour tablettes.
*/
Mosaic.prototype.homeIcon = function()
{
	this.removeHomeIcon();
	//On construit le div.
	var homeIcon = "<img id='homeIcon' src='./img/homeIcon.png' />";
	//On l'ajoute.
	$('body').append(homeIcon);
	//On spécifie ses coordonnées.
	$('#homeIcon').css(
	{
		top: 0,
		left: 0,
		'z-index': 900
	});
}

/*
 * Supprime l'icone de sortie pour tablettes.
*/
Mosaic.prototype.removeHomeIcon = function()
{
	$('#homeIcon').remove();
}

/*
 * Affiche l'icone de sortie de recherche pour tablettes.
*/
Mosaic.prototype.searchExitIcon = function()
{
	//S'il n'y a pas de notification de recherche, on s'en va.
	if($('#notify_search_1gesture').length == 0)
	{
		return;
	}
	
	this.removeSearchExitIcon();
	//On construit le div.
	var searchExitIcon = "<img id='searchExitIcon' src='./img/exitIcon.png' />";
	//On l'ajoute.
	$('body').append(searchExitIcon);
	//On spécifie ses coordonnées.
	$('#searchExitIcon').css(
	{
		top: 0,
		left: +$('#notify_search_1gesture').position().left + $('#notify_search_1gesture').width() - $('#searchExitIcon').width() - parseInt($('#searchExitIcon').css('margin-left')) / 2,
		'z-index': 900
	});
}

/*
 * Supprime l'icone de sortie de recherche pour tablettes.
*/
Mosaic.prototype.removeSearchExitIcon = function()
{
	$('#searchExitIcon').remove();
}

/*
 * Affiche l'icone des credits.
 * Est appelé dans les fichiers :
 * mosaic > fonction loadMosaic.
 * zoomInteractions > fonctions zoom et unzoom.
*/
Mosaic.prototype.creditsIcon = function()
{
	this.removeCreditsIcon();
	//On construit le div.
	var creditsIcon = "<img id='creditsIcon' src='./img/creditsIcon.png' />";
	//On l'ajoute.
	$('body').append(creditsIcon);
	//On spécifie ses coordonnées.
	$('#creditsIcon').css(
	{
		top: $(window).height() - $('#creditsIcon').height() - 2 * parseInt($('#creditsIcon').css('margin-left')),
		left: $(window).width() - $('#creditsIcon').width() - 2 * parseInt($('#creditsIcon').css('margin-left'))
	});
}

/*
 * Supprime l'icone des credits.
 * Est appelé dans les fichiers :
 * zoomInteractions > fonctions zoom et unzoom.
 * notifications > fonction helpIcon.
*/
Mosaic.prototype.removeCreditsIcon = function()
{
	this.isCreditsIconZooming = false;
	this.isCreditsIconZoomed = false;
	$('#creditsIcon').remove();
}

/*
 * Agrandit l'icone des credits.
 * Est appelé dans le fichier :
 * mosaic > fonction onMouseMove.
*/
Mosaic.prototype.showBigCredits = function()
{
	//Si on a déjà zoomé on quitte.
	if(this.isCreditsIconZoomed || this.isCreditsIconZooming)
	{
		return;
	}
	
	this.isCreditsIconZooming = true;
	
	var _this = this;
	
	$('#creditsIcon').animate(
	{
		width: 100,
		height: 100,
		top: $(window).height() - 100 - 2 * parseInt($('#creditsIcon').css('margin-left')),
		left: $(window).width() - 100 - 2 * parseInt($('#creditsIcon').css('margin-left'))
	}, this.config.timeShowBigCredits, function()
	{
		_this.isCreditsIconZoomed = true;
		_this.isCreditsIconZooming = false;
	});
}

/*
 * Rétrecit l'icone des credits.
 * Est appelé dans le fichier :
 * mosaic > fonction onMouseMove.
*/
Mosaic.prototype.showSmallCredits = function()
{
	//Si on n'a pas zoomé on quitte.
	if(!this.isCreditsIconZoomed || this.isCreditsIconZooming)
	{
		return;
	}
	
	this.isCreditsIconZooming = true;
	
	var _this = this;
	
	var creditsIconWidth = $('#creditsIcon').width();
	
	$('#creditsIcon').animate(
	{
		width: 50,
		height: 50,
		top: $(window).height() - 50 - 2 * parseInt($('#creditsIcon').css('margin-left')),
		left: $(window).width() - 50 - 2 * parseInt($('#creditsIcon').css('margin-left'))
	}, this.config.timeShowBigCredits, function()
	{
		_this.isCreditsIconZoomed = false;
		_this.isCreditsIconZooming = false;
	});
}

/*
 * Affiche les crédits.
*/
Mosaic.prototype.notifyCredits = function(tabCredits)
{
	//Si ils sont déjà affichés on quitte.
    if(this.creditsDisplayed)
    {
        return;
    }
	
    //On enlève les autres notifications.
    this.removeNotifications();
    
    //On indique qu'ils sont affichés.
    this.creditsDisplayed = true;
	
	//Panneau des crédits.
	//On crée les flèches au niveau du container en cas d'overflow du texte.
	var credits = "<div id='notify_credits'><div id='credits_upArrow_mask' class='credits_masks'></div><div id='credits_upArrow' class='credits_arrows'></div><div id='credits_container'></div><div id='credits_downArrow_mask' class='credits_masks'></div><div id='credits_downArrow' class='credits_arrows'></div></div>";
	
	//Pied de page des crédits.
	var credits_footer = "<div id='credits_footer'><div id='credits_footer_BBM'></div><div id='credits_footer_text'>" + this.creditsMetadata.footer_line1 + "<br />" + this.creditsMetadata.footer_line2 + "</div><div id='credits_footer_partners'></div></div>";
	
	$('body').append(credits);
	
	//On récupère les éléments css du div des crédits.
	var notify_credits = $('#notify_credits'), window_width = $(window).width(), window_height = $(window).height(), notify_margin = parseInt(notify_credits.css('margin-left')), notify_padding = parseInt(notify_credits.css('padding-left'));

	//On ajoute le pied de page aux crédits.
	notify_credits.append(credits_footer);
	
	//Elements html contenant les crédits.
	var credits_elements = "<div id='credits_content_left' class='credits_content'><div id='credits_title' class='credits_text'>" + this.creditsMetadata.title + "<br /></div><div id='credits_subtitle' class='credits_text'>" + this.creditsMetadata.subtitle + "<br /><br /></div>";
	
	for(var i = 0 ; i < this.tabCredits.length ; i++)
	{
		credits_elements += "<div class='credits_film credits_text'>" + this.tabCredits[i].film + "</div><div class='credits_body credits_text'>";
		if(this.tabCredits[i].realisation)
		{
			credits_elements += this.creditsMetadata.realisation + " : " + this.tabCredits[i].realisation + "<br />";
		}
		if(this.tabCredits[i].company)
		{
			credits_elements += this.creditsMetadata.company + " : " + this.tabCredits[i].company + "<br />";
		}
		if(this.tabCredits[i].production)
		{
			credits_elements += this.creditsMetadata.production + " : " + this.tabCredits[i].production + "<br />";
		}
		if(this.tabCredits[i].choregraphy)
		{
			credits_elements += this.creditsMetadata.choregraphy + " : " + this.tabCredits[i].choregraphy + "<br />";
		}
		if(this.tabCredits[i].music)
		{
			credits_elements += this.creditsMetadata.music + " : " + this.tabCredits[i].music + "<br />";
		}
		
		credits_elements += "<br /></div>"
		
		if(i == Math.floor(this.tabCredits.length / 3))
		{
			credits_elements += "</div><div id='credits_content_center' class='credits_content'>"
		}
		else if(i == Math.floor(this.tabCredits.length * 2 / 3))
		{
			credits_elements += "</div><div id='credits_content_right' class='credits_content'>"
		}
	}
	
	credits_elements += "</div>";
	
	$('#credits_container').append(credits_elements);
	
	//On le positionne
	notify_credits.css(
    {
        left: "0px",
        top: "0px",
        width: window_width - notify_margin * 2 - notify_padding * 2,
        height: window_height - notify_margin * 2 - notify_padding * 2,
        'z-index': 1000
	});
	
	//$('#credits_content').css('background-color', '#0000FF');
	
	this.column_gap = 30;
	// this.column_width = (notify_credits.width() - notify_margin * 2 - notify_padding * 2) / 3 - this.column_gap * 3;
	this.column_width = 150;//Math.ceil((notify_credits.width() - this.column_gap) / 3 - notify_margin * 2);
	//console.log(Math.ceil((notify_credits.width() - this.column_gap) / 3 - notify_margin * 2));
	//Dimensions des flèches.
	var arrowWidth = 50, arrowHeight = 50;
	//Dimensions du footer.
	var footer_height = 100;
	
	//On spécifie les colonnes.
	$('#credits_container').css(
	{
		position: 'absolute',
		/*,'-moz-column-width': this.column_width,
		'-webkit-column-width': this.column_width,
		'-moz-column-gap': this.column_gap,
		'-webkit-column-gap': this.column_gap,
		'-moz-column-rule': '1px solid #ddccb5',
		'-webkit-column-rule': '1px solid #ddccb5'*/
    });
	
	$('.credits_content').css(
	{
		position: 'absolute',
		width: Math.floor(notify_credits.width() / 3)
	});
	$('#credits_content_left').css(
	{
		top: 0,//+$('#credits_title').height() + $('#credits_subtitle').height(),
		left: 0
	});
	$('#credits_content_center').css(
	{
		top: 0,
		left: Math.floor(notify_credits.width() / 3)
	});
	$('#credits_content_right').css(
	{
		top: 0,
		left: Math.floor(notify_credits.width() * 2 / 3)
	});
	
	//On récupère la hauteur de la colonne la plus longue.
	var credits_content_max_height = Math.max(Math.max($('#credits_content_left').height(), $('#credits_content_center').height()), $('#credits_content_right').height());
	
	//CSS du pied de page.
	$('#credits_footer').css(
	{
		position: 'absolute',
		'background-color': '#FFF',
		width: +notify_credits.width() + notify_margin + notify_padding,
		height: footer_height,
		top: +notify_credits.height() - 100 + notify_margin + notify_padding,
		left: '0px'
	});
	$('#credits_footer_BBM').css(
	{
		position: 'absolute',
		'background-image': 'url(./img/creditsBBM.png)',
		'background-repeat': 'no-repeat',
		'background-size': '300px 40px',
		width: '300px',
		height: '40px',
		top: '0px',
		left: '0px'
	});
	$('#credits_footer_partners').css(
	{
		position: 'absolute',
		'background-image': 'url(./img/creditsPartners.png)',
		'background-repeat': 'no-repeat',
		width: '386px',
		height: '41px',
		top: $('#credits_footer').height() - 41,
		left: +notify_credits.width() - 386 + notify_margin + notify_padding
	});
	$('#credits_footer_text').css(
	{
		position: 'absolute',
		width: notify_credits.width() - $('#credits_footer_partners').width(),
		top: '40px',
		left: '0px',
	});
	
	//On ajoute les flèches à l'interface, bien qu'elles soient invisibles s'il n'y a pas d'overflow du texte.
	$('#credits_upArrow').css(
	{
		top: 0,
		left: notify_credits.width() / 2 - arrowWidth / 2
	});
	$('#credits_downArrow').css(
	{
		top: $('#credits_footer').position().top - arrowHeight,
		left: notify_credits.width() / 2 - arrowWidth / 2
	});
	
	//On masque ce qu'il y a derrière les flèches.
	$('.credits_masks').css(
	{
		position: 'absolute',
		left: 0,
		'background-color': '#D1D2D4',
		width: notify_credits.width(),
		height: arrowHeight,
		opacity: 0,
		'z-index': 100
	});
	$('#credits_upArrow_mask').css(
	{
		top: 0
	});
	$('#credits_downArrow_mask').css(
	{
		top: $('#credits_footer').position().top - arrowHeight
	});
	
	//Nombre de pages de crédits.
	this.creditsPageLength = Math.ceil(credits_content_max_height / (notify_credits.height() - footer_height - 2 * arrowHeight));
	
	//On suppose qu'il n'y a pas d'overflow du texte des crédits.
	this.isCreditsTextOverflow = false;
	
	//Si la taille totale des crédits excède celle de la hauteur du panneau des crédits x 3, alors le panneau sera en plusieurs parties.
	if(credits_content_max_height > (notify_credits.height() - footer_height - 2 * arrowHeight))
	{
		//Si on est arrivé là, on a constaté un overflow du texte des crédits.
		this.isCreditsTextOverflow = true;
		
		//Si on est sur la première page des crédits.
		if(this.creditsPageNumber == 0)
		{
			//On ne laisse pas la place du haut pour la flèche haut puisqu'on est sur la première page.
			$('#credits_container').css(
			{
				//top: 0,
				height: notify_credits.height() - footer_height - arrowHeight
			});
			$('#credits_downArrow, #credits_downArrow_mask').css('opacity', '1');
		}
		//Sinon si on est sur la dernière page des crédits.
		else if(this.creditsPageNumber + 1 == creditsPageLength)
		{
			$('#credits_downArrow, #credits_downArrow_mask').css('opacity', '0');
		}
		//Sinon on laisse la place pour revenir en arrière ou en avant.
		else
		{
			$('#credits_container').css(
			{
				//top: arrowHeight,
				height: notify_credits.height() - footer_height - arrowHeight * 2,
			});
		}
	}
}

/*
 * Supprime les crédits.
*/
Mosaic.prototype.removeCredits = function()
{
	//On indique qu'ils ne sont plus affichés.
    this.creditsDisplayed = false;
	this.creditsPageNumber = 0;
	$('#notify_credits').remove();
}