Front IDILL :
authorbastiena
Wed, 30 May 2012 10:21:36 +0200
changeset 35 4267d6d27a7d
parent 34 909dfe0c1dca
child 36 25e71ada2a6d
Front IDILL : Config file added dor the Front Random play at the beginning (when no user is detected) Pointers added Curves added (search and filter modes) Mosaic completion added (depletion to come later) State of the Front : just before the communication module creation
front_idill/src/config.json
front_idill/src/img/pointer.png
front_idill/src/img/pointer2.png
front_idill/src/index.html
front_idill/src/mosaic/css/mosaic.less
front_idill/src/mosaic/js/mosaic.js
front_idill/src/player/metadataplayer/LdtPlayer-core.js
front_idill/src/player/metadataplayer/Timeline.js
front_idill/src/search/css/curve.css
front_idill/src/search/css/searchCanvas.css
front_idill/src/search/js/curve.js
front_idill/src/search/js/searchCanvas.js
front_idill/src/snapshots-little/50 shots.png
front_idill/src/snapshots-little/alger.png
front_idill/src/snapshots-little/animalz.png
front_idill/src/snapshots-little/aside.png
front_idill/src/snapshots-little/deep end dance.png
front_idill/src/snapshots-little/encontro cotidianos.png
front_idill/src/snapshots-little/exotica.png
front_idill/src/snapshots-little/fenella.png
front_idill/src/snapshots-little/flying lesson.png
front_idill/src/snapshots-little/i am my mother.png
front_idill/src/snapshots-little/instrument.png
front_idill/src/snapshots-little/joudance 2 in asakusa_stage1.png
front_idill/src/snapshots-little/mue.png
front_idill/src/snapshots-little/new under the sun.png
front_idill/src/snapshots-little/nid de lune.png
front_idill/src/snapshots-little/patria.png
front_idill/src/snapshots-little/respire.png
front_idill/src/snapshots-little/sliced.png
front_idill/src/snapshots-little/spin.png
front_idill/src/snapshots-little/stronger.png
front_idill/src/snapshots-little/tank man tango a tianmen memorial.png
front_idill/src/snapshots-little/the rat.png
front_idill/src/snapshots-little/vrtti.png
front_idill/src/snapshots-little/you are you.png
front_idill/src/snapshots/50 shots.png
front_idill/src/snapshots/alger.png
front_idill/src/snapshots/animalz.png
front_idill/src/snapshots/aside.png
front_idill/src/snapshots/deep end dance.png
front_idill/src/snapshots/encontro cotidianos.png
front_idill/src/snapshots/exotica.png
front_idill/src/snapshots/fenella.png
front_idill/src/snapshots/flying lesson.png
front_idill/src/snapshots/i am my mother.png
front_idill/src/snapshots/instrument.png
front_idill/src/snapshots/joudance 2 in asakusa_stage1.png
front_idill/src/snapshots/mue.png
front_idill/src/snapshots/new under the sun.png
front_idill/src/snapshots/nid de lune.png
front_idill/src/snapshots/patria.png
front_idill/src/snapshots/respire.png
front_idill/src/snapshots/sliced.png
front_idill/src/snapshots/stronger.png
front_idill/src/snapshots/tank man tango a tianmen memorial.png
front_idill/src/snapshots/the rat.png
front_idill/src/snapshots/vrtti.png
front_idill/src/snapshots/you are you.png
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/front_idill/src/config.json	Wed May 30 10:21:36 2012 +0200
@@ -0,0 +1,19 @@
+{
+	"local":"false",
+	"length":"5",
+	"imagesToShow":"20",
+	"totalImages":"23",
+	"timePrezoom":"500",
+	"timePreUnzoom":"200",
+	"timeZoom":"500",
+	"timeUnzoom":"400",
+	"timeNeighbourGlowing":"1000",
+	"timeNeighbourUnglowing":"1000",
+	"timeMovingToNeighbour":"1000",
+	"timeSearchFade":"2000",
+	"timeNotifyFade":"2000",
+	"timeFilterFade":"2000",
+	"zoomPercentage":"0.80",
+	"prezoomPercentage":"0.25",
+	"zoomedMargin":"42"
+}
\ No newline at end of file
Binary file front_idill/src/img/pointer.png has changed
Binary file front_idill/src/img/pointer2.png has changed
--- a/front_idill/src/index.html	Thu May 24 10:35:27 2012 +0200
+++ b/front_idill/src/index.html	Wed May 30 10:21:36 2012 +0200
@@ -30,6 +30,7 @@
         <script type="text/javascript" src="../lib/less-1.3.0.min.js"></script>
         <script type="text/javascript" src="../lib/underscore-min.js"></script>
         <script type="text/javascript" src="../lib/jquery.min.js"></script>
+        <script type="text/javascript" src="../lib/jquery-ui.min.js"></script>
         <script type="text/javascript" src="./mosaic/js/mosaic.js"></script>
         <script type="text/javascript" src="./mosaic/js/localMosaic.js"></script>
 		<script type="text/javascript" src="./player/metadataplayer/LdtPlayer-core.js"></script>
@@ -50,18 +51,38 @@
         <!-- Scripts principaux. -->
         <script type="text/javascript">
             //Longueur de la mosaïques et nombre d'images à afficher (seront importés des paramètres du Middleware).
-            var length = 5, imagesToShow = 20, totalImages = 23;
+			var default_parameters = new Object();
+			default_parameters['local'] = true;
+			default_parameters['length'] = 5;
+			default_parameters['imagesToShow'] = 20;
+			default_parameters['totalImages'] = 23;
+			default_parameters['timePrezoom'] = 500;
+			default_parameters['timePreUnzoom'] = 200;
+			default_parameters['timeZoom'] = 500;
+			default_parameters['timeUnzoom'] = 400;
+			default_parameters['timeNeighbourGlowing'] = 1000;
+			default_parameters['timeNeighbourUnglowing'] = 1000;
+			default_parameters['timeMovingToNeighbour'] = 1000;
+			default_parameters['timeSearchFade'] = 2000;
+			default_parameters['timeNotifyFade'] = 2000;
+			default_parameters['timeFilterFade'] = 2000;
+			default_parameters['timeFilling'] = 500;
+			default_parameters['zoomPercentage'] = 0.80;
+			default_parameters['prezoomPercentage'] = 0.25;
+			default_parameters['zoomedMargin'] = 42;
+			
+            /*var length = 5, imagesToShow = 20, totalImages = 23;
             //Temps de chargement du prezoom en ms (seront importés des paramètres du Middleware).
             var timePrezoom = 500, timePreUnzoom = 200, timeZoom = 500, timeUnzoom = 400;
             var timeNeighbourGlowing = 1000, timeNeighbourUnglowing = 1000, timeMovingToNeighbour = 1000;
 			var timeSearchFade = 2000;
 			var timeNotifyFade = 2000;
             var zoomPercentage = 0.80, prezoomPercentage = 0.25;
-            var zoomedMargin = 42;
+            var zoomedMargin = 42;*/
             //On instancie la mosaïque.
-            var mos = new mosaic(length, imagesToShow, totalImages, zoomPercentage, prezoomPercentage, zoomedMargin);
+            
             //On spécifie les attributs de temps.
-            mos.zoomTime = timeZoom;
+            /*mos.zoomTime = timeZoom;
             mos.unzoomTime = timeUnzoom;
             mos.preZoomTime = timePrezoom;
             mos.preUnzoomTime = timePreUnzoom;
@@ -69,7 +90,7 @@
             mos.timeNeighbourUnglowing = timeNeighbourUnglowing;
             mos.timeMovingToNeighbour = timeMovingToNeighbour;
 			mos.timeSearchFade = timeSearchFade;
-			mos.timeNotifyFade = timeNotifyFade;
+			mos.timeNotifyFade = timeNotifyFade;*/
             //On instancie une mosaïque locale pour le zoom total (pas encore implémenté).
             //var lMos = new localMosaic(length, imagesToShow, zoomedMargin);
             //mos.localMos = lMos;
@@ -80,17 +101,11 @@
                 imgs[i] = i + '.jpg';
 			}*/
             
-            //Si on a changé les dimensions de la fenêtre, on raffraichit la mosaïque.
-            $(window).resize(function ()
-            {
-                mos.loadMosaic();
-            });
-            
             //Si la page a chargé, on raffraichit la mosaïque.
             $(document).ready(function ()
             {
-                mos.loadMosaic();
-				//mos.newSearch();
+				var mos = new mosaic('./config.json', default_parameters);
+                //mos.loadMosaic();
                 
                 $('.snapshotDivs').mouseenter(function ()
                 {
@@ -99,56 +114,7 @@
                 });
                 $('body').keypress(function (event)
                 {
-					//Sinon si on a appuyé sur 's' ou 'S'.
-					if(event.which == 103 || event.which == 71)
-					{
-						//Si on est déjà en recherche par courbes.
-						if(mos.currentMode == "SEARCH" || mos.currentMode == "FILTER")
-						{
-							//On quitte cette recherche.
-							mos.leaveSearch();
-							//Si on était en mode recherche.
-							if(mos.currentMode == "SEARCH")
-							{
-								//On revient dans la vidéo.
-								mos.currentMode = "VIDEO";
-							}
-							else
-							{
-								//Sinon c'est qu'on était dans la mosaïque.
-								mos.currentMode = "MOSAIC";
-							}
-						}
-						else
-						{
-							//Si on est en plein écran.
-							if(mos.fullscreen)
-							{
-								//On entre en mode recherche.
-								mos.currentMode = "SEARCH";
-							}
-							//Sinon.
-							else
-							{
-								//On entre en mode filtrage.
-								mos.currentMode = "FILTER";
-							}
-							
-							mos.startSearch();
-						}
-					}
-					//Si c'est a ou A.
-					else if(event.which == 65 || event.which == 97)
-					{
-						if(!mos.helpDisplayed)
-						{
-							mos.notifyHelp();
-						}
-						else
-						{
-							mos.removeHelp();
-						}
-					}
+					mos.manageControlEvents(event);
                 });
             });
         </script>
--- a/front_idill/src/mosaic/css/mosaic.less	Thu May 24 10:35:27 2012 +0200
+++ b/front_idill/src/mosaic/css/mosaic.less	Wed May 30 10:21:36 2012 +0200
@@ -36,6 +36,12 @@
 @notify-help-margin: 15px;
 @notify-help-search-background-image-path: url("../../pictos/help/recherche.png");
 @notify-help-controls-background-image-path: url("../../pictos/help/controles.png");
+@mainPointer-background-image-path: url("../../img/pointer.png");
+
+html
+{
+	//cursor: none;
+}
 
 body
 {
@@ -152,6 +158,27 @@
 	z-index: 400;
 }
 
