integration/js/editor.js
author veltr
Tue, 06 Nov 2012 11:01:27 +0100
changeset 32 47f9a2d63a0a
parent 29 5ce5e26091ea
child 39 d3d8a88878ed
permissions -rw-r--r--
Various UI improvements


IriSP.hc_messages = {
    duration_ : "Durée :",
    edit_segment: "Éditer le segment",
    segment_down: "Descendre le segment",
    segment_up: "Remonter le segment",
    delete_segment: "Supprimer le segment"
}

IriSP.Hashcut = function(options) {
    
    
    /* Load Media List */
    
    var directory = new IriSP.Model.Directory(),
        project = directory.remoteSource({
            url: options.url,
            serializer: IriSP.serializers.medialist
        }),
        mashup = new IriSP.Model.Mashup(false, project),
        mediatemplate = _.template('<li class="item-video" data-media-id="<%= id %>"><img src="<%= thumbnail %>" alt="<%= title %>" />'
            + '<span class="video-info"><span class="title-video"><%= title %></span><span class="author"><%= description %></span>'
            + '<span class="time-length"><%= IriSP.hc_messages.duration_ %> <span><%= duration.toString() %></span></span></span></li>'),
        segmenttemplate = _.template('<li class="item-video" data-segment-id="<%= annotation.id %>" data-media-id="<%= annotation.getMedia().id %>">'
            + '<img src="<%= annotation.getMedia().thumbnail %>" alt="<%= annotation.getMedia().title %>" />'
            + '<span class="video-info"><span class="title-video"><%= annotation.getMedia().title %></span>'
            + '<span class="subtitle"><%= annotation.title %></span><span class="duration"><%= annotation.begin.toString() %> - <%= annotation.end.toString() %> (<%= annotation.getDuration().toString() %>)</span>'
            + '<ul class="tools"><li><a class="edit" href="#" title="<%= IriSP.hc_messages.edit_segment %>"></a></li><li><a class="bottom" href="#" title="<%= IriSP.hc_messages.segment_down %>"></a></li>'
            + '<li><a class="top" href="#" title="<%= IriSP.hc_messages.segment_up %>"></a></li><li><a class="delete" href="#" title="<%= IriSP.hc_messages.delete_segment %>"></a></li></ul></span></li>'),
        viztemplate = _.template('<div class="frise-segment" data-segment-id="<%= segmentid %>" style="background-color:<%= color %>; left:<%= left %>%; width:<%= width %>%;"></div>'),
        intervaltemplate = _.template('<span class="frise-indication" style="left:<%= left %>%;"><%= time.toString() %></span>'),
        mediasegmenttemplate = _.template('<div class="media-segments-list"><div class="media-segment">'
            + '<div class="media-section media-segment-section" style="left:<%= left %>px; width:<%= width %>px; background:<%= annotation.getMedia().color %>"></div>'
            + '<div class="media-section media-current-section" style="left:<%= currentleft %>px; width:<%= currentwidth %>px;"><div class="media-current-section-inner"></div></div>'
            + '<div class="popin media-segment-popin" style="left:<%= popleft %>px"><img style="left:<%= pointerpos %>px;" class="pointer" src="img/popin-triangle.png" alt="" /><div class="popin-content">'
            + '<h3><%= annotation.title %></h3><a href="#" class="button reprendre-segment" data-segment-id="<%= annotation.id %>">Cloner le segment</a>'
            + '<p>De: <span><%= annotation.begin.toString() %></span> à <span><%= annotation.end.toString() %></span> (durée: <span><%= annotation.getDuration().toString() %></span>)</p>'
            + '</div></div></div></div>');

    /* Fill left column with Media List */

    project.onLoad(function() {
        var html = '';
        project.getMedias().forEach(function(_m) {
            html += mediatemplate(_m);
        });
        $(".col-left .list-video").html(html);
    });
    
    /* Search Media with left column form */
    
    $(".col-left input").on("keyup change input paste", function() {
        var val = $(this).val();
        if (val) {
            var find = IriSP.Model.regexpFromTextOrArray(val, true),
                replace = IriSP.Model.regexpFromTextOrArray(val, false);
        }
        $(".col-left .item-video").each(function() {
            var li = $(this),
                title = $(this).find(".title-video"),
                titletext = title.text();
            if (val && find.test(titletext)) {
                title.html(titletext.replace(replace, '<span style="background: yellow;">$1</span>'));
                li.show();
            } else {
                title.text(titletext);
                if (val) {
                    li.hide();
                } else {
                    li.show();
                }
            }
        })
    });
    
    /* Fill right column when mashup is updated */
   
    function setPointerToCurrentAnnotation() {
        if (mashupCurrentAnnotation) {
            var p = (mashupCurrentAnnotation.begin + mashupCurrentAnnotation.end) / (2 * mashup.duration);
            $(".mashup-description .pointer").css("left", (100 * p) + "%");
        }
    }
    
    function updateMashupUI() {
        var listhtml = '', vizhtml = '', t = 0, k = mashup.duration ? (100 / mashup.duration) : 0;
        mashup.segments.forEach(function(_s) {
            listhtml += segmenttemplate(_s);
            var vizdata = {
                left: k * t,
                width: k * _s.duration,
                color: _s.getMedia().color,
                segmentid: _s.annotation.id
            }
            vizhtml += viztemplate(vizdata);
            t += _s.duration.milliseconds;
        });
        
        var intervals = [ 1000, 2000, 5000, 10000, 30000, 60000, 120000, 300000, 600000, 900000, 1800000, 3600000, 7200000 ];
        
        function createIntervals(maxn) {
            for (var i = 0; i < intervals.length; i++) {
                if (mashup.duration / intervals[i] <= maxn) {
                    var html = '';
                    for (var j = intervals[i]; j < mashup.duration; j += intervals[i]) {
                        html += intervaltemplate({ left: k * j, time: new IriSP.Model.Time(j) });
                    }
                    return html;
                }
            }
            return "";
        }
        
        $(".col-right .list-video").html(listhtml).find(".item-video:last-child .bottom, .item-video:first-child .top").addClass("disable");
        $(".mashup-total-duration").text(mashup.duration.toString());
        $(".frise-segments").html(vizhtml);
        $(".col-right .frise-indications").html(createIntervals(4));
        $(".bloc-pvw .frise-indications").html(createIntervals(8));
        highlightCurrentSegment();
        if (currentMedia === mashup) {
            $(".Ldt-Ctrl-Time-Total").text(currentMedia.duration.toString());
            if (mashupTimecode > mashup.duration) {
                mashup.setCurrentTime(mashup.duration);
            }
            changeCurrentAnnotation();
            setPointerToCurrentAnnotation();
        }
    }
    
    mashup.on("change",updateMashupUI);
    
    /* Slider */
   
    var timeSlider = $(".Ldt-Slider"),
        timeSliderContainer = $(".Ldt-Slider-Container"),
        slidersRange = 920;
    timeSlider.slider({
        range: "min",
        value: 0,
        min: 0,
        max: slidersRange,
        slide: function(event, ui) {
            if (currentMedia) {
                var t = currentMedia.duration * ui.value / slidersRange;
                currentMedia.setCurrentTime(t);
            }
        }
    });
    
    var timeSliderHandle = timeSlider.find('.ui-slider-handle'),
        timeSliderMaximized = false,
        timeSliderTimeoutId = false,
        timeSliderMinimizedHeight = 4,
        timeSliderMaximizedHeight = 10,
        timeSliderTimeoutDuration = 1500,
        timeTooltip = $(".Ldt-Slider-Time");
    
    timeSliderContainer.css(calculateSliderCss(timeSliderMinimizedHeight));
    timeSliderHandle.css(calculateHandleCss(timeSliderMinimizedHeight));
    
    function timeSliderMouseOver() {
        if (timeSliderTimeoutId) {
            window.clearTimeout(timeSliderTimeoutId);
            timeSliderTimeoutId = false;
        }
        if (!timeSliderMaximized) {
           timeSliderAnimateToHeight(timeSliderMaximizedHeight);
           timeSliderMaximized = true;
        }
    }
    
    function timeSliderMouseOut() {
        timeTooltip.hide();
        if (timeSliderTimeoutId) {
            clearTimeout(timeSliderTimeoutId);
            timeSliderTimeoutId = false;
        }
        timeSliderTimeoutId = setTimeout(function() {
            if (timeSliderMaximized) {
                timeSliderAnimateToHeight(timeSliderMinimizedHeight);
                timeSliderMaximized = false;
            }
            timeSliderTimeoutId = false;
        }, timeSliderTimeoutDuration);
    }
    
    timeSliderContainer
        .mouseover(function() {
            timeTooltip.show();
            timeSliderMouseOver();
        })
        .mouseout(timeSliderMouseOut);
    timeSlider.mousemove(function(_e) {
            var _x = _e.pageX - timeSlider.offset().left,
                _t = new IriSP.Model.Time(
                );
            timeTooltip.text(_t.toString()).css("left",_x);
        });
    
    $(".Ldt-Ctrl").mouseover(timeSliderMouseOver).mouseout(timeSliderMouseOut);
    
    function timeSliderAnimateToHeight(_height) {
        timeSliderContainer.stop().animate(
            calculateSliderCss(_height),
            500,
            function() {
                IriSP.jQuery(this).css("overflow","visible");
            });
        timeSliderHandle.stop().animate(
            calculateHandleCss(_height),
            500,
            function() {
                IriSP.jQuery(this).css("overflow","visible");
            });
    }

    function calculateSliderCss(_size) {
        return {
            height: _size + "px",
            "margin-top": (timeSliderMinimizedHeight - _size) + "px"
        };
    }

    function calculateHandleCss(_size) {
        return {
            height: (2 + _size) + "px",
            width: (2 + _size) + "px",
            "margin-left": -Math.ceil(2 + _size / 2) + "px" 
        }
    }
    
    /* Controller Widget */
   
    var volBlock = $(".Ldt-Ctrl-Volume-Control");
    
    $('.Ldt-Ctrl-Sound')
        .click(function() {
            if (currentMedia) {
                currentMedia.setMuted(!currentMedia.getMuted());
            }
        })
        .mouseover(function() {
            volBlock.show();
        })
        .mouseout(function() {
            volBlock.hide();
        });
    volBlock.mouseover(function() {
        volBlock.show();
    }).mouseout(function() {
        volBlock.hide();
    });
    
    var volBar = $(".Ldt-Ctrl-Volume-Bar");
    
    function ctrlVolumeUpdater() {
        if (currentMedia) {
            var _muted = currentMedia.getMuted(),
                _vol = currentMedia.getVolume();
            if (_vol === false) {
                _vol = .5;
            }
            var _soundCtl = $(".Ldt-Ctrl-Sound");
            _soundCtl.removeClass("Ldt-Ctrl-Sound-Mute Ldt-Ctrl-Sound-Half Ldt-Ctrl-Sound-Full");
            if (_muted) {        
                _soundCtl.attr("title", "Activer le son")
                    .addClass("Ldt-Ctrl-Sound-Mute");    
            } else {
                _soundCtl.attr("title", "Couper le son")
                    .addClass(_vol < .5 ? "Ldt-Ctrl-Sound-Half" : "Ldt-Ctrl-Sound-Full" )
            }
            volBar.slider("value", _muted ? 0 : 100 * _vol);
            volBar.attr("title",'Volume : ' + Math.floor(100 * _vol) + '%');
        }
    }
    
    volBar.slider({
        slide: function(event, ui) {
            if (currentMedia) {
                currentMedia.setVolume(ui.value / 100);
            }
        }
    });
    
    $(".Ldt-Ctrl-Play").click(function() {
        if (currentMedia) {
            if (currentMedia.getPaused()) {        
                currentMedia.play();
            } else {
                currentMedia.pause();
            }
        }
    });
    
    $(".Ldt-Ctrl-SetIn").click(function() {
        if (currentMedia && currentSegment) {
            currentSegment.setBegin(currentMedia.getCurrentTime());
        }
    });
    $(".Ldt-Ctrl-SetOut").click(function() {
        if (currentMedia && currentSegment) {
            currentSegment.setEnd(currentMedia.getCurrentTime());
        }
    });
    
    /* Slice Widget */
   
    var sliceSlider = $(".Ldt-Slice"),
        sliceStartTime;
    
    sliceSlider.slider({
        range: true,
        values: [0, slidersRange],
        min: 0,
        max: slidersRange,
        start: function() {
            if (currentMedia) {
                if (!currentMedia.getPaused()) {
                    currentMedia.pause();
                }
            }
        },
        slide: function(event, ui) {
            if (currentMedia && currentSegment) {
                var t = currentMedia.duration * ui.value / slidersRange;
                if (ui.value === ui.values[0]) {
                    currentSegment.setBegin(t);
                } else {
                    currentSegment.setEnd(t);
                }
            }
        }
    });
    
    sliceSlider.find(".ui-slider-handle:first")
        .addClass("Ldt-Slice-left-handle")
        .click(function() {
            if (currentMedia && currentSegment) {
                currentMedia.setCurrentTime(currentSegment.begin);
            }
        });
    sliceSlider.find(".ui-slider-handle:last")
        .addClass("Ldt-Slice-right-handle")
        .click(function() {
            if (currentMedia && currentSegment) {
                currentMedia.setCurrentTime(currentSegment.end);
            }
        });
    
    /* UI Events */

    function onCurrentMediaPlay() {
        $(".Ldt-Ctrl-Play")
            .attr("title", "Pause")
            .removeClass("Ldt-Ctrl-Play-PlayState")
            .addClass("Ldt-Ctrl-Play-PauseState")
    }
    
    function onCurrentMediaPause() {
        $(".Ldt-Ctrl-Play")
            .attr("title", "Lecture")
            .removeClass("Ldt-Ctrl-Play-PauseState")
            .addClass("Ldt-Ctrl-Play-PlayState")
    }
    
    function onCurrentMediaTimeupdate(_time) {
        $(".Ldt-Ctrl-Time-Elapsed").text(_time.toString());
        timeSlider.slider("value",slidersRange * _time / currentMedia.duration);
    }
    
    /* Mashup Player */

    var mashupCurrentMedia = null,
        mashupCurrentAnnotation = null,
        mashupSegmentBegin,
        mashupSegmentEnd,
        mashupTimecode = 0,
        mashupSeeking = false,
        seekdiv = $(".video-wait"),
        mashupTimedelta;
    
    function showSeek() {
        if (mashupSeeking) {
            seekdiv.show();
        }
    }
    
    function changeCurrentAnnotation() {
        if (mashupTimecode >= mashup.duration) {
            if (!mashup.paused) {
                mashup.paused = true;
                mashup.trigger("pause");
            }
            mashupTimecode = 0;
        }
        var _annotation = mashup.getAnnotationAtTime( mashupTimecode );
        if (typeof _annotation === "undefined") {
            if (mashupCurrentMedia) {
                mashupCurrentMedia.pause();
                if (!mashup.paused) {
                    mashup.paused = true;
                    mashup.trigger("pause");
                }
            }
            return;
        }
        mashupCurrentAnnotation = _annotation;
        mashupSegmentBegin = mashupCurrentAnnotation.annotation.begin.milliseconds;
        mashupSegmentEnd = mashupCurrentAnnotation.annotation.end.milliseconds;
        mashupTimedelta = mashupSegmentBegin - mashupCurrentAnnotation.begin.milliseconds;
        mashupCurrentMedia = mashupCurrentAnnotation.getMedia();
        
        project.getMedias().forEach(function(_media) {
            if (_media !== mashupCurrentMedia) {
                _media.hide();
                _media.pause();
            } else {
                _media.show();
            }
        });
        
        mashupCurrentMedia.setCurrentTime( mashupTimecode + mashupTimedelta);
        mashupCurrentMedia.seeking = true;
        
        if (!mashup.paused) {
            mashupCurrentMedia.play();
            mashupSeeking = true;
            setTimeout(showSeek,200);
        }
        mashup.trigger("timeupdate", new IriSP.Model.Time(mashupTimecode));

    }
    
    /* Set current Media */
   
    var currentMedia, currentSegment;
    
    function updateSliderAndTangles() {
        if (currentMedia && currentSegment) {
            var start = currentSegment.begin,
                end = currentSegment.end,
                dur = currentSegment.getDuration(),
                f = slidersRange / currentMedia.duration,
                tangleStart = $(".tangle-start"),
                tangleEnd = $(".tangle-end"),
                tangleDuration = $(".tangle-duration"),
                k = 100 / currentMedia.duration,
                p = k * (start + end) / 2;
            sliceSlider.slider( "values", [ f * start, f * end ] );
            tangleStart.text(start.toString(tangleStart.hasClass("active"))).attr("data-milliseconds",start.milliseconds);
            tangleEnd.text(end.toString(tangleEnd.hasClass("active"))).attr("data-milliseconds",end.milliseconds);
            tangleDuration.text(dur.toString(tangleDuration.hasClass("active"))).attr("data-milliseconds",dur.milliseconds);
            $(".segment-info .pointer").css("left", p + "%");
            $(".media-current-section").css({
                left: (k * start) + "%",
                width: (k * dur) + "%"
            })
        }
    }
    
    var addMode;
    
    function setMedia(media) {
        if (currentMedia) {
            currentMedia.pause();
        }
        currentMedia = media;
        if (currentMedia.elementType == "media") {
            $("video").hide();
            showSegmentation();
            if (!currentMedia.loaded) {
                seekdiv.show();
            }
            var currentvideo = $('#video_' + currentMedia.id);
            if (!currentvideo.length) {
                addMediaPlayer(currentMedia);
            }
            $(".tab-media-title").text(currentMedia.title);
            
            addMode = !(currentSegment && mashup.hasAnnotation(currentSegment));
            
            if (!currentSegment) {
                currentSegment = new IriSP.Model.Annotation(false, project);
                currentSegment.setMedia(currentMedia.id);
                currentSegment.setBegin(0);
                currentSegment.setEnd(currentMedia.duration);
                currentSegment.title = "Segment sans titre";
                currentSegment.description = "Extrait de « " + currentMedia.title + " »";
                currentSegment.on("change-begin", function() {
                    if (currentMedia && currentSegment === this) {
                        currentMedia.setCurrentTime(this.begin);
                        updateSliderAndTangles();
                    }
                });
                currentSegment.on("change-end", function() {
                    if (currentMedia && currentSegment === this) {
                        currentMedia.setCurrentTime(this.end);
                        updateSliderAndTangles();
                    }
                });
                currentSegment.on("enter", function() {
                    if (currentMedia === mashup) {
                        $(".annotation-title").text(this.title);
                        $(".annotation-begin").text(this.begin.toString());
                        $(".annotation-end").text(this.end.toString());
                        $(".annotation-media-title").text(this.getMedia().title);
                        $(".annotation-description").text(this.description);
                        setPointerToCurrentAnnotation();
                        highlightCurrentSegment();
                    }
                });
            }
            if (currentMedia.loaded) {
                currentMedia.setCurrentTime(currentSegment.begin);
            }
            $(".add-segment").val(addMode ? "Ajouter au Hashcut" : "Sauvegarder");
            $(".create-or-edit").text(addMode ? "Créer un nouveau segment" : "Modifier le segment");
            updateSliderAndTangles();
            media.show();
            $("#segment-title").val(currentSegment.title);
            $("#segment-description").val(currentSegment.description);
            $("#segment-tags").val("");
            var relatedSegments = mashup.segments.filter(function(_s) {
                return _s.getMedia() === currentMedia && _s.annotation !== currentSegment;
            });
            var html = "";
            if (relatedSegments.length) {
                var k = $(".Ldt-Slider").width() / currentSegment.getMedia().duration,
                    currentleft = k * currentSegment.begin,
                    currentwidth = k * currentSegment.getDuration();
                relatedSegments.forEach(function(_s) {
                    var pos = k * (_s.annotation.begin + _s.annotation.end) / 2,
                        corrpos = Math.max(145, Math.min(305, pos));
                    vizdata = {
                        annotation : _s.annotation,
                        currentleft : currentleft,
                        currentwidth : currentwidth,
                        popleft : corrpos,
                        left : k * _s.annotation.begin,
                        width : k * _s.annotation.getDuration(),
                        pointerpos : (pos - corrpos)
                    }
                    html += mediasegmenttemplate(vizdata);
                });
                $(".self-media-segments").show();
            } else {
                $(".self-media-segments").hide();
            }
        }
        $(".self-media-segments .media-segments-list").html(html);
        if (currentMedia.elementType === "mashup") {
            showPreview();
            mashup.checkLoaded();
        }
        $(".Ldt-Ctrl-Time-Total").text(currentMedia.duration.toString());
        // TODO: Do something with the tags !
        onCurrentMediaTimeupdate(currentMedia.getCurrentTime());
        onCurrentMediaPause();
        highlightCurrentSegment();
    }
    
    function addMediaPlayer(media) {
        var videoid = "video_" + media.id,
            videoEl = $('<video>'),
            width = $(".video").width(),
            height = $(".video").height(),
            mp4_file = media.video.replace(/\.webm$/i,'.mp4'),
            webm_file = media.video.replace(/\.mp4$/i,'.webm'),
            mp4_src = $('<source>'),
            webm_src = $('<source>');
        mp4_src.attr({
            src: mp4_file,
            type: "video/mp4"
        });
        webm_src.attr({
            src: webm_file,
            type: "video/webm"
        });
        videoEl.attr({
            id : videoid,
            width : width,
            height : height
        }).css({
            position : "absolute",
            left: 0,
            top: 0,
            width : width,
            height : height
        });
        videoEl.append(mp4_src).append(webm_src);
        $(".video").append(videoEl);
        
        media.show = function() {
            videoEl.show();
        }
        media.hide = function() {
            videoEl.hide();
        }
        
        var popcorn = Popcorn("#" + videoid);
        
        // Binding functions to Popcorn
        
        media.on("setcurrenttime", function(_milliseconds) {
            if (media.loaded) {
                popcorn.currentTime(_milliseconds / 1000);
            }
        });
        
        media.on("setvolume", function(_vol) {
            media.volume = _vol;
            if (media.loaded) {
                popcorn.volume(_vol);
            }
        });
        
        media.on("setmuted", function(_muted) {
            media.muted = _muted;
            if (media.loaded) {
                popcorn.muted(_muted);
            }
        });
        
        media.on("setplay", function() {
            if (media.loaded) {
                popcorn.play();
            }
        });
        
        media.on("setpause", function() {
            if (media.loaded) {
                popcorn.pause();
            }
        });
        
        // Binding Popcorn events to media
        
        function getVolume() {
            media.muted = popcorn.muted();
            media.volume = popcorn.volume();
        }
        
        popcorn.on("loadedmetadata", function() {
            getVolume();
            media.loaded = true;
            media.trigger("loadedmetadata");
            media.trigger("volumechange");
        })
        
        popcorn.on("timeupdate", function() {
            media.trigger("timeupdate", new IriSP.Model.Time(1000*popcorn.currentTime()));
        });
        
        popcorn.on("volumechange", function() {
            getVolume();
            media.trigger("volumechange");
        })
        
        popcorn.on("play", function() {
            media.trigger("play");
        });
        
        popcorn.on("pause", function() {
            media.trigger("pause");
        });
        
        popcorn.on("seeked", function() {
            media.trigger("seeked");
        });
        
        // Binding UI Events and Mashup Playing to Media
        
        media.on("loadedmetadata", function() {
            if (media === currentMedia) {
                seekdiv.hide();
            }
            mashup.checkLoaded();
        });
        
        media.on("play", function() {
            if (media === currentMedia) {
                onCurrentMediaPlay();
            }
            if (mashup === currentMedia && media === mashupCurrentMedia) {
                mashup.trigger("play");
            }
        });
        
        media.on("pause", function() {
            if (media === currentMedia) {
                onCurrentMediaPause();
            }
            if (mashup === currentMedia && media === mashupCurrentMedia) {
                mashup.trigger("pause");
            }
        });
        
        media.on("timeupdate", function(_time) {
            if (media === currentMedia) {
                onCurrentMediaTimeupdate(_time);
            }
            if (mashup === currentMedia && !mashup.paused && media === mashupCurrentMedia && !media.seeking) {
                if ( _time < mashupSegmentEnd ) {
                    if ( _time >= mashupSegmentBegin ) {
                        mashupTimecode = _time - mashupTimedelta;
                    } else {
                        mashupTimecode = mashupSegmentBegin - mashupTimedelta;
                        media.setCurrentTime(mashupSegmentBegin);
                    }
                } else {
                    mashupTimecode = mashupSegmentEnd - mashupTimedelta;
                    media.pause();
                    changeCurrentAnnotation();
                }
                mashup.trigger("timeupdate", new IriSP.Model.Time(mashupTimecode));
            }
        });
        
        media.on("seeked", function() {
            media.seeking = false;
            if (mashup === currentMedia && media === mashupCurrentMedia && mashupSeeking) {
                mashupSeeking = false;
                seekdiv.hide();
            }
        });
        
        media.on("volumechange", function() {
            if (media === currentMedia) {
                ctrlVolumeUpdater();
            }
            mashup.muted = media.muted;
            mashup.volume = media.volume;
            mashup.trigger("volumechange");
        })
        
    }

    // Mashup Events
    
    mashup.on("setcurrenttime", function(_milliseconds) {
        mashupTimecode = _milliseconds;
        changeCurrentAnnotation();
    });
    
    mashup.on("setvolume", function(_vol) {
        mashup.getMedias().forEach(function(_media) {
            _media.setVolume(_vol);
        });
        mashup.volume = _vol;
    });
    
    mashup.on("setmuted", function(_muted) {
        mashup.getMedias().forEach(function(_media) {
            _media.setMuted(_muted);
        });
        mashup.muted = _muted;
    });
    
    mashup.on("setplay", function() {
        mashup.paused = false;
        changeCurrentAnnotation();
    });
    
    mashup.on("setpause", function() {
        mashup.paused = true;
        if (mashupCurrentMedia) {
            mashupCurrentMedia.pause();
        }
    });
    
    mashup.on("loadedmetadata", function() {
        if (mashup === currentMedia) {
            changeCurrentAnnotation();
        }
    });
    
    /* Mashup Events to UI */
   
    mashup.on("play", function() {
        if (mashup === currentMedia) {
            onCurrentMediaPlay();
        }
    });
    
    mashup.on("pause", function() {
        if (mashup === currentMedia) {
            onCurrentMediaPause();
        }
    });
    
    mashup.on("timeupdate", function(_time) {
        if (mashup === currentMedia) {
            $(".frise-position").css("left",(100*_time/mashup.duration)+"%");
            onCurrentMediaTimeupdate(_time);
        }
    });
        
    /* Segment Form interaction */
   
    $("#segment-title").on("keyup change input paste", function() {
        if (currentMedia && currentSegment) {
            currentSegment.title = $(this).val();
            updateMashupUI();
        }
    });
    $("#segment-description").on("keyup change input paste", function() {
        if (currentMedia && currentSegment) {
            currentSegment.description = $(this).val();
        }
    });
    $("#segment-form").submit(function() {
        if (addMode) {
            mashup.addAnnotation(currentSegment);
        } else {
            updateMashupUI();
        }
        var segment = mashup.getAnnotation(currentSegment);
        currentSegment = undefined;
        setMedia(mashup);
        if (segment) {
            mashup.setCurrentTime(segment.begin);
        }
        return false;
    })
    
    /* Click on media items */
   
    $(".col-left").on("click", ".item-video", function() {
        currentSegment = undefined;
        setMedia(project.getElement($(this).attr("data-media-id")));
    });
    
    /* Click on Tabs */
    
    function showSegmentation() {
        $(".col-middle").removeClass("empty-mode pvw-mode").addClass("segment-mode");
        return false;
    }
    function showPreview() {
        $(".col-middle").removeClass("empty-mode segment-mode").addClass("pvw-mode");
        return false;
    }
    function showEmpty() {
        $("video").hide();
        $(".col-middle").removeClass("pvw-mode segment-mode").addClass("empty-mode");
        return false;
    }
    
    $(".tab-pvw").click(function() {
        if (mashup.segments.length) {
            setMedia(mashup);
        }
    });
    
    /* Click on segments */
    
    function reorganizeMashup() {
        var ids = $(".organize-segments .item-video").map(function(){return $(this).attr("data-segment-id")});
        mashup.setAnnotationsById(ids);
    }
    
    function highlightCurrentSegment() {
        $(".organize-segments .item-video, .col-left .item-video, .frise-segment").removeClass("active");
        var segmentid = undefined;
        if (currentMedia && currentSegment) {
            segmentid = currentSegment.id;
        }
        if (currentMedia === mashup && mashupCurrentAnnotation) {
            segmentid = mashupCurrentAnnotation.annotation.id;
        }
        $(".item-video[data-segment-id='" + segmentid + "']").addClass("active");
        var mediaid = undefined;
        if (currentMedia) {
            mediaid = currentMedia.id;
        }
        if (currentMedia === mashup && mashupCurrentMedia) {
            mediaid = mashupCurrentMedia.id
        }
        $(".col-left .item-video[data-media-id='" + mediaid + "']").addClass("active");
    }
    
    function hoverSegment() {
        var segmentid = $(this).attr("data-segment-id");
        $(".organize-segments .item-video, .frise-segment").removeClass("active");
        $(".item-video[data-segment-id='" + segmentid + "'], .frise-segment[data-segment-id='" + segmentid + "']").addClass("active");
    }
    
    $(".frise")
    .on("mouseover", ".frise-segment", hoverSegment)
    .on("mouseout", ".frise-segment", highlightCurrentSegment)
    
    $(".organize-segments")
    .sortable({
        stop : reorganizeMashup
    })
    .on("mouseover", ".item-video", hoverSegment)
    .on("mouseout", ".item-video", highlightCurrentSegment)
    .on("click", ".item-video", function(e) {
        var el = $(this),
            segment = mashup.getAnnotationById(el.attr("data-segment-id"));
        setMedia(mashup);
        if (segment) {
            mashup.setCurrentTime(segment.begin);
        }
        return false;
    })
    .on("click", ".edit", function(e) {
        var currentItem = $(this).parents(".item-video"),
            media = project.getElement(currentItem.attr("data-media-id")),
            segment = project.getElement(currentItem.attr("data-segment-id"));
        currentSegment = segment;
        setMedia(media);
        return false;
    })
    .on("click", ".top", function(e){
        var currentItem = $(this).parents(".item-video");
        currentItem.insertBefore(currentItem.prev());
		reorganizeMashup();
		return false;
    })
    .on("click", ".bottom", function(e){
        var currentItem = $(this).parents(".item-video");
        currentItem.insertAfter(currentItem.next());
		reorganizeMashup();
        return false;
    })
    .on("click", ".delete", function(e){
        var id = $(this).parents(".item-video").attr("data-segment-id");
        mashup.removeAnnotationById(id);
        if (!mashup.segments.length) {
            showEmpty();
        }
        return false;
    });
    
    /* Tangles */
    var tangleMsPerPixel = 100,
        activeTangle,
        tangleStartX,
        tangleStartVal,
        tangleHasMoved;
    
    $(".time-tangle").mousedown(function(evt) {
        activeTangle = $(this);
        activeTangle.addClass("active");
        tangleStartVal = +activeTangle.attr("data-milliseconds");
        tangleStartX = evt.pageX;
        tangleHasMoved = false;
        $(this).siblings(".time-tangle").addClass("deactivate");
        return false;
    });
    $(document)
        .mousemove(function(evt) {
            if (activeTangle) {
                tangleHasMoved = true;
                var newval = new IriSP.Model.Time(tangleMsPerPixel * (evt.pageX - tangleStartX) + tangleStartVal);
                activeTangle.trigger("valuechange", newval);
                return false;
            }
        })
        .mouseup(function() {
            if (activeTangle) {
                activeTangle.text(activeTangle.text().replace(/\.\d+$/,''));
                $(".time-tangle").removeClass("active deactivate");
                activeTangle = undefined;
            }
        });
        
    $(".tangle-start")
        .mouseup(function(evt) {
            if (!tangleHasMoved && currentMedia && currentSegment) {
                currentMedia.setCurrentTime(currentSegment.begin);
            }
        })
        .on("valuechange", function(evt, val) {
            if (currentMedia && currentSegment) {
                currentSegment.setBegin(val);
            }
        });
    $(".tangle-end")
        .mouseup(function(evt) {
            if (!tangleHasMoved && currentMedia && currentSegment) {
                currentMedia.setCurrentTime(currentSegment.end);
            }
        })
        .on("valuechange", function(evt, val) {
            if (currentMedia && currentSegment) {
                currentSegment.setEnd(val);
            }
        });
    $(".tangle-duration").on("valuechange", function(evt, val) {
        if (currentMedia && currentSegment) {
            currentSegment.setDuration(val);
        }
    });
    
    /* Click on current segment in Preview */
    
    $(".mashup-description .edit").click(function() {
        if (mashupCurrentAnnotation) {
            currentSegment = mashupCurrentAnnotation.annotation;
            setMedia(mashupCurrentAnnotation.getMedia());
        }
    });
    
    /* Handling related segments */
   
    $(".media-segments-list").on("mouseover", ".media-segment", function() {
        $(this).find(".media-segment-popin").show();
    }).on("mouseout", ".media-segment", function() {
        $(this).find(".media-segment-popin").hide();
    }).on("click", ".reprendre-segment", function() {
        var s = project.getElement($(this).attr("data-segment-id"));
        currentSegment.title = s.title;
        currentSegment.description = s.description;
        $("#segment-title").val(s.title);
        $("#segment-description").val(s.description);
        currentSegment.setBegin(s.begin);
        currentSegment.setEnd(s.end);
        return false;
    });
    
    /* Changing Hashcut Title and description */
   
    $("#hashcut-title").on("keyup change input paste", function() {
        mashup.title = $(this).val();
        $(".title-video-wrap a").text(mashup.title);
    });
    
}