re-enabled traces
authorRaphael Velt <raph.velt@gmail.com>
Tue, 22 May 2012 16:47:35 +0200
changeset 623 5b7d7ab6baff
parent 622 7e5174fe9816
child 624 8ae3d6d7d3c0
re-enabled traces
web/edito-arts-numeriques/config.php
web/player_embed.php
web/polemicaltimeline.php
web/res/js/tracemanager.js
web/res/metadataplayer/Annotation.css
web/res/metadataplayer/Annotation.js
web/res/metadataplayer/AnnotationsList.js
web/res/metadataplayer/Controller.js
web/res/metadataplayer/LdtPlayer-core.js
web/res/metadataplayer/Polemic.js
web/res/metadataplayer/Segments.js
web/res/metadataplayer/Slider.js
web/res/metadataplayer/Tagcloud.js
web/res/metadataplayer/Trace.js
--- a/web/edito-arts-numeriques/config.php	Mon May 21 18:53:02 2012 +0200
+++ b/web/edito-arts-numeriques/config.php	Tue May 22 16:47:35 2012 +0200
@@ -47,5 +47,5 @@
 
     // After the event
 	'metadata'    => "http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/cljson/id/99d311d0-8d5e-11e1-aa20-00145ea4a2be",
-    'pad_url'     => 'http://pads.iri-research.org/p/edito-arts-numeriques?showControls=true&showChat=true&showLineNumbers=true&useMonospaceFont=false'
+//    'pad_url'     => 'http://pads.iri-research.org/p/edito-arts-numeriques?showControls=true&showChat=true&showLineNumbers=true&useMonospaceFont=false'
 );
\ No newline at end of file
--- a/web/player_embed.php	Mon May 21 18:53:02 2012 +0200
+++ b/web/player_embed.php	Tue May 22 16:47:35 2012 +0200
@@ -61,7 +61,11 @@
                 { type: "Arrow" },
                 { type: "Annotation" },
                 { type: "Tweet" },
-                { type: "Mediafragment"}
+                { type: "Mediafragment"},
+                {
+                    type: "Trace",
+                    default_subject: "PolemicTweet-player"
+                }
             ]
         },
         player:{
--- a/web/polemicaltimeline.php	Mon May 21 18:53:02 2012 +0200
+++ b/web/polemicaltimeline.php	Tue May 22 16:47:35 2012 +0200
@@ -121,7 +121,11 @@
                     //foreign_url : "http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/front/player/{{media}}/{{project}}/{{annotationType}}#id={{annotation}}",
                     container: "AnnotationsListContainer"
                 },