+.notifications_inSearch
+{
+	position: relative;
+	float: left;
+	width: 100px;
+	height: 100px;
+	background-repeat: no-repeat;
+	background-position: 0px 0px;
+	background-size: 100px 100px;
+	opacity: 0;
+	margin: 15px;
+	z-index: 400;
+}
+
+.notifications_inSearch_container
+{
+	position: absolute;
+	background-color: #fff;
+	background: transparent;
+}
+
 #notify_selection
 {
 	background-image: @notify-selection-background-image-path;
@@ -269,4 +296,23 @@
 .notify_imgs_small
 {
 	margin: 4px;
+}
+
+.filterHiders
+{
+	position: absolute;
+	background-color: #fff;
+	background: transparent;
+}
+
+#mainPointer
+{
+	position: absolute;
+	width: 74px;
+	height: 74px;
+	background-image: @mainPointer-background-image-path;
+	background-position: 0px 0px;
+	background-repeat: no-repeat;
+	z-index: 500;
+	display: none;
 }
\ No newline at end of file
--- a/front_idill/src/mosaic/js/mosaic.js	Thu May 24 10:35:27 2012 +0200
+++ b/front_idill/src/mosaic/js/mosaic.js	Wed May 30 10:21:36 2012 +0200
@@ -22,96 +22,75 @@
  * Elle contient sa longueur, le nombre d'images total, une liste d'urls pour les vidéos, leurs snapshots principaux et leur position.
  * Contient également les dimensions en px de la mosaïque.
  */
-function mosaic(len, imgToShow, imgTotal, zoomPercentage, prezoomPercentage, zoomedMargin)
+function mosaic(config, default_conf)
 {
-    //S'il s'agit d'un rectangle.
-    if(imgToShow % len == 0)
-    {
-        //Longueur horizontale.
-        this.length = len;
-        //Nombre d'images dans la mosaïque.
-        this.imagesToShow = imgToShow;
-		this.imagesTotal = imgTotal;
-        //Tableaux des urls des vidéos, des snapshots et de leur position dans la mosaïque.
-        this.videos = [];
-        this.urls = [];
-        this.imgs = [];
-        this.ids = [];
-		//On remplit le tableau d'ids.
-		for(var i = 0 ; i < this.imagesTotal ; i++)
-			this.ids.push(i);
-		//On les mélange.
-		this.ids.sort(function()
-		{
-			return 0.5 - Math.random()
-		});
-		
-		console.log(this.ids);
-		
-        //Dimensions de la mosaïque en pixels.
-        this.width;
-        this.height;
-        //Dimensions d'un snapshot en pixels.
-        this.snapshotWidth;
-        this.snapshotHeight;
-        //Espacement entre les snapshots en pixels.
-        this.marginWidth;
-        
-        //Temps d'intéractions/d'animations.
-        this.preZoomTime;
-        this.preUnzoomTime;
-        this.zoomTime;
-        this.unzoomTime;
-        this.timeNeighbourGlowing;
-        this.timeNeighbourUnglowing;
-        this.timeMovingToNeighbour;
-		this.timeSearchFade;
-		this.timeNotifyFade;
-        
-        //Booléens permettant ou non certaines intéractions selon le contexte.
-        this.zoomed;
-        this.fullscreen;
-        this.canMoveToNeighbour;
-		this.helpDisplayed;
-        
-        //Mode actuel.
-        this.currentMode;
-        //Snapshot sur lequel on a zoomé.
-        this.previousZoomedSN;
-        //Son ID.
-        this.previousId;
-        //Largeur de la marge pour le centrage vertical de la mosaïque.
-        this.MPTop_margin;
-        this.top_margin;
-        //Pourcentage d'agrandissement lors d'un prézoom et d'un zoom.
-        this.prezoomPercentage = prezoomPercentage;
-        this.zoomPercentage = zoomPercentage;
-        //Espacement des snapshots après un zoom.
-        this.zoomedMargin = zoomedMargin;
-        //Mosaïque locale.
-        this.localMos;
-        //Position des voisins lors d'un zoom.
-        this.neighboursIds = [];
-        //ID du snapshot du milieu lors d'un zoom.
-        this.centerId;
-		
-		//Lecteur.
-		this.player;
-		
-		//Coordonnées et dimensions d'un snapshot zoomé.
-		this.snTop = 0;
-		this.snLeft = 0;
-		this.snWidth = 0;
-		this.snHeight = 0;
-		
-		this.searchCanvas;
-		
-		this.loadFromJson('./player/json/videos.json');
-    }
-    else
-    {
-        //Affiche un message d'erreur.
-    }
+	//Chemin du fichier de configuration.
+	this.config_path = config;
+	//Configuration par défaut en cas de valeur erronnée.
+	this.default_config = default_conf;
+	this.config = new Object();
+	//Tableaux des urls des vidéos, des snapshots et de leur position dans la mosaïque.
+	this.videos = [];
+	this.urls = [];
+	this.imgs = [];
+	this.ids = [];
+	this.fillingIds = [];
+	this.currentRandomVideoIdx = 0;
+	
+	//Dimensions de la mosaïque en pixels.
+	this.width;
+	this.height;
+	//Dimensions d'un snapshot en pixels.
+	this.snapshotWidth;
+	this.snapshotHeight;
+	//Espacement entre les snapshots en pixels.
+	this.marginWidth;
+	
+	//Booléens permettant ou non certaines intéractions selon le contexte.
+	this.zoomed;
+	this.fullscreen;
+	this.canMoveToNeighbour;
+	this.helpDisplayed;
+	
+	//Type de marqueur recherché dans la mosaïque (en mode filter).
+	this.filterSearchedType = "";
+	
+	//Mode actuel.
+	this.currentMode = "MOSAIC";
+	//Snapshot sur lequel on a zoomé.
+	this.previousZoomedSN;
+	//Son ID.
+	this.previousId;
+	//Largeur de la marge pour le centrage vertical de la mosaïque.
+	this.MPTop_margin;
+	this.top_margin;
+
+	//Mosaïque locale.
+	this.localMos;
+	//Position des voisins lors d'un zoom.
+	this.neighboursIds = [];
+	//ID du snapshot du milieu lors d'un zoom.
+	this.centerId;
+	
+	//Snapshots a afficher.
+	this.snapshotsToShow = 1;
+	
+	//Lecteur.
+	this.player;
+	//Annotations (pour les marqueurs los d'un filtrage).
+	this.annotations = [];
+	
+	//Coordonnées et dimensions d'un snapshot zoomé.
+	this.snTop = 0;
+	this.snLeft = 0;
+	this.snWidth = 0;
+	this.snHeight = 0;
+	
+	this.searchCanvas;
+	//Position actuelle de la vidéo zoomée.
+	this.notifyTopVideo;
+	this.notifyLeftVideo;
+	this.loadParameters(this.config_path);
 }
 
 /*
@@ -120,25 +99,48 @@
  */
 mosaic.prototype.createMosaic = function()
 {
-    this.previousZoomedSN = '';
-    this.previousPrezoomDiv = '';
-    this.fullscreen = false;
-    this.canMoveToNeighbour = false;
-	this.helpDisplayed = false;
-    var str = '';
-    
-    if(this.imgs.length >= this.imagesToShow)
+	console.log('CREATE');
+	this.currentMode = "NO-USER";
+	var initPanel = '<div id="initPanel"></div>';
+	var mp = $('#mainPanel');
+	mp.append(initPanel);
+	$('#initPanel').css(
+	{
+		background: 'transparent',
+		width: mp.width(),
+		height: mp.height(),
+		top: mp.position().top,
+		left: mp.position().left,
+		'margin-top': this.MPTop_margin
+	});
+	
+	var len = this.config['length'], imgs = this.config['imagesToShow'], imgsTotal = this.config['imagesTotal'];
+	
+	//S'il s'agit d'un rectangle.
+    if(imgs % len == 0)
     {
-        for(var i = 0 ; i < this.imagesToShow ; i++)
-        {
-            //On charge les images de petite taille pour ne pas surcharger la mosaïque lors de l'affichage global.
-            str += '<div id="snapshotDiv-' + i + '" class="snapshotDivs"><img id="snapshot-' + i + '" class="snapshots" src="snapshots-little/' + this.imgs[i] + '" /></div>';
-        }
-    }
-    
-	console.log(this.imagesToShow);
-	
-    return str;
+		this.previousZoomedSN = '';
+		this.previousPrezoomDiv = '';
+		this.fullscreen = false;
+		this.canMoveToNeighbour = false;
+		this.helpDisplayed = false;
+		var str = '';
+		
+		if(this.imgs.length >= imgs)
+		{
+			for(var i = 0 ; i < imgs ; i++)
+			{
+				//On charge les images de petite taille pour ne pas surcharger la mosaïque lors de l'affichage global.
+				str += '<div id="snapshotDiv-' + i + '" class="snapshotDivs" style="opacity: 0;"><img id="snapshot-' + i + '" class="snapshots" src="snapshots-little/' + this.imgs[i] + '" /></div>';
+			}
+		}
+		
+		return str;
+	}
+	else
+	{
+		alert("Le nombre d'images a afficher doit être divisible par la longueur de la mosaïque !");
+	}
 }
 
 /*
@@ -146,6 +148,7 @@
  */
 mosaic.prototype.loadMosaic = function()
 {
+	console.log('LOAD');
 	var createMosaic = this.createMosaic();
 	
 	if(createMosaic == '')
@@ -162,11 +165,11 @@
     $('#mainPanel').html(createMosaic);
     //On récupère la taille des bordures.
     this.marginWidth = $('.snapshotDivs').css('margin-bottom');
-    this.marginWidth = parseFloat(mos.marginWidth)*2;
+    this.marginWidth = parseFloat(this.marginWidth)*2;
     //On calcule la taille des divs contenant les snapshots.
     this.width = $('#mainPanel').innerWidth();
     //On ne calculera pas tout de suite la hauteur de la mosaique étant donnée qu'elle est calculée par la suite dynamiquement.
-    this.snapshotWidth = this.width / this.length - this.marginWidth;
+    this.snapshotWidth = this.width / this.config['length'] - this.marginWidth;
     this.snapshotHeight = this.snapshotWidth*9/16;
     $('.snapshotDivs').css('width', this.snapshotWidth).css('height', this.snapshotHeight).css('margin', this.marginWidth/2);
     
@@ -183,17 +186,287 @@
 		//On effectue un prézoom dès qu'on va sur une image.
 		_this.preZoom($(this));
 	});
-	$('body').keypress(function (event)
+	
+	this.addPointers();
+	
+	//Si dans le metadata player _ n'est pas déclaré, on le déclare.
+	if(typeof _ !== "undefined" && typeof IriSP._ === "undefined")
+	{
+		IriSP._ = _;
+	}
+	
+	if(typeof $ !== "undefined" && typeof IriSP.jQuery === "undefined")
+	{
+		IriSP.jQuery = $;
+	}
+	
+	//On charge les marqueurs.
+	var sourceManager = new IriSP.Model.Directory(),
+	globalAnnotations = new IriSP.Model.List(sourceManager),
+	nbFichiers = _this.urls.length,
+	fichiersCharges = 0;
+	
+	for (var i = 0; i < nbFichiers; i++)
+	{
+		console.log('url : ' + _this.urls[i]);
+		var source = sourceManager.remoteSource({url: _this.urls[i], serializer: IriSP.serializers.ldt});
+		source.onLoad(function()
+		{
+			globalAnnotations.addElements(source.getAnnotations());
+			fichiersCharges++;
+			if (fichiersCharges == nbFichiers)
+			{
+				// instructions à exécuter quand tout est chargé
+				_this.annotations = globalAnnotations;
+				console.log('annotations loaded');
+				_this.init();
+			}
+		});
+	}
+}
+
+/*
+ * Charge les paramètres du Front. Local (true/false) est le mode de chargement des données.
+*/
+mosaic.prototype.loadParameters = function(file_path)
+{
+	var _this = this;
+	
+	var supposedToBeInt = ['length', 'imagesToShow', 'totalImages', 'timePrezoom', 'timePreUnzoom', 'timeZoom', 'timeUnzoom', 'timeNeighbourGlowing', 'timeNeighbourUnglowing', 'timeMovingToNeighbour', 'timeSearchFade', 'timeNotifyFade', 'timeFilterFade', 'timeFilling', 'zoomedMargin'];
+	var supposedToBeFloat = ['zoomPercentage', 'prezoomPercentage'];
+	
+	$.getJSON(file_path, function(data)
 	{
-		//Si on a appuié sur la touche 'q' ou 'Q';
-		if(event.which == 113 || event.which == 81)
+		for(key in data)
 		{
-		   _this.unzoom();
+			var val = data[key];
+			
+			if(_.include(supposedToBeInt, key))
+			{
+				var intVal = parseInt(val);
+				if(isNaN(intVal))
+				{
+					console.log(_this.default_config);
+					_this.config[key] = _this.default_config[key];
+					console.log("param[" + key + "] : Valeur " + val + " incorrecte (non Int). Valeur par défaut " + _this.default_config[key] + " chargée à la place.");
+				}
+				else
+				{
+					_this.config[key] = intVal;
+				}
+			}
+			else if(_.include(supposedToBeFloat, key))
+			{
+				var floatVal = parseFloat(val);
+				if(isNaN(floatVal))
+				{
+					_this.config[key] = _this.default_config[key];
+					console.log("param[" + key + "] : Valeur " + val + " incorrecte (non Float). Valeur par défaut " + _this.default_config[key] + " chargée à la place.");
+				}
+				else
+				{
+					_this.config[key] = floatVal;
+				}
+			}
+			else
+			{
+				_this.config[key] = val;
+			}
+		}
+		
+		//On remplit le tableau d'ids.
+		for(var i = 0 ; i < _this.config['totalImages'] ; i++)
+			_this.ids.push(i);
+		//On les mélange.
+		_this.ids.sort(function()
+		{
+			return 0.5 - Math.random()
+		});
+		
+		//On remplit le tableau d'ids destiné à afficher les snapshots au fur et à mesure.
+		for(var i = 0 ; i < _this.config['imagesToShow'] ; i++)
+			_this.fillingIds.push(i);
+		//On les mélange.
+		_this.fillingIds.sort(function()
+		{
+			return 0.5 - Math.random()
+		});
+		
+		if(_this.config['local'] == 'true')
+		{
+			console.log("Loading local metadata.");
+			_this.loadFromJson('./player/json/local_videos.json');
+		}
+		else
+		{
+			console.log("Loading online metadata.");
+			_this.loadFromJson('./player/json/online_videos.json');
 		}
 	});
 }
 
 /*
+ * Phase principale (utilisateur non détecté). Une vidéo se lance aléatoirement.
+ * L'interface est identique à celle du zoom, mais sans interaction possible avec les voisins, ni les controles timeline.
+ * Lors de la fin d'une lecture, on dézoome vers la mosaïque, puis on rezoome vers un autre snapshot (aléatoire).
+*/
+mosaic.prototype.init = function()
+{
+	var _this = this;
+	
+	if(this.currentRandomVideoIdx > this.config['imagesToShow'])
+	{
+		this.currentRandomVideoIdx = 0;
+	}
+	
+	this.previousZoomedSN = $('#snapshotDiv-' + this.fillingIds[this.currentRandomVideoIdx]);
+	this.previousId = $('img', this.previousZoomedSN).attr('id');
+	
+	console.log('ids', this.fillingIds[this.currentRandomVideoIdx]);
+	
+	this.previousZoomedSN.fadeTo(this.config['timePrezoom'], 1, function()
+	{
+		_this.zoom();
+		_this.currentRandomVideoIdx++;
+	});
+}
+
+/*
+ * Remplissage de la mosaïque en fonction du nombre d'images à afficher.
+*/
+mosaic.prototype.showNImages = function(n)
+{
+	if(n > 1)
+	{
+		this.currentMode = "INCOMING-" + n;
+		this.unzoom();
+	}
+	
+	for(var i = 0 ; i < n ; i++)
+	{
+		if($('#snapshotDiv-' + i).css('opacity') < 1)
+		{
+			$('#snapshotDiv-' + i).fadeTo(this.config['timeFilling'], 1);
+		}
+	}
+}
+
+/*
+ * Affiche les pointeurs.
+*/
+mosaic.prototype.addPointers = function()
+{
+	var _this = this;
+	
+	var mainPointer = '<div id="mainPointer" class="pointers"></div>';
+	$('body').append(mainPointer);
+	$('body').mousemove(function(evt)
+	{
+		$('#mainPointer').css(
+		{
+			top: evt.pageY - $('#mainPointer').height()/2,
+			left: evt.pageX - $('#mainPointer').width()/2
+		});
+	});
+}
+
+/*
+ * Gère les événements de contrôle dans la mosaïque.
+*/
+mosaic.prototype.manageControlEvents = function(event)
+{
+	console.log('manage');
+	//Sinon si on a appuyé sur 'g' ou 'G'.
+	if(event.which == 103 || event.which == 71)
+	{
+		//Si on est déjà en recherche par courbes.
+		if(this.currentMode == "SEARCH" || this.currentMode == "FILTER")
+		{
+			//On quitte cette recherche.
+			this.leaveSearch();
+			//Si on était en mode recherche.
+			if(this.currentMode == "SEARCH")
+			{
+				//On revient dans la vidéo.
+				this.currentMode = "VIDEO";
+			}
+			else
+			{
+				//Sinon c'est qu'on était dans la mosaïque.
+				this.currentMode = "MOSAIC";
+			}
+		}
+		else
+		{
+			//Si on est en plein écran.
+			if(this.fullscreen)
+			{
+				//On entre en mode recherche.
+				this.currentMode = "SEARCH";
+			}
+			//Sinon.
+			else
+			{
+				//On entre en mode filtrage.
+				this.currentMode = "FILTER";
+			}
+			
+			this.startSearch();
+		}
+	}
+	//Si c'est a ou A.
+	else if(event.which == 65 || event.which == 97)
+	{
+		if(!this.helpDisplayed)
+		{
+			this.notifyHelp();
+		}
+		else
+		{
+			this.removeHelp();
+		}
+	}
+	//Si c'est v ou V.
+	else if(event.which == 86 || event.which == 118)
+	{
+		this.notifySearchMarkers('run;jump;fall');
+	}
+	//Si c'est b ou B.
+	else if(event.which == 66 || event.which == 98)
+	{
+		this.removeSearchMarkers();
+	}
+	//Si c'est k ou K.
+	else if(event.which == 75 || event.which == 107)
+	{
+		this.searchFilter('circle');
+	}
+	//Si c'est l ou L.
+	else if(event.which == 76 || event.which == 108)
+	{
+		this.removeFilter();
+	}
+	//Si on a appuié sur la touche 'q' ou 'Q';
+	else if(event.which == 113 || event.which == 81)
+	{
+		this.unzoom();
+	}
+	else if(event.which == 111 || event.which == 79)
+	{
+		if(this.snapshotsToShow > this.imagesToShow)
+		{
+			this.snapshotsToShow = this.imagesToShow;
+		}
+		else
+		{
+			this.snapshotsToShow += 5;
+		}
+		
+		this.showNImages(this.snapshotsToShow);
+	}
+}
+
+/*
  * Zoom sur la position d'une image, 1ère partie. Durant le laps de temps de time ms, l'utilisateur a le choix de zoomer sur une autre image.
  * Après ce laps de temps, l'image zoom complétement et il n'est plus possible de sélectionner une autre image par pointage.
  */
@@ -208,15 +481,15 @@
 	this.removeSelectionSearchMosaicFull();
 	
     //Mosaïque.
-    var mosaic = this;
+    var _this = this;
     //Dimensions de la mosaïque.
     var h = this.height, w = this.width;
     //Longueur en images, nombre d'images et taille de bordure de la mosaïque.
-    var len = this.length, imgs = this.imagesToShow, margin = this.marginWidth;
+    var len = this.config['length'], imgs = this.config['imagesToShow'], margin = this.marginWidth;
     //Dimensions et position d'un snapshot dans la mosaïque.
     var snHeight = this.snapshotHeight, snWidth = this.snapshotWidth;
     var sTop = snapshot.position().top, sLeft = snapshot.position().left;
-    var prezoomPercentage = this.prezoomPercentage;
+    var prezoomPercentage = this.config['prezoomPercentage'];
     
     //ID de l'image actuelle.
     var currentId = $('img', snapshot).attr('id');
@@ -297,16 +570,16 @@
             height: finalDivHeight - margin*2,
             top: finalDivTop + margin,
             left: finalDivLeft + margin
-        }, this.preZoomTime);
+        }, _this.config['timePrezoom']);
         $('#prezoomContainer-' + currentId).animate(
         {
             width: finalDivWidth + margin*2,
             height: finalDivHeight - margin,
             top: finalDivTop + margin,
             left: finalDivLeft
-        }, this.preZoomTime, function()
+        }, _this.config['timePrezoom'], function()
 		{
-			mosaic.notifyPointMosaicPrezoom();
+			_this.notifyPointMosaicPrezoom();
 		});
     });
     
@@ -315,7 +588,7 @@
     {
         if(this.previousZoomedSN != '')
 		{
-            mosaic.zoom();
+            _this.zoom();
 		}
     });
 }
@@ -346,14 +619,14 @@
         height: this.snapshotHeight,
         top: this.previousZoomedSN.position().top,
         left: this.previousZoomedSN.position().left
-    }, this.preUnzoomTime);
+    }, this.config['preUnzoomTime']);
     $('#prezoomContainer-' + id).animate(
     {
         width: this.snapshotWidth + margin,
         height: this.snapshotHeight + margin,
         top: this.previousZoomedSN.position().top,
         left: this.previousZoomedSN.position().left
-    }, this.preUnzoomTime, function(){ $(this).remove(); this.zoomed = false; });
+    }, this.config['preUnzoomTime'], function(){ $(this).remove(); this.zoomed = false; });
 }
 
 
@@ -362,10 +635,10 @@
  */
 mosaic.prototype.zoom = function()
 {
-    var mos = this;
+    var _this = this;
     
     //Si la mosaïque est en pleine écran, pas la peine de zoomer.
-    if(this.fullscreen)
+    if(this.currentMode == "VIDEO" || this.currentMode == "SEARCH")
 	{
         return;
 	}
@@ -373,18 +646,19 @@
 	this.removePointMosaicPrezoom();
     
     //On prend les attributs nécessaires au calculs.
-    var margin = this.marginWidth, len = this.length, imgs = this.imagesToShow;
+    var margin = this.marginWidth, len = this.config['length'], imgs = this.config['imagesToShow'], zoomedMargin = this.config['zoomedMargin'];
+	var zoomPercentage = this.config['zoomPercentage'];
     var initMPWidth = this.previousZoomedSN.width() * len + margin*len, initMPHeight = this.previousZoomedSN.height() * (imgs / len) + margin*(imgs / len);
-    var newMPWidth = initMPWidth * len + this.zoomedMargin * (len), newMPHeight = initMPHeight * (imgs / len) + this.zoomedMargin * ((imgs / len));
-    var newPreMPWidth = initMPWidth * len * this.zoomPercentage + this.zoomedMargin * (len), newPreMPHeight = initMPHeight * (imgs / len) * this.zoomPercentage + this.zoomedMargin * ((imgs / len));
+    var newMPWidth = initMPWidth * len + zoomedMargin * (len), newMPHeight = initMPHeight * (imgs / len) + zoomedMargin * ((imgs / len));
+    var newPreMPWidth = initMPWidth * len * zoomPercentage + zoomedMargin * (len), newPreMPHeight = initMPHeight * (imgs / len) * zoomPercentage + zoomedMargin * ((imgs / len));
     
     //Dimensions et coordonnées initiales du div sur lequel on zoom.
     var initialDivWidth = this.previousZoomedSN.width(), initialDivHeight = this.previousZoomedSN.height();
     var initialDivTop = this.previousZoomedSN.position().top, initialDivLeft = this.previousZoomedSN.position().left;
     //Dimensions et coordonnées finales du div.
-    var finalDivWidth = initialDivWidth * (this.zoomPercentage+1), finalDivHeight = initialDivHeight * (this.zoomPercentage+1);
-    var newZoomTop = -this.previousZoomedSN.position().top*(newPreMPHeight/initMPHeight) - this.zoomedMargin/2 + (initMPHeight - initMPHeight * this.zoomPercentage)/2, newZoomLeft = -this.previousZoomedSN.position().left*(newPreMPWidth/initMPWidth) - this.zoomedMargin/2 + (initMPWidth - initMPWidth * this.zoomPercentage)/2;
-    var newSnWidth = initMPWidth * this.zoomPercentage, newSnHeight = initMPHeight * this.zoomPercentage;
+    var finalDivWidth = initialDivWidth * (zoomPercentage+1), finalDivHeight = initialDivHeight * (zoomPercentage+1);
+    var newZoomTop = -this.previousZoomedSN.position().top*(newPreMPHeight/initMPHeight) - zoomedMargin/2 + (initMPHeight - initMPHeight * zoomPercentage)/2, newZoomLeft = -this.previousZoomedSN.position().left*(newPreMPWidth/initMPWidth) - zoomedMargin/2 + (initMPWidth - initMPWidth * zoomPercentage)/2;
+    var newSnWidth = initMPWidth * zoomPercentage, newSnHeight = initMPHeight * zoomPercentage;
     
     this.preUnzoom(this);
     /*SINGULARITE*/
@@ -397,22 +671,31 @@
     
     //On récupère son ID.
     var tab, zoomedImgId;
-    tab = mos.previousId.split('-');
+    tab = _this.previousId.split('-');
     zoomedImgId = tab[1];
-
-    //Les snapshots baissent alors en opacité, donnant l'impression qu'ils sont grisés.
-    $('.snapshotDivs').animate(
-    {
-        width: newSnWidth,
-        height: newSnHeight,
-        margin: this.zoomedMargin/2 + 'px',
-        opacity: '0.4'
-    }, this.zoomTime);
-    //Le snapshot du milieu revient à une opacité optimale, ce qui attire l'attention de l'utilisateur.
-    $(this.previousZoomedSN).animate(
-    {
-        opacity: '1'
-    }, this.zoomTime);
+	
+	//On donne les dimensions des snapshots.
+	$('.snapshotDivs').animate(
+	{
+		width: newSnWidth,
+		height: newSnHeight,
+		margin: zoomedMargin/2 + 'px',
+	}, this.config['zoomTime']);
+	
+	if(this.currentMode != 'NO-USER')
+	{
+		//Les snapshots baissent alors en opacité, donnant l'impression qu'ils sont grisés.
+		$('.snapshotDivs').animate(
+		{
+			opacity: '0.4'
+		}, this.config['zoomTime']);
+		//Le snapshot du milieu revient à une opacité optimale, ce qui attire l'attention de l'utilisateur.
+		$(this.previousZoomedSN).animate(
+		{
+			opacity: '1'
+		}, this.config['zoomTime']);
+	}
+	
     //On zoome sur la mosaïque.
     $('#mainPanel').animate(
     {
@@ -420,22 +703,24 @@
         height: newPreMPHeight,
         top: newZoomTop,
         left: newZoomLeft
-    }, this.zoomTime, function()
+    }, this.config['zoomTime'], function()
     {
         //On charge les interactions avec les voisins.
-        mos.centerId = zoomedImgId;
-        mos.listenToNeighbours();
-        mos.currentMode = 'VIDEO';
+        _this.centerId = zoomedImgId;
+		
+		if(_this.currentMode != "NO-USER")
+		{
+			_this.currentMode = 'VIDEO';
+			_this.listenToNeighbours();
+		}
 		
-		console.log('h : ' + -newZoomLeft + " " + zoomedImg.position().left);
-
-		mos.snTop = (zoomedImg.position().top + newZoomTop + mos.MPTop_margin), mos.snLeft = (zoomedImg.position().left + newZoomLeft);
-		mos.snWidth = newSnWidth + 1, mos.snHeight = newSnHeight + 1;
+		_this.snTop = (zoomedImg.position().top + newZoomTop + _this.MPTop_margin), _this.snLeft = (zoomedImg.position().left + newZoomLeft);
+		_this.snWidth = newSnWidth + 1, _this.snHeight = newSnHeight + 1;
 		
-		mos.loadPlayer(mos.snTop, mos.snLeft, mos.snWidth, mos.snHeight, newZoomTop, newZoomLeft);
+		_this.notifyTopVideo = newZoomTop;
+		_this.notifyLeftVideo = newZoomLeft;
 		
-        /*mos.unload();
-        mos.localMos.loadLocalMosaic(newZoomTop, newZoomLeft, newSnWidth, newSnHeight, mos.imgs, tab[1]);*/
+		_this.loadPlayer(_this.snTop, _this.snLeft, _this.snWidth, _this.snHeight, newZoomTop, newZoomLeft);
     });
 }
 