-                { type: "Mediafragment"}
+                { type: "Mediafragment"},
+                {
+                    type: "Trace",
+                    default_subject: "PolemicTweet-player"
+                }
             ]
         },
         player:{
--- a/web/res/js/tracemanager.js	Mon May 21 18:53:02 2012 +0200
+++ b/web/res/js/tracemanager.js	Tue May 22 16:47:35 2012 +0200
@@ -1,7 +1,24 @@
 /*
  * Modelled Trace API
+ *
+ * This file is part of ktbs4js.
+ *
+ * ktbs4js is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * ktbs4js is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with ktbs4js.  If not, see <http://www.gnu.org/licenses/>.
+ *
  */
-IriSP.TraceManager = function($) {
+/* FIXME: properly use require.js feature. This will do for debugging in the meantime */
+window.tracemanager = (function($) {
      // If there are more than MAX_FAILURE_COUNT synchronisation
      // failures, then disable synchronisation
      MAX_FAILURE_COUNT = 20;
@@ -74,10 +91,10 @@
          /* Sync mode: delayed, sync (immediate sync), none (no
           * synchronisation with server, the trace has to be explicitly saved
           * if needed */
-         set_sync_mode: function(mode) {
+         set_sync_mode: function(mode, default_subject) {
              this.sync_mode = mode;
              if (! this.isReady && mode !== "none")
-                 this.init();
+                 this.init(default_subject);
              if (mode == 'delayed') {
                  this.start_timer();
              } else {
@@ -120,14 +137,16 @@
          /*
           * Initialize the sync service
           */
-         init: function() {
+         init: function(default_subject) {
              var self = this;
              if (this.isReady)
                  /* Already initialized */
                  return;
+             if (typeof default_subject === 'undefined')
+                 default_subject = 'anonymous';
              if (this.mode == 'GET')
              {
-                 var request=$('<img/>').attr('src', this.url + 'login?userinfo={"name":"ktbs4js"}');
+                 var request=$('<img/>').attr('src', this.url + 'login?userinfo={"default_subject": "' + default_subject + '"}');
                  // Do not wait for the return, assume it is
                  // initialized. This assumption will not work anymore
                  // if login returns some necessary information
@@ -137,7 +156,7 @@
              {
                  $.ajax({ url: this.url + 'login',
                           type: 'POST',
-                          data: 'userinfo={"name":"ktbs4js"}',
+                          data: 'userinfo={"default_subject":"' + default_subject + '"}',
                           success: function(data, textStatus, jqXHR) {
                               self.isReady = true;
                               if (self.buffer.length) {
@@ -195,7 +214,7 @@
           * if needed */
          set_sync_mode: function(mode) {
              if (this.syncservice !== null) {
-                 this.syncservice.set_sync_mode(mode);
+                 this.syncservice.set_sync_mode(mode, this.default_subject);
              }
          },
 
@@ -248,6 +267,9 @@
          },
 
          set_default_subject: function(subject) {
+             // FIXME: if we call this method after the sync_service
+             // init method, then the default_subject will not be
+             // consistent anymore. Maybe we should then call init() again?
              this.default_subject = subject;
          },
 
@@ -434,8 +456,11 @@
              var r = {
                  "@t": (this.trace.shorthands.hasOwnProperty(this.type) ? this.trace.shorthands[this.type] : this.type),
                  "@b": this.begin,
-                 "@s": this.subject
              };
+             // Transmit subject only if different from default_subject
+             if (this.subject !== this.trace.default_subject)
+                 r["@s"] = this.subject;
+
              // Store duration (to save some bytes) and only if it is non-null
              if (this.begin !== this.end)
                  r["@d"] = this.end - this.begin;
@@ -498,8 +523,8 @@
              syncmode = params.syncmode ? params.syncmode : "none";
              default_subject = params.default_subject ? params.default_subject : "default";
              var t = new Trace(url, requestmode);
+             t.set_default_subject(default_subject);
              t.set_sync_mode(syncmode);
-             t.set_default_subject(default_subject);
              this.traces[name] = t;
              return t;
          }
@@ -512,4 +537,4 @@
 
      var tracemanager  = new TraceManager();
      return tracemanager;
- };
+ })(jQuery);
--- a/web/res/metadataplayer/Annotation.css	Mon May 21 18:53:02 2012 +0200
+++ b/web/res/metadataplayer/Annotation.css	Tue May 22 16:47:35 2012 +0200
@@ -4,7 +4,6 @@
     border-color: #b7b7b7;
     padding: 0 1px 1px;
     margin: 0;
-    font-family: Helvetica, Arial, sans-serif;
 }
 
 .Ldt-Annotation-Widget.Ldt-Annotation-ShowTop {
@@ -20,11 +19,15 @@
 
 .Ldt-Annotation-Inner h3 {
     margin: 5px 0;
-    font-size: 15px;
+    font-size: 14px;
     font-weight: bold;
 }
 
-.Ldt-Annotation-Title {
+.Ldt-Annotation-Inner h3.Ldt-Annotation-MashupOrigin {
+    font-size: 12px;
+}
+
+.Ldt-Annotation-Title, .Ldt-Annotation-MashupMedia {
     color: #0068c4;
 }
 
@@ -76,16 +79,39 @@
     display: none;
 }
 
+.Ldt-Annotation-TagTitle {
+    margin: 5px 0 2px; font-size: 12px;
+}
+
 ul.Ldt-Annotation-Tags {
-    list-style: none; padding: 0; margin: 5px 0;
+    display: inline; list-style: none; padding: 0; margin: 5px 0;
+}
+
+li.Ldt-Annotation-TagLabel {
+    display: inline-block; border: none; margin: 0 10px 5px 0; height: 23px; padding: 0 0 0 20px;
+    background: url(img/tag.png) left top no-repeat;
+    cursor: pointer;
 }
 
-.Ldt-Annotation-Tags li {
-    display: inline-block; margin: 0 3px 0 0; padding: 0;
+.Ldt-Annotation-TagLabel span {
+    display: inline-block; font-size: 12px; height: 19px; padding: 4px 5px 0 0; border: none; margin: 0;
+    background: url(img/tag.png) right top no-repeat;
+}
+
+li.Ldt-Annotation-TagLabel:hover {
+    background-position: left -23px;
 }
 
-.Ldt-Annotation-TagLabel {
-    font-weight: bold;
+.Ldt-Annotation-TagLabel:hover span {
+    background-position: right -23px;
+}
+
+.Ldt-Annotation-MashupOrigin {
+    display: none;
+}
+
+.Ldt-Annotation-isMashup .Ldt-Annotation-MashupOrigin {
+    display: block;
 }
 
 .Ldt-Annotation-Empty .Ldt-Annotation-HiddenWhenEmpty {
--- a/web/res/metadataplayer/Annotation.js	Mon May 21 18:53:02 2012 +0200
+++ b/web/res/metadataplayer/Annotation.js	Tue May 22 16:47:35 2012 +0200
@@ -12,26 +12,30 @@
         share_on: "Partager sur",
         watching: "Je regarde ",
         on_site: " sur ",
-        tags: "Mots-clés&nbsp;:"
+        tags: "Mots-clés&nbsp;:",
+        excerpt_from: "Extrait de&nbsp;:"
     },
     "en": {
         share_on: "Share on",
         watching: "I'm watching ",
         on_site: " on ",
-        tags: "Keywords:"
+        tags: "Keywords:",
+        excerpt_from: "Excerpt from:"
     }
 }
 
 IriSP.Widgets.Annotation.prototype.template =
     '<div class="Ldt-Annotation-Widget {{#show_top_border}}Ldt-Annotation-ShowTop{{/show_top_border}}">'
     + '<div class="Ldt-Annotation-Inner Ldt-Annotation-Empty"><div class="Ldt-Annotation-ShareIcons Ldt-Annotation-HiddenWhenMinimized Ldt-Annotation-HiddenWhenEmpty">'
-    + '<a href="#" target="_blank" class="Ldt-Annotation-Share Ldt-Annotation-Fb" title="{{l10n.share_on}} Facebook"></a>'
-    + '<a href="#" target="_blank" class="Ldt-Annotation-Share Ldt-Annotation-Twitter" title="{{l10n.share_on}} Twitter"></a>'
-    + '<a href="#" target="_blank" class="Ldt-Annotation-Share Ldt-Annotation-Gplus" title="{{l10n.share_on}} Google+"></a>'
+    + '<a href="#" target="_blank" class="Ldt-Annotation-Share Ldt-Annotation-Fb Ldt-TraceMe" title="{{l10n.share_on}} Facebook"></a>'
+    + '<a href="#" target="_blank" class="Ldt-Annotation-Share Ldt-Annotation-Twitter Ldt-TraceMe" title="{{l10n.share_on}} Twitter"></a>'
+    + '<a href="#" target="_blank" class="Ldt-Annotation-Share Ldt-Annotation-Gplus Ldt-TraceMe" title="{{l10n.share_on}} Google+"></a>'
     + '</div><h3 class="Ldt-Annotation-HiddenWhenEmpty"><span class="Ldt-Annotation-Title"></span> <span class="Ldt-Annotation-Time">'
     + '( <span class="Ldt-Annotation-Begin"></span> - <span class="Ldt-Annotation-End"></span> )</span></h3>'
+    + '<h3 class="Ldt-Annotation-MashupOrigin Ldt-Annotation-HiddenWhenEmpty">{{l10n.excerpt_from}} <span class="Ldt-Annotation-MashupMedia"></span> <span class="Ldt-Annotation-Time">'
+    + '( <span class="Ldt-Annotation-MashupBegin"></span> - <span class="Ldt-Annotation-MashupEnd"></span> )</span></h3>'
     + '<p class="Ldt-Annotation-Description Ldt-Annotation-HiddenWhenMinimized Ldt-Annotation-HiddenWhenEmpty"></p>'
-    + '<div class="Ldt-Annotation-Tags-Block Ldt-Annotation-HiddenWhenMinimized Ldt-Annotation-HiddenWhenEmpty Ldt-Annotation-NoTags">{{l10n.tags}}<ul class="Ldt-Annotation-Tags"></ul></div></div></div>';
+    + '<div class="Ldt-Annotation-Tags-Block Ldt-Annotation-HiddenWhenMinimized Ldt-Annotation-HiddenWhenEmpty Ldt-Annotation-NoTags"><div class="Ldt-Annotation-TagTitle">{{l10n.tags}}</div><ul class="Ldt-Annotation-Tags"></ul></div></div></div>';
 
 IriSP.Widgets.Annotation.prototype.defaults = {
     annotation_type : "chap",
@@ -78,10 +82,22 @@
     var _tags = _annotation.getTagTexts();
     if (_tags.length) {
         var _html = IriSP._(_tags).map(function(_tag) {
-            return '<li class="Ldt-Annotation-TagLabel">' + _tag + '</li>';
+            return '<li class="Ldt-Annotation-TagLabel"><span>' + _tag + '</span></li>';
         }).join("");
         this.$.find(".Ldt-Annotation-Tags").html(_html);
         this.$.find(".Ldt-Annotation-Tags-Block").removeClass("Ldt-Annotation-NoTags");
+        
+        /* Correct the empty tag bug */
+        this.$.find('.Ldt-Annotation-TagLabel').each(function() {
+            var _el = IriSP.jQuery(this);
+            if (!_el.text().replace(/(^\s+|\s+$)/g,'')) {
+                _el.detach();
+            }
+        });
+    
+        this.$.find('.Ldt-Annotation-TagLabel').click(function() {
+            _this.player.popcorn.trigger("IriSP.search.triggeredSearch", IriSP.jQuery(this).text().replace(/(^\s+|\s+$)/g,''));
+        });
     } else {
         this.$.find(".Ldt-Annotation-Tags-Block").addClass("Ldt-Annotation-NoTags");
     }
@@ -89,6 +105,14 @@
     this.$.find(".Ldt-Annotation-Description").html(_annotation.description);
     this.$.find(".Ldt-Annotation-Begin").html(_annotation.begin.toString());
     this.$.find(".Ldt-Annotation-End").html(_annotation.end.toString());
+    if (_annotation.elementType === "mashedAnnotation") {
+        this.$.find('.Ldt-Annotation-Inner').addClass("Ldt-Annotation-isMashup");
+        this.$.find(".Ldt-Annotation-MashupMedia").html(_annotation.getMedia().title);
+        this.$.find(".Ldt-Annotation-MashupBegin").html(_annotation.annotation.begin.toString());
+        this.$.find(".Ldt-Annotation-MashupEnd").html(_annotation.annotation.end.toString());
+    } else {
+        this.$.find('.Ldt-Annotation-Inner').removeClass("Ldt-Annotation-isMashup");
+    }
     this.$.find(".Ldt-Annotation-Fb").attr("href", "http://www.facebook.com/share.php?" + IriSP.jQuery.param({ u: _url, t: _text }));
     this.$.find(".Ldt-Annotation-Twitter").attr("href", "https://twitter.com/intent/tweet?" + IriSP.jQuery.param({ url: _url, text: _text }));
     this.$.find(".Ldt-Annotation-Gplus").attr("href", "https://plusone.google.com/_/+1/confirm?" + IriSP.jQuery.param({ url: _url, title: _text }));
--- a/web/res/metadataplayer/AnnotationsList.js	Mon May 21 18:53:02 2012 +0200
+++ b/web/res/metadataplayer/AnnotationsList.js	Tue May 22 16:47:35 2012 +0200
@@ -6,6 +6,7 @@
     this.throttledRefresh = IriSP._.throttle(function() {
         _this.refresh(false);
     }, 1500);
+    this.mashupMode = (this.source.currentMedia.elementType === "mashup");
 };
 
 IriSP.Widgets.AnnotationsList.prototype = new IriSP.Widgets.Widget();
@@ -23,7 +24,6 @@
      * e.g. http://ldt.iri.centrepompidou.fr/ldtplatform/ldt/front/player/{{media}}/{{project}}/{{annotationType}}#id={{annotation}}
      */
     foreign_url : "",
-    cinecast_version : false,
     annotation_type : false,
     refresh_interval : 0,
     limit_count : 10,
@@ -34,7 +34,7 @@
     '<div class="Ldt-AnnotationsListWidget">'
     + '<ul class="Ldt-AnnotationsList-ul">'
     + '{{#annotations}}'
-    + '<li id="Ldt-Annotation-li-{{id}}" class="Ldt-AnnotationsList-li Ldt-TraceMe">'
+    + '<li class="Ldt-AnnotationsList-li Ldt-TraceMe" trace-info="annotation-id:{{id}}">'
     + '<div class="Ldt-AnnotationsList-ThumbContainer">'
     + '<a href="{{url}}">'
     + '<img class="Ldt-AnnotationsList-Thumbnail" src="{{thumbnail}}" />'
@@ -50,7 +50,7 @@
     + '{{#tags}}'
     + '{{#.}}'
     + '<li class="Ldt-AnnotationsList-Tag-Li">'
-    + '<div class="Ldt-AnnotationsList-Tag-Div">{{.}}</div>'
+    + '<span>{{.}}</span>'
     + '</li>'
     + '{{/.}}'
     + '{{/tags}}'
@@ -61,12 +61,6 @@
     + '</ul>'
     + '</div>';
 
-IriSP.Widgets.AnnotationsList.prototype.clear = function() {
-};
-
-IriSP.Widgets.AnnotationsList.prototype.clearWidget = function() {
-};
-
 IriSP.Widgets.AnnotationsList.prototype.onSearch = function(searchString) {
     this.searchString = typeof searchString !== "undefined" ? searchString : '';
     var _n = this.refresh(true);
@@ -99,6 +93,27 @@
     }, this.metadata));
 }
 
+IriSP.Widgets.AnnotationsList.prototype.ajaxMashup = function() {
+    var _currentTime = this.player.popcorn.currentTime();
+    if (typeof _currentTime == "undefined") {
+        _currentTime = 0;
+    }
+    var _currentAnnotation = this.source.currentMedia.getAnnotationAtTime(_currentTime * 1000);
+    if (typeof _currentAnnotation !== "undefined" && _currentAnnotation.namespacedId.name !== this.lastMashupAnnotation) {
+        this.lastMashupAnnotation = _currentAnnotation.namespacedId.name;
+        var _currentMedia = _currentAnnotation.getMedia(),
+            _url = Mustache.to_html(this.ajax_url, {
+                media : _currentMedia.namespacedId.name,
+                begin : Math.max(0, _currentAnnotation.annotation.begin.milliseconds - this.ajax_granularity),
+                end : Math.min(_currentMedia.duration.milliseconds, _currentAnnotation.annotation.end.milliseconds + this.ajax_granularity)
+            });
+        console.log("Getting", _url);
+        this.currentSource = this.player.loadMetadata(IriSP._.defaults({
+            "url" : _url
+        }, this.metadata));
+    }
+}
+
 IriSP.Widgets.AnnotationsList.prototype.refresh = function(_forceRedraw) {
     _forceRedraw = (typeof _forceRedraw !== "undefined" && _forceRedraw);
     if (this.currentSource.status !== IriSP.Model._SOURCE_STATUS_READY) {
@@ -109,7 +124,17 @@
     if (typeof _currentTime == "undefined") {
         _currentTime = 0;
     }
-    var _list = this.annotation_type ? this.currentSource.getAnnotationsByTypeTitle(this.annotation_type, true) : this.currentSource.getAnnotations();
+    var _list = this.annotation_type ? this.currentSource.getAnnotationsByTypeTitle(this.annotation_type) : this.currentSource.getAnnotations();
+    if (this.mashupMode) {
+        var _currentAnnotation = this.source.currentMedia.getAnnotationAtTime(_currentTime * 1000);
+        if (typeof _currentAnnotation !== "undefined") {
+            _currentTime = _currentTime - _currentAnnotation.begin.getSeconds() + _currentAnnotation.annotation.begin.getSeconds();
+            var _mediaId = _currentAnnotation.getMedia().namespacedId.name;
+            _list = _list.filter(function(_annotation) {
+                return _annotation.getMedia().namespacedId.name === _mediaId;
+            });
+        }
+    }
     if (this.searchString) {
         _list = _list.searchByTextFields(this.searchString);
     }
@@ -152,7 +177,7 @@
                             )
                     );
                     var _res = {
-                        id : _annotation.id,
+                        id : _annotation.namespacedId.name,
                         title : _annotation.title.replace(_annotation.description,''),
                         description : _annotation.description,
                         begin : _annotation.begin.toString(),
@@ -170,6 +195,14 @@
                 });
     
         this.$.html(_html);
+        
+        /* Correct the empty tag bug */
+        this.$.find('.Ldt-AnnotationsList-Tag-Li').each(function() {
+            var _el = IriSP.jQuery(this);
+            if (!_el.text().replace(/(^\s+|\s+$)/g,'')) {
+                _el.detach();
+            }
+        });
     
         this.$.find('.Ldt-AnnotationsList-Tag-Li').click(function() {
             _this.player.popcorn.trigger("IriSP.search.triggeredSearch", IriSP.jQuery(this).text().replace(/(^\s+|\s+$)/g,''));
@@ -184,9 +217,13 @@
         }
     }
     
-    if (this.ajax_url && this.ajax_granularity) {
-        if (Math.abs(_currentTime - this.lastAjaxQuery) > (this.ajax_granularity / 2000)) {
-            this.ajaxSource();
+    if (this.ajax_url) {
+        if (this.mashupMode) {
+            this.ajaxMashup();
+        } else {
+            if (Math.abs(_currentTime - this.lastAjaxQuery) > (this.ajax_granularity / 2000)) {
+                this.ajaxSource();
+            }
         }
     }
     return _list.length;
@@ -200,8 +237,12 @@
     
     var _this = this;
     
-    if (this.ajax_url && this.ajax_granularity) {
-        this.ajaxSource();
+    if (this.ajax_url) {
+        if (this.mashupMode) {
+            this.ajaxMashup();
+        } else {
+            this.ajaxSource();
+        }
     } else {
         this.currentSource = this.source;
     }
--- a/web/res/metadataplayer/Controller.js	Mon May 21 18:53:02 2012 +0200
+++ b/web/res/metadataplayer/Controller.js	Tue May 22 16:47:35 2012 +0200
@@ -100,7 +100,7 @@
     this.$playButton.click(this.functionWrapper("playHandler"));
     
     this.$.find(".Ldt-Ctrl-Annotate").click(function() {
-        _this.player.popcorn.trigger("IriSP.Player.AnnotateButton.clicked");
+        _this.player.popcorn.trigger("IriSP.CreateAnnotation.toggle");
     });
     this.$.find(".Ldt-Ctrl-SearchBtn").click(this.functionWrapper("searchButtonHandler"));
     
--- a/web/res/metadataplayer/LdtPlayer-core.js	Mon May 21 18:53:02 2012 +0200
+++ b/web/res/metadataplayer/LdtPlayer-core.js	Tue May 22 16:47:35 2012 +0200
@@ -30,6 +30,7 @@
 /* The Metadataplayer Object, single point of entry, replaces IriSP.init_player */
 
 IriSP.Metadataplayer = function(config, video_metadata) {
+    IriSP.log("IriSP.Metadataplayer constructor");
     for (var key in IriSP.guiDefaults) {
         if (IriSP.guiDefaults.hasOwnProperty(key) && !config.gui.hasOwnProperty(key)) {
             config.gui[key] = IriSP.guiDefaults[key]
@@ -48,22 +49,21 @@
 }
 
 IriSP.Metadataplayer.prototype.loadLibs = function() {
-    
-    var $L = $LAB.script(IriSP.getLib("underscore")).script(IriSP.getLib("Mustache")).script(IriSP.getLib("jQuery")).script(IriSP.getLib("swfObject")).wait().script(IriSP.getLib("jQueryUI"));
+    IriSP.log("IriSP.Metadataplayer.prototype.loadLibs");
+    var $L = $LAB
+        .script(IriSP.getLib("underscore"))
+        .script(IriSP.getLib("Mustache"))
+        .script(IriSP.getLib("jQuery"))
+        .script(IriSP.getLib("swfObject"))
+        .wait()
+        .script(IriSP.getLib("jQueryUI"));
 
-    if(this.config.player.type === "jwplayer" || this.config.player.type === "allocine" || this.config.player.type === "dailymotion") {
-        // load our popcorn.js lookalike
+    if (this.config.player.type === "jwplayer" || this.config.player.type === "auto") {
         $L.script(IriSP.getLib("jwplayer"));
-    } else {
-        // load the real popcorn
-        $L.script(IriSP.getLib("popcorn")).script(IriSP.getLib("popcorn.code"));
-        // load plugins if necessary
-        if(this.config.player.type === "youtube") {
-            $L.script(IriSP.getLib("popcorn.youtube"));
-        }
-        if(this.config.player.type === "vimeo"){
-            $L.script(IriSP.getLib("popcorn.vimeo"));
-        }
+    }
+    
+    if (this.config.player.type !== "jwplayer" && this.config.player.type !== "allocine" && this.config.player.type !== "dailymotion") {
+        $L.script(IriSP.getLib("popcorn"));
     }
 
     /* widget specific requirements */
@@ -75,20 +75,23 @@
     }
     
     var _this = this;
-    
+    IriSP.log($L);
     $L.wait(function() {
-        IriSP.jQuery = window.jQuery.noConflict();
-        IriSP._ = window._.noConflict();
-        
-        IriSP.loadCss(IriSP.getLib("cssjQueryUI"))
-        IriSP.loadCss(_this.config.gui.css);
-        
         _this.onLibsLoaded();
-        
     });
 }
 
 IriSP.Metadataplayer.prototype.onLibsLoaded = function() {
+    IriSP.log("IriSP.Metadataplayer.prototype.onLibsLoaded");
+    if (typeof IriSP.jQuery === "undefined" && typeof window.jQuery !== "undefined") {
+        IriSP.jQuery = window.jQuery.noConflict();
+    }
+    if (typeof IriSP._ === "undefined" && typeof window._ !== "undefined") {
+        IriSP._ = window._.noConflict();
+    }
+    IriSP.loadCss(IriSP.getLib("cssjQueryUI"));
+    IriSP.loadCss(this.config.gui.css);
+    
     this.videoData = this.loadMetadata(this.video_metadata);
     this.$ = IriSP.jQuery('#' + this.config.gui.container);
     this.$.css({
@@ -168,10 +171,26 @@
 }
 
 IriSP.Metadataplayer.prototype.configurePopcorn = function() {
+    IriSP.log("IriSP.Metadataplayer.prototype.configurePopcorn");
     var pop,
         ret = this.layoutDivs("video"),
         containerDiv = ret[0],
-        spacerDiv = ret[1];
+        spacerDiv = ret[1],
+        _this = this,
+        _types = {
+            "html5" : /\.(ogg|ogv|webm)$/,
+            "youtube" : /^(https?:\/\/)?(www\.)?youtube\.com/,
+            "dailymotion" : /^(https?:\/\/)?(www\.)?dailymotion\.com/
+        };
+    
+    if (this.config.player.type === "auto") {
+        this.config.player.type = "jwplayer";
+        IriSP._(_types).each(function(_v, _k) {
+            if (_v.test(_this.config.player.video)) {
+                _this.config.player.type = _k
+            }
+        });
+    }
 
     switch(this.config.player.type) {
         /*
@@ -179,15 +198,22 @@
          will contain the video.
          */
         case "html5":
-            var tmpId = Popcorn.guid("video");
-            IriSP.jQuery("#" + containerDiv).append("<video src='" + this.config.player.video + "' id='" + tmpId + "'></video>");
+            var _tmpId = Popcorn.guid("video"),
+                _videoEl = IriSP.jQuery('<video>');
+            
+            _videoEl.attr({
+                "src" : this.config.player.video,
+                "id" : _tmpId
+            })
 
-            if(options.hasOwnProperty("width"))
-                IriSP.jQuery("#" + containerDiv).css("width", this.config.player.width);
-
-            if(options.hasOwnProperty("height"))
-                IriSP.jQuery("#" + containerDiv).css("height", this.config.player.height);
-            pop = Popcorn("#" + tmpId);
+            if(this.config.player.hasOwnProperty("width")) {
+                _videoEl.attr("width", this.config.player.width);
+            }
+            if(this.config.player.hasOwnProperty("height")) {
+                _videoEl.attr("height", this.config.player.height);
+            }
+            IriSP.jQuery("#" + containerDiv).append(_videoEl);
+            pop = Popcorn("#" + _tmpId);
             break;
 
         case "jwplayer":
@@ -208,22 +234,31 @@
             break;
 
         case "youtube":
-            var opts = IriSP.jQuery.extend({}, this.config.player);
-            delete opts.container;
-            opts.controls = 0;
-            opts.autostart = false;
             // Popcorn.youtube wants us to specify the size of the player in the style attribute of its container div.
             IriSP.jQuery("#" + containerDiv).css({
-                width : opts.width + "px",
-                height : opts.height + "px"
-            })
-            pop = Popcorn.youtube("#" + containerDiv, opts.video, opts);
+                width : this.config.player.width + "px",
+                height : this.config.player.height + "px"
+            });
+            var _urlparts = this.config.player.video.split(/[?&]/),
+                _params = {};
+            for (var _j = 1; _j < _urlparts.length; _j++) {
+                var _ppart = _urlparts[_j].split('=');
+                _params[_ppart[0]] = decodeURIComponent(_ppart[1]);
+            }
+            _params.controls = 0;
+            _params.modestbranding = 1;
+            _url = _urlparts[0] + '?' + IriSP.jQuery.param(_params);
+            pop = Popcorn.youtube("#" + containerDiv, _url);
             break;
 
         case "dailymotion":
             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);
@@ -270,7 +305,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) {
@@ -285,13 +320,25 @@
     }
 }
 
+IriSP._cssCache = [];
+
 IriSP.loadCss = function(_cssFile) {
-    IriSP.jQuery("<link>", {
-        rel : "stylesheet",
-        type : "text/css",
-        href : _cssFile
-    }).appendTo('head');
-}/* wrapper that simulates popcorn.js because
+    if (IriSP._(IriSP._cssCache).indexOf(_cssFile) === -1) {
+        IriSP.jQuery("<link>", {
+            rel : "stylesheet",
+            type : "text/css",
+            href : _cssFile
+        }).appendTo('head');
+        IriSP._cssCache.push(_cssFile);
+    }
+}
+
+IriSP.log = function() {
+    if (typeof console !== "undefined" && typeof IriSP.logging !== "undefined" && IriSP.logging) {
+        console.log.apply(console, arguments);
+    }
+}
+/* wrapper that simulates popcorn.js because
    popcorn is a bit unstable at the time */
 
 IriSP.PopcornReplacement = {  
@@ -319,7 +366,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 
@@ -582,6 +629,7 @@
     this.directory = _directory;
     this.idIndex = [];
     if (typeof _directory == "undefined") {
+        console.trace();
         throw "Error : new IriSP.Model.List(directory): directory is undefined";
     }
 }
@@ -589,15 +637,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) {
@@ -625,6 +665,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) {
@@ -757,7 +803,28 @@
  */
 
 IriSP.Model.Time = function(_milliseconds) {
-    this.milliseconds = parseInt(typeof _milliseconds !== "undefined" ? _milliseconds : 0);
+    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);
+            break;
+        case "number":
+            this.milliseconds = _milliseconds;
+            break;
+        case "object":
+            this.milliseconds = parseFloat(_milliseconds.valueOf());
+            break;
+        default:
+            this.milliseconds = 0;
+    }
+    if (this.milliseconds === NaN) {
+        this.milliseconds = _ante;
+    }
 }
 
 IriSP.Model.Time.prototype.setSeconds = function(_seconds) {
@@ -777,6 +844,10 @@
     } 
 }
 
+IriSP.Model.Time.prototype.add = function(_milliseconds) {
+    this.milliseconds += new IriSP.Model.Time(_milliseconds).milliseconds;
+}
+
 IriSP.Model.Time.prototype.valueOf = function() {
     return this.milliseconds;
 }
@@ -893,13 +964,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) {
@@ -939,11 +1021,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) {
@@ -974,6 +1056,106 @@
     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(_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(_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);
+
+IriSP.Model.MashedAnnotation.prototype.getMedia = function() {
+    return this.annotation.getReference("media");
+}
+
+IriSP.Model.MashedAnnotation.prototype.getAnnotationType = function() {
+    return this.annotation.getReference("annotationType");
+}
+
+IriSP.Model.MashedAnnotation.prototype.getTags = function() {
+    return this.annotation.getReference("tag");
+}
+
+IriSP.Model.MashedAnnotation.prototype.getTagTexts = function() {
+    return this.annotation.getTags().getTitles();
+}
+
+/* */
+
+IriSP.Model.Mashup = function(_id, _source) {
+    IriSP.Model.Element.call(this, _id, _source);
+    this.elementType = 'mashup';
+    this.duration = new IriSP.Model.Time();
+    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) {
+    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() {
+    return this.segments;
+}
+
+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) {
@@ -1064,7 +1246,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);
     }
 }
 
@@ -1108,7 +1290,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);
@@ -1135,6 +1316,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);
@@ -1201,18 +1392,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) {
@@ -1237,13 +1417,9 @@
         jQueryUI : "jquery-ui.min.js",
         swfObject : "swfobject.js",
         cssjQueryUI : "jquery-ui.css",
-        popcorn : "popcorn.js",
+        popcorn : "popcorn-complete.min.js",
         jwplayer : "jwplayer.js",
         raphael : "raphael-min.js",
-        "popcorn.mediafragment" : "popcorn.mediafragment.js",
-        "popcorn.code" : "popcorn.code.js",
-        "popcorn.jwplayer" : "popcorn.jwplayer.js",
-        "popcorn.youtube" : "popcorn.youtube.js",
         tracemanager : "tracemanager.js"
     },
     locations : {
@@ -1385,7 +1561,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();
 }
 
 /**
@@ -1434,9 +1611,15 @@
         }
     }
 
-    window.onReady = IriSP.wrap(this, this.ready);
-    window.onAllocineStateChange = IriSP.wrap(this, this.stateHandler);
-    window.onTime = IriSP.wrap(this, this.progressHandler);
+    window.onReady = function() {
+        _this.ready();
+    };
+    window.onAllocineStateChange = function(_state) {
+        _this.stateHandler(_state)
+    }
+    window.onTime = function(_progress) {
+        _this.progressHandler(_progress)
+    };
     
     var _flashVars = {
         "streamFMS" : true,
@@ -1529,13 +1712,16 @@
 
 /** jwplayer player wrapper */
 IriSP.PopcornReplacement.dailymotion = function(container, options) {
-    console.log("Calling");
-    /* appel du parent pour initialiser les structures communes à tous les players */
+    /* Appel du constructeur de la classe parente */
     IriSP.PopcornReplacement.player.call(this, container, options);   
     
     var _this = this;
 
-    /* Définition des fonctions de l'API -  */
+    /* 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() {
@@ -1596,10 +1782,20 @@
             }
         },
     }
-
-    window.onDailymotionPlayerReady = IriSP.wrap(this, this.ready);
-    window.onDailymotionStateChange = IriSP.wrap(this, this.stateHandler);
-    window.onDailymotionVideoProgress = IriSP.wrap(this, this.progressHandler);
+    
+    /* Dailymotion utilise un système de fonctions référencées dans
+     * des variables globales pour la gestion des événements.
+     */
+    
+    window.onDailymotionPlayerReady = function() {
+        _this.onReady();
+    };
+    window.onDailymotionStateChange = function(_state) {
+        _this.onStateChange(_state);
+    }
+    window.onDailymotionVideoProgress = function(_progress) {
+        _this.onProgress(_progress);
+    }
 
     var params = {
         "allowScriptAccess" : "always",
@@ -1614,7 +1810,7 @@
 
 IriSP.PopcornReplacement.dailymotion.prototype = new IriSP.PopcornReplacement.player("", {});
 
-IriSP.PopcornReplacement.dailymotion.prototype.ready = function() {
+IriSP.PopcornReplacement.dailymotion.prototype.onReady = function() {
     
     this.player = document.getElementById(this.container);
     
@@ -1625,14 +1821,14 @@
     this.callbacks.onReady();
 };
 
-IriSP.PopcornReplacement.dailymotion.prototype.progressHandler = function(progressInfo) {
+IriSP.PopcornReplacement.dailymotion.prototype.onProgress = function(progressInfo) {
     
     this.callbacks.onTime({
         position: progressInfo.mediaTime
     });
 }
 
-IriSP.PopcornReplacement.dailymotion.prototype.stateHandler = function(state) {
+IriSP.PopcornReplacement.dailymotion.prototype.onStateChange = function(state) {
     
     switch(state) {
         case 1:
@@ -1648,12 +1844,6 @@
                 position: this.player.getCurrentTime()
             });
             break;
-
-        /*
-        case 5:
-            this.callbacks.onReady();
-            break;
-        */
     }
     
 };/* To wrap a player the develop should create a new class derived from 
@@ -1684,148 +1874,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) {
@@ -1833,44 +2051,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 = {}
@@ -1880,7 +2067,6 @@
     types :  {
         media : {
             serialized_name : "medias",
-            model_name : "media",
             deserializer : function(_data, _source) {
                 var _res = new IriSP.Model.Media(_data.id, _source);
                 _res.video = (
@@ -1977,6 +2163,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
@@ -1988,13 +2176,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) {
@@ -2007,7 +2216,7 @@
                 });
             }
         });
-        return _res;
+        return JSON.stringify(_res);
     },
     loadData : function(_url, _callback) {
         IriSP.jQuery.getJSON(_url, _callback)
--- a/web/res/metadataplayer/Polemic.js	Mon May 21 18:53:02 2012 +0200
+++ b/web/res/metadataplayer/Polemic.js	Tue May 22 16:47:35 2012 +0200
@@ -155,7 +155,7 @@
             
             function displayElement(_x, _y, _color, _id, _title) {
                 _html += Mustache.to_html(
-                    '<div class="Ldt-Polemic-TweetDiv" annotation-id="{{id}}" tweet-title="{{title}}" pos-x="{{posx}}" pos-y="{{top}}" polemic-color="{{color}}"'
+                    '<div class="Ldt-Polemic-TweetDiv Ldt-TraceMe" trace-info="annotation-id:{{id}}" annotation-id="{{id}}" tweet-title="{{title}}" pos-x="{{posx}}" pos-y="{{top}}" polemic-color="{{color}}"'
                     + ' style="width: {{width}}px; height: {{height}}px; top: {{top}}px; left: {{left}}px; background: {{color}}"></div>',
                 {
                     id: _id,
@@ -173,13 +173,13 @@
                 var _y = _this.height;
                 _slice.annotations.forEach(function(_annotation) {
                     _y -= _this.element_height;
-                    displayElement(_x, _y, _this.defaultcolor, _annotation.id, _annotation.title);
+                    displayElement(_x, _y, _this.defaultcolor, _annotation.namespacedId.name, _annotation.title);
                 });
                 IriSP._(_slice.polemicStacks).forEach(function(_annotations, _j) {
                     var _color = _this.polemics[_j].color;
                     _annotations.forEach(function(_annotation) {
                         _y -= _this.element_height;
-                        displayElement(_x, _y, _color, _annotation.id, _annotation.title);
+                        displayElement(_x, _y, _color, _annotation.namespacedId.name, _annotation.title);
                     });
                 });
                 _x += _this.element_width;
@@ -226,7 +226,7 @@
             
         function displayStackElement(_x, _y, _h, _color, _nums, _begin, _end) {
             _html += Mustache.to_html(
-                '<div class="Ldt-Polemic-TweetDiv" pos-x="{{posx}}" pos-y="{{top}}" annotation-counts="{{nums}}" begin-time="{{begin}}" end-time="{{end}}"'
+                '<div class="Ldt-Polemic-TweetDiv Ldt-TraceMe" trace-info="annotation-block,time:{{begin}}" pos-x="{{posx}}" pos-y="{{top}}" annotation-counts="{{nums}}" begin-time="{{begin}}" end-time="{{end}}"'
                 + ' style="width: {{width}}px; height: {{height}}px; top: {{top}}px; left: {{left}}px; background: {{color}}"></div>',
             {
                 nums: _nums,
--- a/web/res/metadataplayer/Segments.js	Mon May 21 18:53:02 2012 +0200
+++ b/web/res/metadataplayer/Segments.js	Tue May 22 16:47:35 2012 +0200
@@ -19,7 +19,7 @@
 
 IriSP.Widgets.Segments.prototype.template =
     '<div class="Ldt-Segments-List">{{#segments}}'
-    + '<div class="Ldt-Segments-Segment" segment-id="{{id}}" segment-text="{{text}}" segment-color="{{color}}" center-pos="{{center}}" begin-seconds="{{beginseconds}}"'
+    + '<div class="Ldt-Segments-Segment Ldt-TraceMe" trace-info="segment-id:{{id}}" segment-id="{{id}}" segment-text="{{text}}" segment-color="{{color}}" center-pos="{{center}}" begin-seconds="{{beginseconds}}"'
     + 'style="left:{{left}}px; width:{{width}}px; background:{{color}}"></div>'
     + '{{/segments}}</div>'
     + '<div class="Ldt-Segments-Position"></div>';
--- a/web/res/metadataplayer/Slider.js	Mon May 21 18:53:02 2012 +0200
+++ b/web/res/metadataplayer/Slider.js	Tue May 22 16:47:35 2012 +0200
@@ -31,9 +31,9 @@
         range: "min",
         value: 0,
         min: 0,
-        max: this.source.getDuration().getSeconds(),
+        max: this.source.getDuration().milliseconds,
         slide: function(event, ui) {
-            _this.player.popcorn.currentTime(ui.value);
+            _this.player.popcorn.currentTime(ui.value / 1000);
             _this.player.popcorn.trigger("IriSP.Mediafragment.setHashToTime");
         }
     });
@@ -51,9 +51,9 @@
 };
 
 IriSP.Widgets.Slider.prototype.onTimeupdate = function() {
-    var _time = this.player.popcorn.currentTime();
+    var _time = 1000 * this.player.popcorn.currentTime();
     this.$slider.slider("value",_time);
-    this.player.popcorn.trigger("IriSP.Arrow.updatePosition",{widget: this.type, time: 1000 * _time});
+    this.player.popcorn.trigger("IriSP.Arrow.updatePosition",{widget: this.type, time: _time});
 }
 
 IriSP.Widgets.Slider.prototype.onMouseover = function() {
--- a/web/res/metadataplayer/Tagcloud.js	Mon May 21 18:53:02 2012 +0200
+++ b/web/res/metadataplayer/Tagcloud.js	Tue May 22 16:47:35 2012 +0200
@@ -7,7 +7,7 @@
 
 IriSP.Widgets.Tagcloud.prototype.template =
     '<div class="Ldt-Tagcloud-Container"><ul class="Ldt-Tagcloud-List">'
-    + '{{#words}}<li class="Ldt-Tagcloud-item" content="{{word}}" style="font-size: {{size}}px">{{word}}</li>{{/words}}'
+    + '{{#words}}<li class="Ldt-Tagcloud-item Ldt-TraceMe" trace-info="tag:{{word}}" content="{{word}}" style="font-size: {{size}}px">{{word}}</li>{{/words}}'
     + '</ul></div>';
 
 IriSP.Widgets.Tagcloud.prototype.defaults = {
@@ -66,6 +66,9 @@
         })
         .first(this.tag_count)
         .value();
+    if (!_words.length) {
+        return;
+    }
     var _max = _words[0].count,
         _min = Math.min(_words[_words.length - 1].count, _max - 1),
         _scale = (this.max_font_size - this.min_font_size) / Math.sqrt(_max - _min);
--- a/web/res/metadataplayer/Trace.js	Mon May 21 18:53:02 2012 +0200
+++ b/web/res/metadataplayer/Trace.js	Tue May 22 16:47:35 2012 +0200
@@ -20,7 +20,6 @@
   }
   var _this = this,
     _listeners = {
-        "IriSP.createAnnotationWidget.addedAnnotation" : 0,
         "IriSP.search.open" : 0,
         "IriSP.search.closed" : 0,
         "IriSP.search" : 0,
@@ -46,72 +45,69 @@
         }
         _this.player.popcorn.listen(_listener, _f);
     });
-    this.player.popcorn.listen("timeupdate", IriSP._.throttle(function(_arg) {
-        _this.eventHandler(_listener, _arg);
-    }));
     
     this.tracer = window.tracemanager.init_trace("test", {
         url: this.url,
         requestmode: this.requestmode,
         syncmode: this.syncmode
     });
-    this.tracer.set_default_subject("metadataplayer");
     this.tracer.trace("StartTracing", {});
     
     this.mouseLocation = '';
-    IriSP.jQuery(".Ldt-Widget").bind("click mouseover mouseout dragstart dragstop", function(_e) {
-        var _widget = IriSP.jQuery(this).attr("widget-type"),
-            _class = _e.target.className;
-        var _data = {
-            "type": _e.type,
-            "x": _e.clientX,
-            "y": _e.clientY,
-            "widget": _widget
+    IriSP.jQuery(".Ldt-Widget").bind("click mouseover mouseout", function(_e) {
+        var _target = IriSP.jQuery(_e.target);
+
+        while (!_target.hasClass("Ldt-TraceMe") && !_target.hasClass("Ldt-Widget") && _target.length) {
+            _target = _target.parent();
         }
-        if (typeof _class == "string" && _class.indexOf('Ldt-TraceMe') != -1) {
-            var _name = _e.target.localName,
-                _id = _e.target.id,
-                _text = _e.target.textContent.trim(),
-                _title = _e.target.title,
-                _value = _e.target.value;
-            _data.target = _name + (_id.length ? '#' + IriSP.jqEscape(_id) : '') + (_class.length ? ('.' + IriSP.jqEscape(_class).replace(/\s/g,'.')).replace(/\.Ldt-(Widget|TraceMe)/g,'') : '');
-            if (typeof _title == "string" && _title.length && _title.length < 140) {
-                _data.title = _title;
-            }
-            if (typeof _text == "string" && _text.length && _text.length < 140) {
-                _data.text = _text;
-            }
-            if (typeof _value == "string" && _value.length) {
-                _data.value = _value;
-            }
-            this.player.popcorn.trigger('IriSP.TraceWidget.MouseEvents', _data);
-        } else {
-            //console.log(_e.type+','+_this.mouseLocation+','+_widget);
-            if (_e.type == "mouseover") {
-                if (_this.mouseLocation != _widget) {
+        
+        var _widget = IriSP.jQuery(this).attr("widget-type"),
+            _data = {
+                "type": _e.type,
+                "x": _e.clientX,
+                "y": _e.clientY,
+                "widget": _widget
+            },
+            _targetEl = _target[0],
+            _class = _targetEl.className,
+            _name = _targetEl.localName,
+            _id = _targetEl.id,
+            _value = _targetEl.value,
+            _traceInfo = _target.attr("trace-info"),
+            _lastTarget = _name + (_id && _id.length ? '#' + IriSP.jqEscape(_id) : '') + (_class && _class.length ? ('.' + IriSP.jqEscape(_class).replace(/\s/g,'.')).replace(/\.Ldt-(Widget|TraceMe)/g,'') : '');
+        _data.target = _lastTarget
+        if (typeof _traceInfo == "string" && _traceInfo.length && _traceInfo.length < 140) {
+            _data.traceInfo = _traceInfo;
+            _lastTarget += ( ";" + _traceInfo );
+        }
+        if (typeof _value == "string" && _value.length) {
+            _data.value = _value;
+        }
+        switch(_e.type) {
+            case "mouseover":
+                if (_this.lastTarget != _lastTarget) {
                     _this.player.popcorn.trigger('IriSP.TraceWidget.MouseEvents', _data);
                 } else {
                     if (typeof _this.moTimeout != "undefined") {
                         clearTimeout(_this.moTimeout);
-                        delete _this.moTimeout;
+                        _this.moTimeout = undefined;
                     }
                 }
-            }
-            if (_e.type == "click") {
-                _this.player.popcorn.trigger('IriSP.TraceWidget.MouseEvents', _data);
-            }
-            if (_e.type == "mouseout") {
+            break;
+            case "mouseout":
                 if (typeof _this.moTimeout != "undefined") {
                     clearTimeout(_this.moTimeout);
                 }
                 _this.moTimeout = setTimeout(function() {
-                   if (_data.widget != _this.mouseLocation) {
+                   if (_lastTarget != _this.lastTarget) {
                        _this.player.popcorn.trigger('IriSP.TraceWidget.MouseEvents', _data);
                    }
                 },100);
-            }
+            break;
+            default:
+                _this.player.popcorn.trigger('IriSP.TraceWidget.MouseEvents', _data);
         }
-        _this.mouseLocation = _widget;
+        _this.lastTarget = _lastTarget;
     });
 }