@@ -444,20 +729,20 @@
 */
 mosaic.prototype.loadPlayer = function(newZoomTop, newZoomLeft, newSnWidth, newSnHeight, zoomTop, zoomLeft)
 {
+	var _this = this;
+	
 	//On configure les options de lancement.
 	IriSP.libFiles.defaultDir = "../lib/";
 	IriSP.widgetsDir = "./player/metadataplayer/"
 	
 	var videoToPlay = this.videos[this.centerId];
 	var currentMetadata = this.urls[this.centerId];
-	console.log('VIDEO[' + this.centerId + '] : ' + videoToPlay);
-	console.log('MD[' + this.centerId + '] : ' + currentMetadata);
 	
 	var _metadata = {
 		url: currentMetadata,
 		format: 'ldt'
 	};
-	console.log(zoomTop + " m" + this.marginWidth);
+	
 	var _config = {
 		gui: {
 			zoomTop: zoomTop - this.marginWidth*2,
@@ -498,6 +783,23 @@
 	//On démarre le player.
 	this.player = null;
 	this.player = new IriSP.Metadataplayer(_config, _metadata);
+	
+	if(this.currentMode == 'NO-USER')
+	{
+		this.player.onLoad(function()
+		{
+			console.log(_this.player);
+			console.log(_this.player.popcorn);
+			//Lorsque le player est en pause (par exemple lorsque le curseur arrive à la fin de la timeline).
+			if(_this.player.popcorn != undefined)
+			{
+				_this.player.popcorn.listen('pause', function()
+				{
+					_this.unzoom();
+				});
+			}
+		});
+	}
 }
 
 /*
@@ -506,7 +808,8 @@
 mosaic.prototype.unzoom = function()
 {
     //Si on n'est pas en plein écran, on quitte.
-    if(!this.fullscreen)
+	console.log("'" + this.currentMode + "'");
+    if(this.currentMode != "SEARCH" && this.currentMode != "VIDEO" && this.currentMode != "NO-USER" && this.currentMode.indexOf("INCOMING") == -1)
 	{
         return;
 	}
@@ -519,25 +822,45 @@
     //On charge les attributs nécessaires aux calculs.
     var sWidth = this.snapshotWidth, sHeight = this.snapshotHeight;
     var mpWidth = this.width, mpHeight = this.height;
-    var mos = this;
+    var _this = this;
     
     //On passe le snapshot sur lequel on a zoomé en SD.
     var zoomedImg = $('img', this.previousZoomedSN);
     var src = zoomedImg.attr('src');
     zoomedImg.attr('src', src.replace('snapshots/', 'snapshots-little/'));
 	
-	mos.player.widgets[0].freePlayer();
+	_this.player.widgets[0].freePlayer();
 	$('.LdtPlayer').remove();
 	$('body').append('<div class="LdtPlayer" id="LdtPlayer"></div>');
+	_this.reaffectKeyPress();
     
     //On rend leur opacité aux snapshots. Qui ne sont alors plus grisés.
     $('.snapshotDivs').animate(
     {
         width: sWidth,
         height: sHeight,
-        margin: this.marginWidth/2 + 'px',
-        opacity: '1'
-    }, this.unzoomTime);
+        margin: this.marginWidth/2 + 'px'
+    }, this.config['unzoomTime']);
+	
+	if(this.currentMode != 'NO-USER')
+	{
+		if(this.currentMode.indexOf("INCOMING") == -1)
+		{
+			$('.snapshotDivs').animate(
+			{
+				opacity: '1'
+			}, this.config['unzoomTime']);
+		}
+	}
+	else
+	{
+		console.log('init');
+		this.previousZoomedSN.fadeTo(this.config['unzoomTime'], 0, function()
+		{
+			_this.init();
+		});
+	}
+	
     //On dézoom sur la mosaïque.
     $('#mainPanel').animate(
     {
@@ -545,17 +868,24 @@
         height: mpHeight,
         top: '0px',
         left: '0px'
-    }, this.unzoomTime, function()
+    }, this.config['unzoomTime'], function()
     {
         //On n'est plus en plein écran, et on ne peut plus se déplacer vers le prochain voisin.
-        mos.fullscreen = false;
-        mos.canMoveToNeighbour = false;
-        //On revient en mode MOSAIC.
-        mos.currentMode = 'MOSAIC';
-        //On ne permet plus le déplacement vers les voisins.
-        $('.snapshotDivs').unbind('mouseenter', mos.selectNeighbour);
-		//On remet les notifications initiales.
-		mos.notifySelectionSearchMosaicFull();
+        _this.fullscreen = false;
+        _this.canMoveToNeighbour = false;
+		
+		if(_this.currentMode != 'NO-USER')
+		{
+			//On revient en mode MOSAIC.
+			_this.currentMode = 'MOSAIC';
+			//On ne permet plus le déplacement vers les voisins.
+			$('.snapshotDivs').unbind('mouseover', function()
+			{
+				_this.selectNeighbour();
+			});
+			//On remet les notifications initiales.
+			_this.notifySelectionSearchMosaicFull();
+		}
     });
 }
 
@@ -566,20 +896,21 @@
 {
     ////TEST
     //$('.test').empty();
-    this.canMoveToNeighbour = false;
-    var currentLine = Math.floor(this.centerId / this.length), currentColumn = this.centerId % this.length;
+    var _this = this;
+    
+	this.canMoveToNeighbour = false;
+    var currentLine = Math.floor(this.centerId / this.config['length']), currentColumn = this.centerId % this.config['length'];
     var zoomedImg = $('img', this.previousZoomedSN);
-    var mos = this;
     
     //On cherche l'ID des voisins.
     //Si le voisin de gauche est sur la même ligne, on n'est pas sur la bordure de gauche.
     this.neighboursIds[0] = (currentColumn > 0) ? (this.centerId - 1) : -1;
     //Si le voisin de droite est sur la même ligne, on n'est pas sur la bordure de droite.
-    this.neighboursIds[1] = (currentColumn < this.length) ? (+this.centerId + 1) : -1;
+    this.neighboursIds[1] = (currentColumn < this.config['length']) ? (+this.centerId + 1) : -1;
     //Si le voisin du haut est sur la même colonne, on n'est pas sur la bordure du haut.
-    this.neighboursIds[2] = (currentLine > 0) ? (this.centerId - this.length) : -1;
+    this.neighboursIds[2] = (currentLine > 0) ? (this.centerId - this.config['length']) : -1;
     //Si le voisin du bas est sur la même colonne, on n'est pas sur la bordure du bas.
-    this.neighboursIds[3] = (currentLine < (this.imagesToShow / this.length)) ? (+this.centerId + this.length) : -1;
+    this.neighboursIds[3] = (currentLine < (this.config['imagesToShow'] / this.config['length'])) ? (+this.centerId + this.config['length']) : -1;
     
 	//ID du cadre voisin.
 	var preId;
@@ -591,7 +922,11 @@
 			preId = '#neighbourFrameBorder-' + this.neighboursIds[i];
             //On permet le déplacement vers les voisins.
             // $('#snapshotDiv-' + this.neighboursIds[i] + ', ' + preId + '-left,' + preId + '-right,' + preId + '-up,' + preId + '-down').mouseenter(mos.selectNeighbour);
-            $('#snapshotDiv-' + this.neighboursIds[i]).mouseenter(mos.selectNeighbour);
+			
+            $('#snapshotDiv-' + this.neighboursIds[i]).mouseover(function()
+			{
+				_this.selectNeighbour($(this));
+			});
         }
     }
 }
@@ -599,20 +934,22 @@
 /*
  * Change la coloration d'une bordure où on se positionne lors d'une vue en plein écran.
  */
-mosaic.prototype.selectNeighbour = function()
+mosaic.prototype.selectNeighbour = function(neighbour)
 {
     ////TEST
     //$('.test').append(mos.currentMode + " " + $(this).attr('id') + " " + 'snapshotDiv-' + mos.centerId + ',');
-    
+	var _this = this;
+	
     //Si on est en mode VIDEO (plein écran) ET si le snapshot pointé est un voisin.
-    if((mos.currentMode == 'VIDEO') && ($(this).attr('id') != 'snapshotDiv-' + mos.centerId))
-    {
+    
+    if((this.currentMode == 'VIDEO') && (neighbour.attr('id') != 'snapshotDiv-' + this.centerId))
+    {
         //On crée le cadre qui va être superposé au voisin.
         //On le colle au voisin.
-		var tab = $(this).attr('id').split('-');
+		var tab = neighbour.attr('id').split('-');
 		var snapshotId = tab[1];
         var neighbourFrame = '';
-		var marginValue = parseFloat($(this).css('margin'));
+		var marginValue = parseFloat(neighbour.css('margin'));
 		
 		neighbourFrame += '<div class="neighbourFrame" id="neighbourFrame-' + snapshotId + '"><div class="neighbourImgBg" id="neighbourImgBg-' + snapshotId + '"><div class="neighbourImg" id="neighbourImg-' + snapshotId + '"></div></div></div>';
 		
@@ -621,28 +958,28 @@
 		//On positionne le div de background juste au niveau du voisin.
         $('#neighbourFrame-' + snapshotId).css(
 		{
-			'top': (+$(this).position().top + marginValue),
-			'left': (+$(this).position().left + marginValue),
-			'width': $(this).width(),
-			'height': $(this).height()
+			'top': (+neighbour.position().top + marginValue),
+			'left': (+neighbour.position().left + marginValue),
+			'width': neighbour.width(),
+			'height': neighbour.height()
 		});
 		//On positionne le div de background noir juste au niveau de l'image du voisin.
         $('#neighbourImgBg-' + snapshotId).css(
 		{
 			'top': marginValue,
 			'left': marginValue,
-			'width': $(this).width() - marginValue*2,
-			'height': $(this).height() - marginValue*2,
+			'width': neighbour.width() - marginValue*2,
+			'height': neighbour.height() - marginValue*2,
 		});
 		//On met par dessus le div de l'image clonée du voisin.
 		$('#neighbourImg-' + snapshotId).css(
 		{
 			'top': 0,
 			'left': 0,
-			'width': $(this).width() - marginValue*2,
-			'height': $(this).height() - marginValue*2,
-			'background-image': 'url("' + $('img', $(this)).attr('src') + '")',
-			'background-size': $(this).width() + 'px ' + $(this).height() + 'px',
+			'width': neighbour.width() - marginValue*2,
+			'height': neighbour.height() - marginValue*2,
+			'background-image': 'url("' + $('img', neighbour).attr('src') + '")',
+			'background-size': neighbour.width() + 'px ' + neighbour.height() + 'px',
 			'background-position': -marginValue + 'px ' + -marginValue + 'px',
 			'opacity': '0.4'
 		});
@@ -653,40 +990,45 @@
         {
             //On le fait apparaître.
             opacity: '1'
-        }, timeNeighbourGlowing, function()
+        }, _this.config['timeNeighbourGlowing'], function()
         {
             //On peut désormais se déplacer vers ce voisin.
-            mos.canMoveToNeighbour = true;
+            _this.canMoveToNeighbour = true;
         });
 		//Lorsqu'on quitte un des snapshots (bien entendu le voisin en question), on retire le cadre.
-		$(fId).mouseleave(mos.deselectNeighbour)
 		//Si on clique sur le voisin ou son cadre, on passe au voisin suivant.
-		$(fId).click(mos.moveToNeighbour);
+		$(fId).mouseout(function()
+		{
+			_this.deselectNeighbour($(this))
+		}).click(function()
+		{
+			_this.moveToNeighbour($(this))
+		});
     }
 }
 
 /*
  * Change la coloration d'une bordure quittée lors d'une vue en plein écran.
  */
-mosaic.prototype.deselectNeighbour = function()
+mosaic.prototype.deselectNeighbour = function(neighbour)
 {
     ////TEST
     //$('.test').append('un,');
 	
     //On ne peut plus se déplacer vers les voisins.
-    mos.canMoveToNeighbour = false;
+    this.canMoveToNeighbour = false;
     
 	//On récupère le voisin.
-	var neighbourFrame = $(this);
+	var neighbourFrame = neighbour;
 	
     //Si on est en mode VIDEO.
-    if(mos.currentMode == 'VIDEO')
+    if(this.currentMode == 'VIDEO')
     {
         //On le fait disparaître progressivement.
         neighbourFrame.animate(
         {
             opacity: '0'
-        }, timeNeighbourUnglowing, function()
+        }, this.config['timeNeighbourUnglowing'], function()
         {
             //Une fois invisible, on le supprime.
             neighbourFrame.remove();
@@ -697,34 +1039,36 @@
 /*
  * Lors d'une vue en plein écran, on se déplace vers le voisin dont l'id a été spécifié dans la fonction appelante.
  */
-mosaic.prototype.moveToNeighbour = function()
-{
+mosaic.prototype.moveToNeighbour = function(neighbour)
+{
+	var _this = this;
     //Si on ne peut pas se déplacer vers les voisins, on quitte.
-    if(!mos.canMoveToNeighbour)
+    if(!_this.canMoveToNeighbour)
 	{
         return;
 	}
     
     //On obtient l'ID de destination.
-    var tab = $(this).attr('id').split('-');
+    var tab = neighbour.attr('id').split('-');
     var destinationId = tab[1];
     
     //On charge les attributs nécessaires aux calculs.
+	var length = _this.config['length'];
     var MPCurrentTop = $('#mainPanel').position().top, MPCurrentLeft = $('#mainPanel').position().left;
-    var divideCoeffTop = Math.floor(destinationId / mos.length) == 0 ? 1 : Math.floor(destinationId / mos.length);
-    var divideCoeffLeft = destinationId % mos.length == 0 ? 1 : destinationId % mos.length;
+    var divideCoeffTop = Math.floor(destinationId / length) == 0 ? 1 : Math.floor(destinationId / length);
+    var divideCoeffLeft = destinationId % length == 0 ? 1 : destinationId % length;
     var neighbourFrameTop = $('#snapshotDiv-' + destinationId).position().top, neighbourFrameLeft = $('#snapshotDiv-' + destinationId).position().left;
     
     //On définit pour le déplacement vertical s'il est nécessaire de se déplacer en haut ou en bas.
-    if(mos.previousZoomedSN.position().top > neighbourFrameTop)
-        MPCurrentTop += Math.abs(neighbourFrameTop - mos.previousZoomedSN.position().top);
-    else if(mos.previousZoomedSN.position().top < neighbourFrameTop)
-        MPCurrentTop -= Math.abs(neighbourFrameTop - mos.previousZoomedSN.position().top);
+    if(_this.previousZoomedSN.position().top > neighbourFrameTop)
+        MPCurrentTop += Math.abs(neighbourFrameTop - _this.previousZoomedSN.position().top);
+    else if(_this.previousZoomedSN.position().top < neighbourFrameTop)
+        MPCurrentTop -= Math.abs(neighbourFrameTop - _this.previousZoomedSN.position().top);
     //On définit pour le déplacement horizontal s'il est nécessaire de se déplacer à gauche ou à droite.
-    if(mos.previousZoomedSN.position().left > neighbourFrameLeft)
-        MPCurrentLeft += Math.abs(neighbourFrameLeft - mos.previousZoomedSN.position().left);
-    else if(mos.previousZoomedSN.position().left < neighbourFrameLeft)
-        MPCurrentLeft -= Math.abs(neighbourFrameLeft - mos.previousZoomedSN.position().left);
+    if(_this.previousZoomedSN.position().left > neighbourFrameLeft)
+        MPCurrentLeft += Math.abs(neighbourFrameLeft - _this.previousZoomedSN.position().left);
+    else if(_this.previousZoomedSN.position().left < neighbourFrameLeft)
+        MPCurrentLeft -= Math.abs(neighbourFrameLeft - _this.previousZoomedSN.position().left);
     
     //On passe le snapshot de destination en HD.
     var destinationImg = $('#snapshot-' + destinationId);
@@ -732,22 +1076,23 @@
     destinationImg.attr('src', destinationImgSrc.replace('snapshots-little/', 'snapshots/'));
     
     //On passe l'ancien snapshot en SD.
-    var currentImgSrc = $('img', mos.previousZoomedSN).attr('src');
-    $('img', mos.previousZoomedSN).attr('src', currentImgSrc.replace('snapshots/', 'snapshots-little/'));
+    var currentImgSrc = $('img', _this.previousZoomedSN).attr('src');
+    $('img', _this.previousZoomedSN).attr('src', currentImgSrc.replace('snapshots/', 'snapshots-little/'));
     
     //On obtient l'ID du div de coloration du snapshot vers lequel on se déplace afin de le supprimer.
-    var neighbourFrame = $(this);
+    var neighbourFrame = neighbour;
     var tab = neighbourFrame.attr('id').split('-');
-    mos.centerId = tab[1];
+    _this.centerId = tab[1];
     $(this).css('opacity', '0');
     neighbourFrame.remove();
     
-	mos.player.widgets[0].freePlayer();
+	_this.player.widgets[0].freePlayer();
 	$('.LdtPlayer').remove();
 	$('body').append('<div class="LdtPlayer" id="LdtPlayer"></div>');
+	_this.reaffectKeyPress();
 	
     //On grise le snapshot qu'on vient de quitter.
-    mos.previousZoomedSN.animate(
+    _this.previousZoomedSN.animate(
     {
         opacity: '0.4'
     });
@@ -757,20 +1102,23 @@
     {
         top: MPCurrentTop,
         left: MPCurrentLeft
-    }, timeMovingToNeighbour, function()
+    }, _this.config['timeMovingToNeighbour'], function()
     {
         //On fait apparaître le snapshot vers lequel on s'est déplacé.
         $('#snapshotDiv-' + destinationId).animate(
         {
             opacity: '1'
-        }, mos.zoomTime, function()
+        }, _this.config['zoomTime'], function()
         {
             //On recharge les voisins.
-            $('.snapshotDivs').unbind('mouseenter', mos.selectNeighbour);
-            mos.previousZoomedSN = $('#snapshotDiv-' + mos.centerId);
-            mos.listenToNeighbours();
+            $('.snapshotDivs').unbind('mouseenter', _this.selectNeighbour);
+            _this.previousZoomedSN = $('#snapshotDiv-' + _this.centerId);
+            _this.listenToNeighbours();
 			
-			mos.loadPlayer((destinationImg.position().top + MPCurrentTop + mos.MPTop_margin), (destinationImg.position().left + MPCurrentLeft), destinationImg.width(), destinationImg.height(), MPCurrentTop, MPCurrentLeft);
+			_this.notifyTopVideo = MPCurrentTop;
+			_this.notifyLeftVideo = MPCurrentLeft;
+			
+			_this.loadPlayer((destinationImg.position().top + MPCurrentTop + _this.MPTop_margin), (destinationImg.position().left + MPCurrentLeft), destinationImg.width(), destinationImg.height(), MPCurrentTop, MPCurrentLeft);
         });
     });
 }
@@ -834,19 +1182,24 @@
 	{
 		$.each(data, function(key, val)
 		{
-			// console.log(val);
 			$.each(val, function(key_video, val_video)
 			{
 				$.getJSON(val_video.metadata, function(meta)
 				{
-					_this.affectVideoById(val_video.metadata, meta.medias[0].url.replace('rtmp://', 'http://').replace('/ddc_player/', '/').replace('mp4:', '').replace('.m4v', '.mp4'));
-					//console.log(meta.medias[0].url.replace('rtmp://', 'http://').replace('/ddc_player/', '/'));
+					if(_this.config['local'] == 'true')
+					{
+						_this.affectVideoById(val_video.metadata, meta.medias[0].url.replace('rtmp://media.iri.centrepompidou.fr/ddc_player/', './player/videos/').replace('mp4:', '').replace('video/', '').replace('ldtplatform/', '').replace('.m4v', '.mp4'));
+						console.log(meta.medias[0].url.replace('rtmp://media.iri.centrepompidou.fr/ddc_player/', './player/videos/').replace('mp4:', '').replace('video/', '').replace('ldtplatform/', '').replace('.m4v', '.mp4'));
+					}
+					else
+					{
+						_this.affectVideoById(val_video.metadata, meta.medias[0].url.replace('rtmp://', 'http://').replace('/ddc_player/', '/').replace('mp4:', '').replace('.m4v', '.mp4'));
+						console.log(meta.medias[0].url.replace('rtmp://', 'http://').replace('/ddc_player/', '/').replace('mp4:', '').replace('.m4v', '.mp4'));
+					}
 				});
-				
-				// _this.imgs.push(val_video.snapshot);
-				// _this.urls.push(val_video.metadata);
 				_this.imgs[_this.ids[i]] = val_video.snapshot;
 				_this.urls[_this.ids[i]] = val_video.metadata;
+				console.log('ids : ' + _this.ids[i]);
 				i++;
 			});
 		});
@@ -921,6 +1274,11 @@
 */
 mosaic.prototype.notifySelectionSearchMosaicFull = function()
 {
+	if(this.currentMode == "NO-USER" || this.currentMode.indexOf("INCOMING") == -1)
+	{
+		return;
+	}
+	
 	//On spécifie les notifications en div.
 	var notification_selection = "<div id='notify_selection' class='notifications'></div>";
 	var notification_search = "<div id='notify_search' class='notifications'></div>";
@@ -964,7 +1322,7 @@
 */
 mosaic.prototype.notifyPointMosaicPrezoom = function()
 {
-	if($('#notify_point').length > 0)
+	if($('#notify_point').length > 0 || this.currentMode == "NO-USER" || this.currentMode.indexOf("INCOMING") == -1)
 	{
 		return;
 	}
@@ -974,7 +1332,7 @@
 	
 	//On les ajoute à la mosaïque.
 	$('#mainPanel').append(notification_point);
-	console.log('Append');
+	
 	//On calcule leurs coordonnées et dimensions.
 	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
 	var notify_margin = parseInt($('.notifications').css('margin'));
@@ -1071,8 +1429,7 @@
 		left: "0px",
 		top: "0px",
 		width: notify_width - notify_margin * 2,
-		height: notify_height - notify_margin * 2,
-		"margin-top": notify_margin_top
+		height: notify_height - notify_margin * 2
 	});
 	
 	var search_width = $('#help_search').width();
@@ -1131,4 +1488,220 @@
 		_this.helpDisplayed = false;
 		$('#notify_help').remove();
 	});
+}
+
+/*
+ * Affiche les types de marqueurs correspondants à ce qu'on a commencé à tracer lors d'une recherche.
+*/
+ mosaic.prototype.notifySearchMarkers = function(markersStr)
+{
+	if($('.notifications_inSearch_container').length > 0)
+	{
+		return;
+	}
+	
+	console.log(markersStr);
+	
+	var markersList = markersStr.split(new RegExp(';'));
+	
+	var notification_search_markers = "<div class='notifications_inSearch_container'>";
+	
+	//On spécifie les notifications en div.
+	for(var i = 0 ; i < markersList.length ; i++)
+	{
+		notification_search_markers += "<div class='notifications_inSearch' style='background-image: url(./pictos/big/normal/" + markersList[i] + ".png);'></div>";
+	}
+	
+	notification_search_markers += "</div>";
+	
+	//On les ajoute à la mosaïque.
+	$('#mainPanel').append(notification_search_markers);
+	
+	//On calcule leurs coordonnées et dimensions.
+	var notify_width = $('.notifications_inSearch_container').width(), notify_height = $('.notifications_inSearch_container').height();
+	var notify_margin = parseInt($('.notifications_inSearch').css('margin'));
+	var point_left = $(window).width() / 2 - (notify_width) / 2 - notify_margin;
+	var point_top = 0;
+	
+	if(this.currentMode == "VIDEO" || this.currentMode == "SEARCH")
+	{
+		point_top = -this.notifyTopVideo,
+		point_left = -this.notifyLeftVideo + ($(window).width() - notify_width) / 2
+	}
+	
+	//On les positionne.
+	$('.notifications_inSearch_container').css(
+	{
+		left: point_left,
+		top: point_top
+	});
+	
+	//On les fait apparaître.
+	$('.notifications_inSearch').css(
+	{
+		opacity: "0.9"
+	});
+}
+
+/*
+ * Supprime la notification de maintient du pointage.
+*/
+mosaic.prototype.removeSearchMarkers = function()
+{	
+	$('.notifications_inSearch_container').remove();
+}
+
+/*
+ * Effectuer un filtrage de la mosaïque par rapport à un type de marqueurs.
+*/
+mosaic.prototype.searchFilter = function(type)
+{
+	var _this = this;
+	
+	if(this.currentMode == "MOSAIC")
+	{
+		this.currentMode = "FILTER";
+		
+		if(this.annotations.length > 0)
+		{
+			var gestureNumberByVideo = new Object();
+			var maxAnnotationNumber = 0;
+			// for(var i = 0 ; i < this.config['imagesToShow'] ; i++)
+			for(var i = 0 ; i < this.annotations.length ; i++)
+			{
+				var current = this.annotations[i];
+				if(current.annotationType.contents.title == type)
+				{
+					if(gestureNumberByVideo[current.source.url] == undefined || gestureNumberByVideo[current.source.url] == '')
+					{
+						gestureNumberByVideo[current.source.url] = 0;
+					}
+					
+					gestureNumberByVideo[current.source.url]++;
+				}
+			}
+			
+			for(var i = 0 ; i < this.urls.length ; i++)
+			{
+				if(gestureNumberByVideo[this.urls[i]] == undefined || gestureNumberByVideo[this.urls[i]] == '')
+				{
+					gestureNumberByVideo[this.urls[i]] = 0;
+				}
+			}
+			
+			//On récupère la vidéo qui score le nombre d'occurences de la gesture le plus haut.
+			for(i in gestureNumberByVideo)
+			{	
+				// console.log(i + " " + gestureNumberByVideo[i]);
+				if(maxAnnotationNumber < gestureNumberByVideo[i])
+				{
+					maxAnnotationNumber = gestureNumberByVideo[i];
+				}
+			}
+			
+			var snMargin = parseInt($('.snapshotDivs').css('margin'));
+			
+			//On affiche l'opacité résultante pour chaque vidéo.
+			for(i in gestureNumberByVideo)
+			{
+				//Opacité conventionelle.
+				var opacity = gestureNumberByVideo[i] / maxAnnotationNumber;
+				// console.log('opacity b : ' + opacity + ' for ' + gestureNumberByVideo[i]);
+				//Ce qui est à zéro le restera (par conséquent le snapshot associé sera invisible).
+				if(opacity > 0)
+				{
+					//On réhausse l'opacité de 50%.
+					opacity = this.scaleIntervals(0., 1., 0.5, 1., opacity);
+				}
+				
+				var filterIndex = this.getIdxFromMetadata(i);
+				
+				if(filterIndex >= 0)
+				{
+					console.log('#snapshotDiv-' + filterIndex + " " + _this.config['timeFilterFade'] + " " + opacity);
+					$('#snapshotDiv-' + filterIndex).fadeTo(_this.config['timeFilterFade'], opacity);
+					
+					if(opacity == 0)
+					{
+						var filteredSnapshot = $('#snapshotDiv-' + filterIndex);
+						
+						if(filteredSnapshot.length > 0)
+						{
+							var hider = '<div id="filterHider-' + filterIndex + '" class="filterHiders"></div>';
+							$('#mainPanel').append(hider);
+							
+							$('#filterHider-' + filterIndex).css(
+							{
+								width: +filteredSnapshot.width() + 4 * snMargin,
+								height: +filteredSnapshot.height() + 4 * snMargin,
+								top: filteredSnapshot.position().top - snMargin,
+								left: filteredSnapshot.position().left - snMargin
+							});
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+/*
+ * Passe une valeur de l'intervalle [A, B] à l'intervalle [C, D].
+*/
+mosaic.prototype.scaleIntervals = function(A, B, C, D, val)
+{
+	return (D - C + A) * val + (C - A);
+}
+
+/*
+ * Retourne l'index d'un snapshot en fonction de ses metadonnées.
+*/
+mosaic.prototype.getIdxFromMetadata = function(metadata)
+{
+	var _this = this;
+	
+	for(idx in this.urls)
+	{
+		if(this.urls[idx] == metadata)
+		{
+			for(id in this.ids)
+			{
+				if(this.ids[id] == idx)
+				{
+					return id;
+				}
+			}
+		}
+	}
+	
+	return -1;
+}
+
+/*
+ * Enlève une recherche par filtre.
+*/
+mosaic.prototype.removeFilter = function()
+{
+	if(this.currentMode == "FILTER")
+	{
+		this.currentMode = "MOSAIC";
+		
+		var _this = this;
+		
+		$('.filterHiders').remove();
+		$('.snapshotDivs').fadeTo(_this.config['timeFilterFade'], 1);
+	}
+}
+
+/*
+ * Rebind keypress pour body.
+*/
+mosaic.prototype.reaffectKeyPress = function()
+{
+	var _this = this;
+	
+	$('body').keypress(function (event)
+	{
+		_this.manageControlEvents(event);
+	});
 }
\ No newline at end of file
--- a/front_idill/src/player/metadataplayer/LdtPlayer-core.js	Thu May 24 10:35:27 2012 +0200
+++ b/front_idill/src/player/metadataplayer/LdtPlayer-core.js	Wed May 30 10:21:36 2012 +0200
@@ -41,11 +41,35 @@
     this.video_metadata = video_metadata;
     this.sourceManager = new IriSP.Model.Directory();
     this.config = config;
+    this.callbackQueue = [];
+    this.isLoaded = false;
     this.loadLibs();
 }
 
 IriSP.Metadataplayer.prototype.toString = function() {
-    return 'A Metadataplayer in DIV #' + this.config.gui.container;
+    return 'Metadataplayer in #' + this.config.gui.container;
+}
+
+IriSP.Metadataplayer.prototype.deferCallback = function(_callback) {
+    var _this = this;
+    IriSP._.defer(function() {
+        _callback.call(_this);
+    });
+}
+
+IriSP.Metadataplayer.prototype.handleCallbacks = function() {
+    this.isLoaded = true;
+    while (this.callbackQueue.length) {
+        this.deferCallback(this.callbackQueue.splice(0,1)[0]);
+    }
+}
+
+IriSP.Metadataplayer.prototype.onLoad = function(_callback) {
+    if (this.isLoaded) {
+        this.deferCallback(_callback);
+    } else {
+        this.callbackQueue.push(_callback);
+    }
 }
 
 IriSP.Metadataplayer.prototype.loadLibs = function() {
@@ -143,6 +167,7 @@
         });
     };
     this.$.find('.Ldt-Loader').detach();
+    this.handleCallbacks();
 }
 
 IriSP.Metadataplayer.prototype.loadWidget = function(_widgetConfig, _callback) {
@@ -178,7 +203,7 @@
         spacerDiv = ret[1],
         _this = this,
         _types = {
-            "html5" : /\.(ogg|ogv|webm|mp4)$/,
+            "html5" : /\.(ogg|ogv|webm)$/,
             "youtube" : /^(https?:\/\/)?(www\.)?youtube\.com/,
             "dailymotion" : /^(https?:\/\/)?(www\.)?dailymotion\.com/
         };
@@ -255,6 +280,10 @@
             pop = new IriSP.PopcornReplacement.dailymotion("#" + containerDiv, this.config.player);
             break;
 
+        case "mashup":
+            pop = new IriSP.PopcornReplacement.mashup("#" + containerDiv, this.config.player);
+            break;
+            
         case "allocine":
             /* pass the options as-is to the allocine player and let it handle everything */
             pop = new IriSP.PopcornReplacement.allocine("#" + containerDiv, this.config.player);
@@ -301,7 +330,7 @@
 /* utils.js - various utils that don't belong anywhere else */
 
 IriSP.jqEscape = function(_text) {
-    return text.replace(/(:|\.)/g,'\\$1');
+    return _text.replace(/(:|\.)/g,'\\$1');
 }
 
 IriSP.getLib = function(lib) {
@@ -362,7 +391,7 @@
     "muted": false
   };
     
-  this.container = container.slice(1); //eschew the '#'
+  this.container = container.replace(/^#/,''); //eschew the '#'
   
   this.msgPump = {}; /* dictionnary used to receive and send messages */
   this.__codes = []; /* used to schedule the execution of a piece of code in 
@@ -625,6 +654,7 @@
     this.directory = _directory;
     this.idIndex = [];
     if (typeof _directory == "undefined") {
+        console.trace();
         throw "Error : new IriSP.Model.List(directory): directory is undefined";
     }
 }
@@ -632,15 +662,7 @@
 IriSP.Model.List.prototype = new Array();
 
 IriSP.Model.List.prototype.getElement = function(_id) {
-    var _index = IriSP._(this.idIndex).indexOf(_id);
-    if (_index !== -1) {
-        return this[_index];
-    } else {
-        var _un = _id.replace(/.*:/);
-        return IriSP._(this.idIndex).find(function(_i) {
-            return _i.replace(/.*:/) === _un;
-        });
-    }
+    return this[_id];
 }
 
 IriSP.Model.List.prototype.hasId = function(_id) {
@@ -668,6 +690,12 @@
     }
 }
 
+IriSP.Model.List.prototype.pluck = function(_key) {
+    return this.map(function(_value) {
+        return _value[_key];
+    });
+}
+
 /* We override Array's filter function because it doesn't return an IriSP.Model.List
  */
 IriSP.Model.List.prototype.filter = function(_callback) {
@@ -800,6 +828,12 @@
  */
 
 IriSP.Model.Time = function(_milliseconds) {
+    this.milliseconds = 0;
+    this.setMilliseconds(_milliseconds);
+}
+
+IriSP.Model.Time.prototype.setMilliseconds = function(_milliseconds) {
+    var _ante = _milliseconds;
     switch(typeof _milliseconds) {
         case "string":
             this.milliseconds = parseFloat(_milliseconds);
@@ -814,7 +848,7 @@
             this.milliseconds = 0;
     }
     if (this.milliseconds === NaN) {
-        this.milliseconds = 0;
+        this.milliseconds = _ante;
     }
 }
 
@@ -955,13 +989,24 @@
 IriSP.Model.Media.prototype = new IriSP.Model.Element();
 
 IriSP.Model.Media.prototype.setDuration = function(_durationMs) {
-    this.duration.milliseconds = _durationMs;
+    this.duration.setMilliseconds(_durationMs);
 }
 
 IriSP.Model.Media.prototype.getAnnotations = function() {
     return this.getRelated("annotation");
 }
 
+IriSP.Model.Media.prototype.getAnnotationsByTypeTitle = function(_title) {
+    var _annTypes = this.source.getAnnotationTypes().searchByTitle(_title).pluck("id");
+    if (_annTypes.length) {
+        return this.getAnnotations().filter(function(_annotation) {
+            return IriSP._(_annTypes).indexOf(_annotation.getAnnotationType().id) !== -1;
+        });
+    } else {
+        return new IriSP.Model.List(this.source.directory)
+    }
+}
+
 /* */
 
 IriSP.Model.Tag = function(_id, _source) {
@@ -1001,11 +1046,11 @@
 IriSP.Model.Annotation.prototype = new IriSP.Model.Element(null);
 
 IriSP.Model.Annotation.prototype.setBegin = function(_beginMs) {
-    this.begin.milliseconds = _beginMs;
+    this.begin.setMilliseconds(_beginMs);
 }
 
 IriSP.Model.Annotation.prototype.setEnd = function(_beginMs) {
-    this.end.milliseconds = _beginMs;
+    this.end.setMilliseconds(_beginMs);
 }
 
 IriSP.Model.Annotation.prototype.setMedia = function(_idRef) {
@@ -1036,17 +1081,21 @@
     return this.getTags().getTitles();
 }
 
+IriSP.Model.Annotation.prototype.getDuration = function() {
+    return new IriSP.Model.Time(this.end.milliseconds - this.begin.milliseconds)
+}
+
 /* */
 
-IriSP.Model.MashedAnnotation = function(_annotation, _offset) {
-    IriSP.Model.Element.call(this, IriSP.Model.getUID(), _annotation.source);
+IriSP.Model.MashedAnnotation = function(_mashup, _annotation) {
+    IriSP.Model.Element.call(this, _mashup.namespacedId.name + "_" + _annotation.namespacedId.name, _annotation.source);
     this.elementType = 'mashedAnnotation';
     this.annotation = _annotation;
-    this.begin = new IriSP.Model.Time(_offset);
-    var _duration = (this.annotation.end - this.annotation.begin);
-    this.end = new IriSP.Model.Time(_offset + _duration)
+    this.begin = new IriSP.Model.Time(_mashup.duration);
+    this.end = new IriSP.Model.Time(_mashup.duration + _annotation.getDuration());
     this.title = this.annotation.title;
     this.description = this.annotation.description;
+    this.color = this.annotation.color;
 }
 
 IriSP.Model.MashedAnnotation.prototype = new IriSP.Model.Element(null);
@@ -1073,15 +1122,24 @@
     IriSP.Model.Element.call(this, _id, _source);
     this.elementType = 'mashup';
     this.duration = new IriSP.Model.Time();
-    this.segments = new IriSP.Model.List();
-    this.medias = new IriSP.Model.List();
+    this.segments = new IriSP.Model.List(_source.directory);
+    this.medias = new IriSP.Model.List(_source.directory);
 }
 
 IriSP.Model.Mashup.prototype = new IriSP.Model.Element();
 
 IriSP.Model.Mashup.prototype.addSegment = function(_annotation) {
-    this.segments.push(new IriSP.Model.MashedAnnotation(_annotation));
-    this.medias.addElement(_annotation.getMedia());
+    var _mashedAnnotation = new IriSP.Model.MashedAnnotation(this, _annotation);
+    this.duration.setMilliseconds(_mashedAnnotation.end);
+    this.segments.push(_mashedAnnotation);
+    this.medias.push(_annotation.getMedia());
+}
+
+IriSP.Model.Mashup.prototype.addSegmentById = function(_elId) {
+    var _annotation = this.source.getElement(_elId);
+    if (typeof _annotation !== "undefined") {
+        this.addSegment(_annotation);
+    }
 }
 
 IriSP.Model.Mashup.prototype.getAnnotations = function() {
@@ -1091,6 +1149,38 @@
 IriSP.Model.Mashup.prototype.getMedias = function() {
     return this.medias;
 }
+
+IriSP.Model.Mashup.prototype.getAnnotationsByTypeTitle = function(_title) {
+    var _annTypes = this.source.getAnnotationTypes().searchByTitle(_title).pluck("id");
+    if (_annTypes.length) {
+        return this.getAnnotations().filter(function(_annotation) {
+            return IriSP._(_annTypes).indexOf(_annotation.getAnnotationType().id) !== -1;
+        });
+    } else {
+        return new IriSP.Model.List(this.source.directory)
+    }
+}
+
+IriSP.Model.Mashup.prototype.getAnnotationAtTime = function(_time) {
+    var _list = this.segments.filter(function(_annotation) {
+        return _annotation.begin <= _time && _annotation.end > _time;
+    });
+    if (_list.length) {
+        return _list[0];
+    } else {
+        return undefined;
+    }
+}
+
+IriSP.Model.Mashup.prototype.getMediaAtTime = function(_time) {
+    var _annotation = this.getAnnotationAtTime(_time);
+    if (typeof _annotation !== "undefined") {
+        return _annotation.getMedia();
+    } else {
+        return undefined;
+    }
+}
+
 /* */
 
 IriSP.Model.Source = function(_config) {
@@ -1181,7 +1271,7 @@
 
 IriSP.Model.Source.prototype.setCurrentMediaId = function(_idRef) {
     if (typeof _idRef !== "undefined") {
-        this.currentMedia = this.getMedias().getElement(this.getNamespaced(_idRef).fullname);
+        this.currentMedia = this.getElement(_idRef);
     }
 }
 
@@ -1225,7 +1315,6 @@
         this.deferCallback(this.callbackQueue.splice(0,1)[0]);
     }
 }
-
 IriSP.Model.Source.prototype.onLoad = function(_callback) {
     if (this.status === IriSP.Model._SOURCE_STATUS_READY) {
         this.deferCallback(_callback);
@@ -1252,6 +1341,16 @@
     return this.getList("media", _global);
 }
 
+IriSP.Model.Source.prototype.getTags = function(_global) {
+    _global = (typeof _global !== "undefined" && _global);
+    return this.getList("tag", _global);
+}
+
+IriSP.Model.Source.prototype.getMashups = function(_global) {
+    _global = (typeof _global !== "undefined" && _global);
+    return this.getList("mashup", _global);
+}
+
 IriSP.Model.Source.prototype.getAnnotationTypes = function(_global) {
     _global = (typeof _global !== "undefined" && _global);
     return this.getList("annotationType", _global);
@@ -1318,18 +1417,7 @@
 }
 
 IriSP.Model.Directory.prototype.getElement = function(_id) {
-    var _res = this.elements[_id];
-    if (typeof _res === "undefined") {
-        var _un = _id.replace(/.*:/),
-            _keys = IriSP._(this.elements).keys();
-            _key = IriSP._(_keys).find(function(_i) {
-                return _i.replace(/.*:/) === _un;
-            });
-        if (typeof _key !== "undefined") {
-            _res = this.elements[_key];
-        }
-    }
-    return _res;
+    return this.elements[_id];
 }
 
 IriSP.Model.Directory.prototype.addElement = function(_element) {
@@ -1498,7 +1586,8 @@
 }
 
 IriSP.Widgets.Widget.prototype.getWidgetAnnotations = function() {
-    return typeof this.annotation_type !== "undefined" && this.annotation_type ? this.source.getAnnotationsByTypeTitle(this.annotation_type) : this.source.getAnnotations();
+    var _curmedia = this.source.currentMedia;
+    return typeof this.annotation_type !== "undefined" && this.annotation_type ? _curmedia.getAnnotationsByTypeTitle(this.annotation_type) : _curmedia.getAnnotations();
 }
 
 /**
@@ -1810,148 +1899,176 @@
 };
 
 IriSP.PopcornReplacement.jwplayer.prototype = new IriSP.PopcornReplacement.player("", {});
-/* Cinecast Cinelab Serializer */
+/* To wrap a player the develop should create a new class derived from
+the IriSP.PopcornReplacement.player and defining the correct functions */
+
+/** jwplayer player wrapper */
+IriSP.PopcornReplacement.mashup = function(container, options) {
+    /* Appel du constructeur de la classe parente */
+    IriSP.PopcornReplacement.player.call(this, container, options);   
+    
+    var _this = this;
+
+    /* Définition des fonctions de commande :
+     this.playerFns.play, .pause, .getPosition, .seek,
+     .getMute, .setMute, .getVolume, .setVolume
+     doivent être rattachés aux fonctions du player
+     * */
+
+    this.playerFns = {
+        play : function() {
+            if (_this.player) {
+                return _this.player.playVideo();
+            } else {
+                return false;
+            }
+        },
+        pause : function() {
+            if (_this.player) {
+                return _this.player.pauseVideo();
+            } else {
+                return false;
+            }
+        },
+        getPosition : function() {
+            if (_this.player) {
+                return _this.player.getCurrentTime();
+            } else {
+                return 0;
+            }
+        },
+        seek : function(pos) {
+            if (_this.player) {
+                return _this.player.seekTo(pos);
+            } else {
+                return false;
+            }
+        },
+        getMute : function() {
+            if (_this.player) {
+                return _this.player.isMuted();
+            } else {
+                return false;
+            }
+        },
+        setMute : function(p) {
+            if (_this.player) {
+                if (p) {
+                    _this.player.mute();
+                }
+                else {
+                    _this.player.unMute();
+                }
+            }
+        },
+        getVolume : function() {
+            if (_this.player) {
+                return _this.player.getVolume() / 2;
+            } else {
+                return false;
+            }
+        },
+        setVolume : function(p) {
+            if (_this.player) {
+                _this.player.setVolume(Math.floor(2 * p));
+            }
+        },
+    }
+    
+    /* Dailymotion utilise un système de fonctions référencées dans
+     * des variables globales pour la gestion des événements.
+     */
+    
+    window.onBabPlayerReady = function() {
+        _this.onReady();
+    };
+    window.onBabStateChange = function(_state) {
+        _this.onStateChange(_state);
+    }
+    window.onBabVideoProgress = function(_progress) {
+        _this.onProgress(_progress);
+    }
+
+    var params = {
+        allowScriptAccess : "always",
+        wmode: "transparent",
+        quality: "high",
+        menu: true,
+        bgcolor: "#869ca7"
+    };
+    var atts = {
+        id : this.container
+    };
+    var flashvars = {
+        urlData: options.mashup_xml
+    };
+    swfobject.embedSWF(options.mashup_swf, this.container, options.width, options.height, "8", null, flashvars, params, atts);
+
+};
+
+IriSP.PopcornReplacement.mashup.prototype = new IriSP.PopcornReplacement.player("", {});
+
+IriSP.PopcornReplacement.mashup.prototype.onReady = function() {
+    
+    this.player = document.getElementById(this.container);
+    
+    this.callbacks.onReady();
+};
+
+IriSP.PopcornReplacement.mashup.prototype.onProgress = function(progressInfo) {
+    
+    this.callbacks.onTime({
+        position: progressInfo.mediaTime
+    });
+}
+
+IriSP.PopcornReplacement.mashup.prototype.onStateChange = function(state) {
+    
+    switch(state) {
+        case 1:
+            this.callbacks.onPlay();
+            break;
+
+        case 2:
+            this.callbacks.onPause();
+            break;
+
+        case 3:
+            this.callbacks.onSeek({
+                position: this.player.getCurrentTime()
+            });
+            break;
+    }
+    
+};/* Used when Putting annotations on the platform */
 
 if (typeof IriSP.serializers === "undefined") {
     IriSP.serializers = {}
 }
 
-IriSP.serializers.cinecast = {
+IriSP.serializers.ldt_annotate = {
     types :  {
-        media : {
-            serialized_name : "medias",
-            model_name : "media",
-            deserializer : function(_data, _source) {
-                var _res = new IriSP.Model.Media(_data.id, _source);
-                _res.video = _data.url;
-                _res.title = _data.meta.title;
-                _res.description = _data.meta.synopsis;
-                _res.setDuration(_data.meta.duration);
-                return _res;        
-            },
-            serializer : function(_data, _source) {
-                return {
-                    id : _source.unNamespace(_data.id),
-                    url : _data.video,
-                    meta : {
-                        title : _data.title,
-                        synopsis : _data.description,
-                        duration : _data.duration.milliseconds
-                    }
-                }
-            }
-        },
-        tag : {
-            serialized_name : "tags",
-            model_name : "tag",
-            deserializer : function(_data, _source) {
-                var _res = new IriSP.Model.Tag(_data.id, _source);
-                _res.title = _data.meta.description;
-                return _res;        
-            },
-            serializer : function(_data, _source) {
-                return {
-                    id : _source.unNamespace(_data.id),
-                    meta : {
-                        description : _data.title
-                    }
-                }
-            }
-        },
-        annotationType : {
-            serialized_name : "annotation_types",
-            deserializer : function(_data, _source) {
-                var _res = new IriSP.Model.AnnotationType(_data.id, _source);
-                _res.title = _source.getNamespaced(_data.id).name;
-                _res.description = _data.meta.description;
-                return _res;        
-            },
+        annotation : {
+            serialized_name : "annotations",
             serializer : function(_data, _source) {
                 return {
-                    id : _source.unNamespace(_data.id),
-                    meta : {
-                        description : _data.description
-                    }
-                }
-            }
-        },
-        annotation : {
-            serialized_name : "annotations",
-            deserializer : function(_data, _source) {
-                var _res = new IriSP.Model.Annotation(_data.id, _source);
-                _res.title = _data.meta.creator_name;
-                _res.description = _data.content.data;
-                _res.created = IriSP.Model.isoToDate(_data.meta.created);
-                _res.setMedia(_data.media, _source);
-                _res.setAnnotationType(_data.type);
-                _res.setTags(IriSP._(_data.tags).map(function(_t) {
-                    if (typeof _source.contents.tag === "undefined") {
-                        _source.contents.tag = new IriSP.Model.List(_source.directory);
-                    }
-                    if (_source.contents.tag.hasId(_t)) {
-                        return _t;
-                    } else {
-                        var _id = _t.toLowerCase()
-                            .replace(/#/g,'')
-                            .replace(/^(\d)/,'_$1')
-                            .replace(/[áâäàã]/g,'a')
-                            .replace(/ç/g,'c')
-                            .replace(/[éèêë]/g,'e')
-                            .replace(/[íìîï]/g,'i')
-                            .replace(/ñ/g,'n')
-                            .replace(/[óòôöõ]/g,'o')
-                            .replace(/œ/g,'oe')
-                            .replace(/[úùûü]/g,'u')
-                            .replace(/ÿ/g,'y')
-                            .replace(/[^A-Za-z0-9_]/g,''),
-                            _tag = new IriSP.Model.Tag(_id, _source);
-                        _tag.title = _t;
-                        _source.contents.tag.push(_tag);
-                        return _id;
-                    }
-                }));
-                _res.setBegin(_data.begin);
-                _res.setEnd(_data.end);
-                _res.creator = _data.meta.creator;
-                return _res;
-            },
-            serializer : function(_data, _source) {
-                return {
-                    id : _source.unNamespace(_data.id),
-                    content : {
-                        data : _data.description
+                    begin: _data.begin.milliseconds,
+                    end: _data.end.milliseconds,
+                    content: {
+                        data: _data.description
                     },
-                    begin : _data.begin.milliseconds,
-                    end : _data.begin.milliseconds,
-                    media : _source.unNamespace(_data.media.id),
-                    type : _source.unNamespace(_data.annotationType.id),
-                    meta : {
-                        created : IriSP.Model.dateToIso(_data.created),
-                        creator : _data.creator,
-                        creator_name : _data.title
-                    },
-                    tags : _data.tag.id.map(function(_id) {
-                        return _source.unNamespace(_id)
-                    })
+                    tags: _data.getTagTexts(),
+                    media: _source.unNamespace(_data.getMedia().id),
+                    title: _data.title,
+                    type_title: _data.getAnnotationType().title,
+                    type: _source.unNamespace(_data.getAnnotationType().id)
                 }
             }
         }
     },
     serialize : function(_source) {
-        var _res = {
-                format : "http://advene.org/ns/cinelab/"
-            },
-            _this = this,
-            _nsls = _source.listNamespaces(true);
-        _res.imports = [];
-        for (var _i = 0; _i < _nsls.length; _i++) {
-           if (typeof _source.directory.namespaces[_nsls[_i]] !== "undefined") {
-               _res.imports.push({
-                   id : _nsls[_i],
-                   url : _source.directory.namespaces[_nsls[_i]]
-               })
-           } 
-        }
+        var _res = {},
+            _this = this;
         _source.forEach(function(_list, _typename) {
             if (typeof _this.types[_typename] !== "undefined") {
                 _res[_this.types[_typename].serialized_name] = _list.map(function(_el) {
@@ -1959,44 +2076,13 @@
                 });
             }
         });
-        return _res;
-    },
-    loadData : function(_url, _callback) {
-        IriSP.jQuery.getJSON(_url, _callback)
-    },
-    deSerialize : function(_data, _source) {
-        if (typeof _data !== "object" || _data === null) {
-            return;
-        }
-        if (typeof _data.imports !== "undefined") {
-            IriSP._(_data.imports).forEach(function(_import) {
-                _source.directory.namespaces[_import.id] = _import.url;
-            })
+        _res.meta = {
+            creator: _source.creator,
+            created: _source.created
         }
-        IriSP._(this.types).forEach(function(_type, _typename) {
-            var _listdata = _data[_type.serialized_name];
-            if (typeof _listdata !== "undefined" && _listdata !== null) {
-                var _list = new IriSP.Model.List(_source.directory);
-                if (_listdata.hasOwnProperty("length")) {
-                    var _l = _listdata.length;
-                    for (var _i = 0; _i < _l; _i++) {
-                        _list.push(_type.deserializer(_listdata[_i], _source));
-                    }
-                } else {
-                    _list.push(_type.deserializer(_listdata, _source));
-                }
-                _source.addList(_typename, _list);
-            }
-        });
-        
-        if (typeof _data.meta !== "undefined" && typeof _data.meta.main_media !== "undefined" && typeof _data.meta.main_media["id-ref"] !== "undefined") {
-            _source.setCurrentMediaId(_data.meta.id);
-        }
-        _source.setDefaultCurrentMedia();
+        return JSON.stringify(_res);
     }
-}
-
-/* LDT Platform Serializer */
+}/* LDT Platform Serializer */
 
 if (typeof IriSP.serializers === "undefined") {
     IriSP.serializers = {}
@@ -2006,7 +2092,6 @@
     types :  {
         media : {
             serialized_name : "medias",
-            model_name : "media",
             deserializer : function(_data, _source) {
                 var _res = new IriSP.Model.Media(_data.id, _source);
                 _res.video = (
@@ -2103,6 +2188,8 @@
             serializer : function(_data, _source) {
                 return {
                     id : _source.unNamespace(_data.id),
+                    begin : _data.begin.milliseconds,
+                    end : _data.end.milliseconds,
                     content : {
                         title : _data.title,
                         description : _data.description
@@ -2114,13 +2201,34 @@
                         "dc:creator" : _data.creator,
                         project : _source.projectId
                     },
-                    tags : IriSP._(_data.tag.id).map(function(_d) {
+                    tags : IriSP._(_data.tag.id).map(function(_id) {
                        return {
                            "id-ref" : _source.unNamespace(_id)
                        } 
                     })
                 }
             }
+        },
+        mashup : {
+            serialized_name : "mashups",
+            deserializer : function(_data, _source) {
+                var _res = new IriSP.Model.Mashup(_data.id, _source);
+                _res.title = _data.meta["dc:title"];
+                _res.description = _data.meta["dc:description"];
+                for (var _i = 0; _i < _data.segments.length; _i++) {
+                    _res.addSegmentById(_data.segments[_i]);
+                }
+                return _res;        
+            },
+            serializer : function(_data, _source) {
+                return {
+                    "dc:title": _data.title,
+                    "dc:description": _data.description,
+                    segments: _data.segments.map(function(_annotation) {
+                        return _source.unNamespace(_id);
+                    })
+                }
+            }
         }
     },
     serialize : function(_source) {
@@ -2133,7 +2241,7 @@
                 });
             }
         });
-        return _res;
+        return JSON.stringify(_res);
     },
     loadData : function(_url, _callback) {
         IriSP.jQuery.getJSON(_url, _callback)
--- a/front_idill/src/player/metadataplayer/Timeline.js	Thu May 24 10:35:27 2012 +0200
+++ b/front_idill/src/player/metadataplayer/Timeline.js	Wed May 30 10:21:36 2012 +0200
@@ -200,7 +200,7 @@
 	var key = this.whichKey(e.which);
 	var time = 0;
 	
-	console.log($(this));
+	// console.log($(this));
 	
 	if(key > -1 && key < 11)
 	{
@@ -264,7 +264,9 @@
 			}
 			else
 			{
-				alert("Unknown gesture type. Operation aborted.");
+				// alert("Unknown gesture type. Operation aborted.");
+				this.removeSearch1Gesture();
+				this.notifySearch1Gesture(typeName, "none");
 			}
 		}
 	}
@@ -730,6 +732,8 @@
 		return;
 	}
 	
+	console.log('(0)');
+	
 	var _this = this;
 	
 	IriSP.jQuery(".search_MBPic").fadeOut(this.markerShowTime, function()
@@ -747,6 +751,7 @@
 		}
 		else
 		{
+			console.log('(1)');
 			// console.log(_this.currentMode);
 			_this.showMarkersSearchByType(type);
 			_this.notifySearch1Gesture(type, "valid");
@@ -756,18 +761,25 @@
 	
 	if(IriSP.jQuery(".search_Marker").length == 0 && type != undefined)
 	{
-		if(type == undefined || !_.include(this.gestures, type))
+		console.log('(2)');
+		this.showMarkersSearchByType(type);
+		_this.removeSearch1Gesture();
+		
+		if(!_.include(this.gestures, type))
 		{
 			this.notifySearch1Gesture(type, "none");
 		}
+		else
+		{
+			_this.notifySearch1Gesture(type, "valid");
+		}
 		// console.log(this.currentMode);
-		this.showMarkersSearchByType(type);
 	}
 }
 
 IriSP.Widgets.Timeline.prototype.freePlayer = function()
 {
-	IriSP.jQuery('body').unbind();
+	IriSP.jQuery('body').unbind('keypress');
 	IriSP.jQuery('.notifications').remove();
 }
 
@@ -777,7 +789,7 @@
 */
 IriSP.Widgets.Timeline.prototype.notifySearch1Gesture = function(gestureName, mode)
 {
-	console.log('C');
+	// console.log('C');
 	if(IriSP.jQuery('#notify_search_1gesture').length > 0)
 	{
 		return;
@@ -791,7 +803,7 @@
 	//On les ajoute à la mosaïque.
 	$('#mainPanel').append(notification_search_1gesture);
 	
-	console.log(this.player.config.gui.zoomTop + " " + this.player.config.gui.zoomLeft);
+	// console.log(this.player.config.gui.zoomTop + " " + this.player.config.gui.zoomLeft);
 	
 	//On calcule leurs coordonnées et dimensions.
 	var notify_width = $('.notifications').width(), notify_height = $('.notifications').height();
@@ -800,7 +812,7 @@
 	
 	if(_.include(this.gestures, gestureName))
 	{
-		IriSP.jQuery('#notify_search_1gesture').css('background-image', 'url("./pictos/big/' + mode + '/' + gestureName.replace('-', '_') + '.png")');
+		IriSP.jQuery('#notify_search_1gesture').css('background-image', 'url("./pictos/big/' + mode + '/' + gestureName + '.png")');
 	}
 	else if(mode == 'none')
 	{
@@ -843,7 +855,7 @@
 */
 IriSP.Widgets.Timeline.prototype.removeSearch1Gesture = function()
 {
-	console.log('R');
-	console.trace();
+	// console.log('R');
+	// console.trace();
 	IriSP.jQuery('#notify_search_1gesture').remove();
 }
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/front_idill/src/search/css/searchCanvas.css	Wed May 30 10:21:36 2012 +0200
@@ -0,0 +1,7 @@
+.canvas
+{
+	position: absolute;
+	background-color: #fff;
+	background: transparent;
+	z-index: 500;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/front_idill/src/search/js/curve.js	Wed May 30 10:21:36 2012 +0200
@@ -0,0 +1,93 @@
+/*
+* 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 : mosaic.js
+ * 
+ * Auteur : alexandre.bastien@iri.centrepompidou.fr
+ * 
+ * Fonctionnalités : Définit la "classe" courbe et définit des fonctions d'intéractions (dessin...).
+ */
+ 
+function curve()
+{
+	tool.fixedDistance = 10;
+	this.path;
+	this.pathStroke;
+	this.lastPoint;
+}
+
+curve.prototype.onMouseDown = function(event)
+{
+	this.pathStroke = new Path();
+	this.path = new Path();
+	
+	this.pathStroke.fillColor = '#366F7A';
+	this.path.fillColor = '#02FEFF';
+	
+	console.log('down');
+};
+
+curve.prototype.onMouseDrag = function(event)
+{
+	//if(event.point.x < 0 || event.point.x > canvasWidth || event.point.y < 0 || event.point.y > canvasHeight)
+		//return;
+	
+	var step = event.delta / 5;
+	var stepStroke = event.delta / 3;
+	step.angle += 90;
+	stepStroke.angle += 90;
+
+	var top = event.point + step;
+	var bottom = event.point - step;
+	
+	var topStroke = event.point + stepStroke;
+	var bottomStroke = event.point - stepStroke;
+
+	this.path.add(top);
+	this.path.insert(0, bottom);
+	this.path.smooth();
+	
+	this.pathStroke.add(topStroke);
+	this.pathStroke.insert(0, bottomStroke);
+	this.pathStroke.smooth();
+	
+	this.lastPoint = event.middlePoint;
+};
+
+curve.prototype.onMouseUp = function(event)
+{
+	this.pathStroke.remove();
+	this.path.remove();
+};
+
+curve.prototype.onKeyDown = function(event)
+{
+	//S'il n'y a rien a colorier, on quitte.
+	if(typeof this.pathStroke === 'undefined' || typeof this.path === 'undefined')
+		return;
+	
+	if(event.key == 'r' || event.key == 'R')
+	{
+		this.pathStroke.fillColor = '#49564F';
+		this.path.fillColor = '#00FE00'
+	}
+	else if(event.key == 'x' || event.key == 'X')
+	{
+		this.pathStroke.fillColor = '#535F6D';
+		this.path.fillColor = '#CCCCCC'
+	}
+	else if(event.key == 'w' || event.key == 'W')
+	{
+		this.pathStroke.fillColor = '#366F7A';
+		this.path.fillColor = '#02FEFF'
+	}
+};
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/front_idill/src/search/js/searchCanvas.js	Wed May 30 10:21:36 2012 +0200
@@ -0,0 +1,121 @@
+function searchCanvas(_canvasTop, _canvasLeft, _canvasWidth, _canvasHeight, _margin_top, _fadeTime, _inMosaic)
+{
+	this.canvasTop = _canvasTop;
+	this.canvasLeft = _canvasLeft;
+	this.canvasWidth = _canvasWidth;
+	this.canvasHeight = _canvasHeight;
+	this.fadeTime = _fadeTime;
+	this.margin_top = _margin_top;
+	
+	//tool.fixedDistance = 10;
+	this.path;
+	this.pathStroke;
+	this.lastPoint;
+	
+	this.inMosaic = _inMosaic;
+	
+	this.hitTool = new paper.Tool();
+	this.hitTool.fixedDistance = 10;
+	this.hitTool.activate();
+}
+
+searchCanvas.prototype.create = function()
+{
+	var _this = this;
+	
+	var canvas = '<canvas id="paperCanvas" width="' + this.canvasWidth + 'px" height="' + this.canvasHeight + 'px" class="canvas"></canvas>';
+	
+	$('body').append(canvas);
+	
+	$('.canvas').css(
+	{
+		top: this.canvasTop,
+		left: this.canvasLeft
+	});
+	
+	if(this.inMosaic)
+	{
+		console.log(this.margin_top);
+		$('.canvas').css(
+		{
+			"margin-top": this.margin_top
+		});
+	}
+	
+	paper.setup('paperCanvas');
+	
+	this.hitTool.onMouseDown = this.onMouseDown;
+	this.hitTool.onMouseDrag = this.onMouseDrag;
+	this.hitTool.onMouseUp = this.onMouseUp;
+	this.hitTool.onKeyDown = this.onKeyDown;
+};
+
+searchCanvas.prototype.leaveSearch = function()
+{
+	$('.canvas').fadeTo(this.fadeTime, 0, function()
+	{
+		$('.canvas').remove();
+	});
+};
+
+searchCanvas.prototype.onMouseDown = function(event)
+{
+	this.pathStroke = new paper.Path();
+	this.path = new paper.Path();
+	
+	this.pathStroke.fillColor = '#366F7A';
+	this.path.fillColor = '#02FEFF';
+	
+	this.pathStroke.add(event.point);
+};
+
+searchCanvas.prototype.onMouseDrag = function(event)
+{
+	var step = event.delta.divide(new paper.Point(4, 4));
+	var stepStroke = event.delta.divide(new paper.Point(2, 2));
+	step.angle += 90;
+	stepStroke.angle += 90;
+
+	var top = event.middlePoint.add(step);
+	var bottom = event.middlePoint.add(step.negate());
+
+	var topStroke = event.middlePoint.add(stepStroke);
+	var bottomStroke = event.middlePoint.add(stepStroke.negate());
+
+	this.path.add(top);
+	this.path.insert(0, bottom);
+    this.path.smooth();
+	
+	this.pathStroke.add(topStroke);
+	this.pathStroke.insert(0, bottomStroke);
+    this.pathStroke.smooth();
+};
+
+searchCanvas.prototype.onMouseUp = function(event)
+{
+	this.pathStroke.remove();
+	this.path.remove();
+};
+
+searchCanvas.prototype.onKeyDown = function(event)
+{
+	//S'il n'y a rien a colorier, on quitte.
+	if(typeof this.pathStroke === 'undefined' || typeof this.path === 'undefined')
+		return;
+	
+	if(event.key == 'r' || event.key == 'R')
+	{
+		this.pathStroke.fillColor = '#49564F';
+		this.path.fillColor = '#00FE00'
+	}
+	else if(event.key == 'x' || event.key == 'X')
+	{
+		this.pathStroke.fillColor = '#535F6D';
+		this.path.fillColor = '#CCCCCC'
+	}
+	else if(event.key == 'w' || event.key == 'W')
+	{
+		this.pathStroke.fillColor = '#366F7A';
+		this.path.fillColor = '#02FEFF'
+	}
+};
\ No newline at end of file
Binary file front_idill/src/snapshots-little/50 shots.png has changed
Binary file front_idill/src/snapshots-little/alger.png has changed
Binary file front_idill/src/snapshots-little/animalz.png has changed
Binary file front_idill/src/snapshots-little/aside.png has changed
Binary file front_idill/src/snapshots-little/deep end dance.png has changed
Binary file front_idill/src/snapshots-little/encontro cotidianos.png has changed
Binary file front_idill/src/snapshots-little/exotica.png has changed
Binary file front_idill/src/snapshots-little/fenella.png has changed
Binary file front_idill/src/snapshots-little/flying lesson.png has changed
Binary file front_idill/src/snapshots-little/i am my mother.png has changed
Binary file front_idill/src/snapshots-little/instrument.png has changed
Binary file front_idill/src/snapshots-little/joudance 2 in asakusa_stage1.png has changed
Binary file front_idill/src/snapshots-little/mue.png has changed
Binary file front_idill/src/snapshots-little/new under the sun.png has changed
Binary file front_idill/src/snapshots-little/nid de lune.png has changed
Binary file front_idill/src/snapshots-little/patria.png has changed
Binary file front_idill/src/snapshots-little/respire.png has changed
Binary file front_idill/src/snapshots-little/sliced.png has changed
Binary file front_idill/src/snapshots-little/spin.png has changed
Binary file front_idill/src/snapshots-little/stronger.png has changed
Binary file front_idill/src/snapshots-little/tank man tango a tianmen memorial.png has changed
Binary file front_idill/src/snapshots-little/the rat.png has changed
Binary file front_idill/src/snapshots-little/vrtti.png has changed
Binary file front_idill/src/snapshots-little/you are you.png has changed
Binary file front_idill/src/snapshots/50 shots.png has changed
Binary file front_idill/src/snapshots/alger.png has changed
Binary file front_idill/src/snapshots/animalz.png has changed
Binary file front_idill/src/snapshots/aside.png has changed
Binary file front_idill/src/snapshots/deep end dance.png has changed
Binary file front_idill/src/snapshots/encontro cotidianos.png has changed
Binary file front_idill/src/snapshots/exotica.png has changed
Binary file front_idill/src/snapshots/fenella.png has changed
Binary file front_idill/src/snapshots/flying lesson.png has changed
Binary file front_idill/src/snapshots/i am my mother.png has changed
Binary file front_idill/src/snapshots/instrument.png has changed
Binary file front_idill/src/snapshots/joudance 2 in asakusa_stage1.png has changed
Binary file front_idill/src/snapshots/mue.png has changed
Binary file front_idill/src/snapshots/new under the sun.png has changed
Binary file front_idill/src/snapshots/nid de lune.png has changed
Binary file front_idill/src/snapshots/patria.png has changed
Binary file front_idill/src/snapshots/respire.png has changed
Binary file front_idill/src/snapshots/sliced.png has changed
Binary file front_idill/src/snapshots/stronger.png has changed
Binary file front_idill/src/snapshots/tank man tango a tianmen memorial.png has changed
Binary file front_idill/src/snapshots/the rat.png has changed
Binary file front_idill/src/snapshots/vrtti.png has changed
Binary file front_idill/src/snapshots/you are you.png has changed