integration/js/edition.js
author Anthony Ly <anthonyly.com@gmail.com>
Tue, 18 Jun 2013 15:51:39 +0200
changeset 136 ac4dc3d6400b
parent 134 0282cb8db314
child 164 0af17a6cce42
permissions -rw-r--r--
update slideshow row

$(function(){

    var myMedia = undefined,
        currentChapter = undefined,
        currentAnnotation = undefined,
        currentSlider = undefined,
        secMiniChapter = 10,
        lengthStringDiapo = 40;

/* Colors */
    var annotationsColors = {
        'video' : '#BE4477',
        'text' : '#5E90CB',
        'slideshow' : '#F69058',
        'audio' : '#63BE6C',
        'links' : '#8985BB'
        },
        colorsRangeIndex = 0,
        colorsRange = [
            '#FF6138', '#FFFF9D', '#BEEB9F', '#79BD8F',  '#00A388',
             '#1695A3', '#ACF0F2', '#F3FFE2', '#EB7F00', '#FF8000',
             '#FFD933', '#CCCC52', '#8FB359', '#FFD393', '#F54F29'
        ];

    function getRandomColor(){
        return colorsRange[(colorsRangeIndex<colorsRange.length) ? colorsRangeIndex++ : (colorsRangeIndex=0)];
    }

    function getTemplate(idTpl){
        return $('#templates').find(idTpl).html();
    }

    myProject.onLoad(function() {
        myProject.regenerateTags = true;

        $(".project-title").text(myProject.title);
        $('.project-title-nav').text(myProject.title);

        myMedia = myProject.getCurrentMedia();

        //load Chapitre
        var anntypes = myProject.getAnnotationTypes().searchByTitle("chapitrage");
        if (!anntypes.length) {
            chapterAnnType = new IriSP.Model.AnnotationType(false, myProject);
            chapterAnnType.title = "chapitrage";
            myProject.getAnnotationTypes().push(chapterAnnType);
        } else {
            chapterAnnType = anntypes[0];
        }
        
        chapterAnnType.media = myMedia;

        chapters = chapterAnnType.getAnnotations();
        if(!chapters.length){
            var dataChapter = {
                title : '',
                begin : 0,
                end : myMedia.duration,
                description : '',
                keywords : []
            };
            newChapter(dataChapter, true);
        }
        $.each(chapters, function(k, v){
            v.color = getRandomColor();
        });
        renderChapter();

        //load Annotations
        var anntypes = myProject.getAnnotationTypes().searchByTitle("annotations");
        if (!anntypes.length) {
            annotationsAnnType = new IriSP.Model.AnnotationType(false, myProject);
            annotationsAnnType.title = "annotations";
            myProject.getAnnotationTypes().push(annotationsAnnType);
        } else {
            annotationsAnnType = anntypes[0];
        }
        
        annotationsAnnType.media = myMedia;

        annotations = annotationsAnnType.getAnnotations();
        $.each(annotations, function(k, v){
            var type = v.content.mimetype.split('-');
            type = type[type.length-1]
            v.type = type;
            v.color = annotationsColors[type];
        });
        renderAnnotation();

        //player
        IriSP.htmlPlayer(
            myMedia,
            $(".main-video"),
            {
                width: 460,
                height: 345,
                controls: true,
                autostart: true,
                url_transform: function(src) {
                    return [{
                        type: "video/mp4",
                        src: src.replace(/\.[\d\w]+$/,'.mp4').replace('rtmp://media.iri.centrepompidou.fr/ddc_player', 'http://media.iri.centrepompidou.fr')
                    }, {
                        type: "video/webm",
                        src: src.replace(/\.[\d\w]+$/,'.webm').replace('rtmp://media.iri.centrepompidou.fr/ddc_player', 'http://media.iri.centrepompidou.fr')
                    }];
                }
            }
        );

        myMedia.on("timeupdate", function(t) {
            //curseur chapitre
            var wContainer = $('.chapitre-cut-wrap').width() - 1,
                pos = wContainer * t / myMedia.duration,
                btnCutChapter = $('.btn-cut-chapter'),
                wBtnCutChapter = btnCutChapter.outerWidth();
            
            $(".indicateur-chapter, .indicateur-annotation").css("left",pos);
            if(pos+wBtnCutChapter>wContainer){
                btnCutChapter.css("left",(pos - wBtnCutChapter));
            }else{
                btnCutChapter.css("left",pos);
            }
            $('.info-time').text(t);

            //display annotations
            refreshAnnotationDisplay(t);
        });//timeupdate
        
    });//myProject.onLoad

/* Display annotation in timeline */

    //hover
    $(document).on('mouseover', '.timeline-annotations .annotation, #list-annotations-rows tr, .item-display-annotation' , function(){
        if(!$(this).hasClass('shadow')) {
            var idAnnotation = $(this).attr('data-id');
            $('#tab-annotation-'+idAnnotation+', #annotation-timeline-'+idAnnotation+', #row-list-annotation-'+idAnnotation+', #item-current-annotation-'+idAnnotation).addClass('shadow');
        }
    });

    $(document).on('mouseover', '.chapter-segment, .row-list-chapter' , function(){
        if(!$(this).hasClass('shadow')) {
            var idChapter = $(this).attr('data-id');
            $('#row-list-chapter-'+idChapter+', #'+idChapter+', #form-chapter-edit-'+idChapter).addClass('shadow');
        }
    });

    $(document).on('mouseout', '.shadow' , function(){
        $('.shadow').removeClass('shadow');
    });

    $(document).on('click', '.annotation, .item-display-annotation', function(e){
        e.preventDefault();
        var idAnnotation = $(this).attr('data-id'),
            annotation = _.find(annotations, function(c){ return c.id == idAnnotation; });
        myMedia.setCurrentTime(annotation.begin);
        if($('#tab-annotation-'+idAnnotation).length){
            $('a[href=#tab-annotation-'+idAnnotation+']').tab('show');
        }else{
            openTab(annotation.type, annotation);
        }
    });

    function refreshAnnotationDisplay(t){
        var currentAnnotationsDisplay = new Array();
        $.each(annotations, function(k, v){

            if(v.begin <= t && v.end >= t){
                currentAnnotationsDisplay.push(v.id);
                if(!$('#item-current-annotation-'+v.id).length){
                    var itemAnnotation = getTemplate('#tpl-item-annotation-display');
                    v.iconTab = getIcon(v.type);
                    itemAnnotation = Mustache.render(itemAnnotation, v);
                    $('.list-current-annotations').append(itemAnnotation)
                }
            }
        });

        $.each($('.list-current-annotations li'), function(k, v){
            var idAnnotation = $(this).attr('data-id'),
                annotationDisplayView = $('.annotation-display-view');
            if($.inArray(idAnnotation, currentAnnotationsDisplay)<0){//il ne doit plus ĂȘtre affichĂ©
                $('#item-current-annotation-'+idAnnotation).remove();
                if(annotationDisplayView.attr('data-id') == idAnnotation && annotationDisplayView.is(":visible")){
                    annotationDisplayView.hide();
                }
            }
        });
        if(currentAnnotation !== undefined){ 
            showCurrentAnnotationInTimeline(currentAnnotation.id);
        }
    }

    function showCurrentAnnotationInTimeline(idAnnotation){
        $('.annotation').removeClass('editing');
        $('#annotation-timeline-'+idAnnotation).addClass('editing');
    }

    $('.list-current-annotations').on('click', 'a', function(e){
        e.preventDefault();
    });
    

/*  Modal */

    //confirmation suppression
    $("#modal-confirm").on('click', '#btn-delete-modal', function(e){
        
        var typeDelete = $(this).attr('data-type-delete'),
            idAnnotation = $(this).attr('data-id');

        if(typeDelete == 'chapter' || typeDelete == 'annotation'){
            e.preventDefault();
            if(typeDelete == 'chapter') deleteChapter(idAnnotation);
            if(typeDelete == 'annotation') deleteAnnotation(idAnnotation);
        }
    });

/* Title project */

    $(document).on('click', '.project-title-editor i, .project-title', function () {
        
        var html = myProject.title;
        var input = $('<input type="text" />');
        input.val(html);
        $('.project-title').replaceWith(input);
        input.focus().keypress(function(e){
            code = (e.keyCode ? e.keyCode : e.which);
            if (code == 13) $(this).blur();
        });
    });
    $(document).on('blur', '.project-title-editor input', function(){
        var newTitle = $(this).val();
        myProject.title = newTitle;
        $(this).replaceWith('<span class="project-title">'+newTitle+'</span></td>');
        $('.project-title-nav').text(newTitle);
        disabledPreview();
    });


/*  Chapter */

    //edit
    $('.list-chapter-wrap').on('click', '.btn-edit-chapter', function(e){
        e.preventDefault();
        var idChapter = $(this).attr('data-chapter-id');
        loadFormChapter(idChapter);
    });

    $('.chapter-widget-info').on('keyup', 'input[name=title], textarea', function(e){
        var name = $(this).attr('name'),
            value = $(this).val();
        currentChapter[name] = value;
        if(name == 'title'){
            var idChapter = $(this).parents('form').attr('data-chapter-id');
            $('.chapter-segments').find('#'+idChapter).text(value);
            $('#row-list-chapter-'+idChapter).find('td:first').text(value);
            $(this).parents('form').find('.btn-delete-chapter').attr('data-title', value);
        }
        disabledPreview();
    });

    //form chapter
    $('.chapter-segments').on('click', 'li', function(){
        var idChapter = $(this).attr('id');
        loadFormChapter(idChapter);
    });

    function loadFormChapter(idChapter){
        currentChapter = _.find(chapters, function(c){ return c.id == idChapter; });
        var chapterWrap = $('.chapter-widget-info'),
            indexChapter = _.indexOf(chapters, currentChapter),
            beginTangle = (indexChapter>0) ? true : false,
            endTangle = (indexChapter<(chapters.length-1)) ? true : false;

        currentChapter.beginTangle = beginTangle;
        currentChapter.endTangle = endTangle;

        var tpl = getTemplate('#tpl-chapter-edit');
            tpl = Mustache.render(tpl, currentChapter);
            chapterWrap.empty().append(tpl);
            chapterWrap.find('.tag-it').tagit(tagitParam);

        myMedia.setCurrentTime(currentChapter.begin);
    }

    //close chapter form
    $(document).on('click', '.btn-ok-chapter', function(e){
        e.preventDefault();
        $('.form-chapter-edit').remove();
    });

    //delete chapter
    $(document).on('click', '.btn-delete-chapter', function(e){
        e.preventDefault();

        if(chapters.length == 1){
            $('#modal-alert .alert-message').hide();
            $('#modal-alert #alert-chapter-number').show();
            $('#modal-alert').modal('show');
            return;
        }
        var idChapter = $(this).attr('data-chapter-id'),
            btnDeleteModal = $("#modal-confirm #btn-delete-modal");
        btnDeleteModal.attr('data-type-delete', 'chapter');
        btnDeleteModal.attr('data-id', idChapter);

        var titleMedia = $(this).attr('data-title'),
            urlDelete = $(this).attr('href');
        $("#modal-confirm #btn-delete-modal").attr('href', urlDelete).focus();
        $("#modal-confirm .modal-body").find('.titleMedia').text(titleMedia);
        $("#modal-confirm").modal('show');

    });

    function deleteChapter(idChapter){
        
        $("#modal-confirm").modal('hide');
        var chapter = _.find(chapters, function(c){ return c.id == idChapter; }),
            indexChapter = _.indexOf(chapters, chapter),
            chapterModify;
        if(indexChapter == 0){
            chapterModify = chapters[1];
            chapterModify.setBegin(0);
        }else{
            chapterModify = chapters[indexChapter-1];
            //var newEnd = new IriSP.Model.Time(chapter.end)
            chapterModify.setEnd(chapter.end);
        }
        chapters.removeId(idChapter);
        myProject.getAnnotations().removeId(idChapter, true);
        renderChapter();
        //si le formulaire est visible
        if($('#form-chapter-edit-'+idChapter).length){
            $('#form-chapter-edit-'+idChapter).remove();
        }
        disabledPreview();
    }

    //new chapter
    function newChapter(dataChapter, render){
        var chapter = new IriSP.Model.Annotation(false, myProject);
            chapter.setMedia(myMedia.id);
            chapter.setBegin(dataChapter.begin);
            chapter.setEnd(dataChapter.end);
            chapter.setAnnotationType(chapterAnnType.id);
            chapter.title = dataChapter.title;
            chapter.description = dataChapter.description;
            chapter.keywords = dataChapter.keywords;
            chapter.color = getRandomColor();
    
        chapters.push(chapter);
        myProject.getAnnotations().push(chapter);
        renderChapter();
        loadFormChapter(chapter.id);
        disabledPreview();
        $('.chapter-title').focus();
    }

    $('.chapter-widget').on('click', '.btn-cut-chapter', function(e){
        e.preventDefault();
        var begin = myMedia.currentTime,
            end = organizeNewChapter(myMedia.currentTime);
        if(!end){
            $('#modal-alert .alert-message').hide();
            $('#modal-alert #alert-chapter-duration').show();
            $('#modal-alert #alert-chapter-duration strong').text(secMiniChapter);
            $('#modal-alert').modal('show');
            return;
        }
        var dataChapter = {
            title : '',
            begin : begin,
            end : end,
            description : '',
            keywords : []
        };

        newChapter(dataChapter, true);
    });
    
    function organizeNewChapter(beginNew){

        var returnEnd = false;
        $.each(chapters, function(k, v){
            var begin = v.begin,
                end = v.end;

            if(beginNew>=begin && beginNew<=end && end-beginNew>secMiniChapter*1000 && beginNew-begin>secMiniChapter*1000){
                returnEnd = new IriSP.Model.Time(end);
                v.setEnd(beginNew); 
            }
        });
 
        return returnEnd;
    }
    
    function renderChapter(){
        var chapterSegmentWrap = $('.chapter-segments'),
            wChapterSegmentWrap = chapterSegmentWrap.width(),
            chapterList = $('.list-chapter-rows-wrap');

        chapters = chapters.sortBy(function(c){
            return c.begin;
        });

        chapterSegmentWrap.empty();
        chapterList.empty();
       
            $.each(chapters, function(k, v){

                //segments
                var width = v.getDuration() * wChapterSegmentWrap / myMedia.duration,
                    left = v.begin * wChapterSegmentWrap / myMedia.duration,
                    segment = $('<li>'+v.title+'</li>').css({
                        left : left,
                        width : width,
                        backgroundColor : v.color
                    }).attr('id', v.id)
                    .attr('data-id', v.id)
                    .addClass('chapter-segment');
        
                chapterSegmentWrap.append(segment);

                //liste
                var tplChapterRow = getTemplate('#tpl-chapter-row');
                tplChapterRow = Mustache.render(tplChapterRow, v);
                chapterList.append(tplChapterRow);
            });
     
    }//renderChapter()

/* Annotation */    

    function newAnnotation(dataAnnotation){
        var annotation = new IriSP.Model.Annotation(false, myProject);
            annotation.setAnnotationType(annotationsAnnType.id);
            annotation.setMedia(myMedia.id);
            annotation.setBegin(dataAnnotation.begin);
            annotation.setEnd(dataAnnotation.end);
            annotation.title = dataAnnotation.title;
            annotation.description = dataAnnotation.description;
            annotation.type = dataAnnotation.type;
            annotation.color = annotationsColors[dataAnnotation.type];
            annotation.keywords = dataAnnotation.keywords;
            annotation.content = getContentAnnotationByType(dataAnnotation.type);

        myProject.getAnnotations().push(annotation);
        annotations.push(annotation);
        disabledPreview();
        refreshAnnotationDisplay(myMedia.getCurrentTime());
        return annotation;
    }

    //annotation content data init
    function getContentAnnotationByType(type){
        var content;
        switch(type){
            case 'audio':
                content = {
                    mimetype : "application/x-ldt-audio",
                    url : "",
                    embedcode : ""
                };
                break;
            case 'video':
                content = {
                    mimetype : "application/x-ldt-video",
                    url : "",
                    embedcode : ""
                };
                break;
            case 'text': 
                content = {
                    mimetype : "application/x-ldt-text",
                    markup : "html",
                    text : ""
                };
                break;
            case 'links': 
                content = {
                    mimetype : "application/x-ldt-links",
                    links : []
                };
                break;
            case 'slideshow': 
                content = {
                    mimetype : "application/x-ldt-slideshow",
                    slideduration : 3000,
                    autostart : false,
                    images : []
                };
                break;
        }
        return content;
    }

    function renderAnnotation(){
        
        var timeline = $('.timeline-annotations'),
            wTimeline = timeline.width(),
            annotationList = $('#list-annotations-rows');

        annotations = annotations.sortBy(function(c){
            return c.begin;
        });

        timeline.empty().append('<li>');
        annotationList.empty();

        $.each(annotations, function(k, v){

            //timeline
            var width = Math.floor(v.getDuration() * wTimeline / myMedia.duration),
                left = Math.floor(v.begin * wTimeline / myMedia.duration),
                dataAnntim = {
                    left : left,
                    width : width,
                    color : v.color,
                    id : v.id,
                    title : v.title
                },
                segment = getTemplate('#tpl-annotation-in-timeline');
                segment = Mustache.render(segment, dataAnntim);

            var isInTimeline = false;
            $.each(timeline.find('li'), function(a, b){
                if(isInTimeline) return;
                var row = $(this);
                if(row.children().length){
                    var canBeInRow = true;
                    $.each(row.find('.annotation'), function(c, d){
                        var oAL = parseInt($(d).css('left')),
                            oAR = oAL + $(d).width(),
                            segmentR = left + width;
                        if(oAL<=left && oAR>=left || oAL<=segmentR && oAR>= segmentR){
                            canBeInRow = false;
                        }
                    });
                    if(canBeInRow){
                        row.append(segment);
                        isInTimeline = true;
                    }
                }else{
                    row.append(segment);
                    isInTimeline = true;
                }
            });

            if(!isInTimeline){
                timeline.append('<li>');
                timeline.find('li:last-child').append(segment);
            }
            
            //liste
                v.iconTab = getIcon(v.type);
                var tplAnnotationRow = getTemplate('#tpl-list-annotation-row');
                tplAnnotationRow = Mustache.render(tplAnnotationRow, v);
                annotationList.append(tplAnnotationRow);
        });
    }//renderAnnotation

    //edit annotation
    $('#list-annotations').on('click', 'a.btn-edit-annotation', function(e){
        e.preventDefault();
        
        var idAnnotation = $(this).attr('data-id');
        //si il est déjà ouvert
        if($('#tab-annotation-'+idAnnotation).length){
            $('a[href=#tab-annotation-'+idAnnotation+']').tab('show');
        }else{
            var data = _.find(annotations, function(c){ return c.id == idAnnotation; });
            openTab(data.type, data);
        } 
    });

    $('.tab-content').on('keyup', '.form-info-general-annotation input[name=title], .form-info-general-annotation textarea', function(e){
        var name = $(this).attr('name'),
            value = $(this).val();
        currentAnnotation[name] = value;
        if(name == 'title'){
            var idAnnotation = $(this).parents('form').attr('data-id');
            $('#onglet-title-'+idAnnotation).text(value);
            $(this).parents('form').find('.btn-delete-annotation').attr('data-title', value);
            $('#annotation-timeline-'+ idAnnotation).attr('title', value);
            $('#annotation-timeline-'+ idAnnotation+' span').text(value);
        }
        disabledPreview();
    });

    //delete annotation
    $(document).on('click','.btn-delete-annotation', function(e){
        e.preventDefault();

        var idAnnotation = $(this).attr('data-id'),
            btnDeleteModal = $("#modal-confirm #btn-delete-modal");
        btnDeleteModal.attr('data-type-delete', 'annotation');
        btnDeleteModal.attr('data-id', idAnnotation);
    });

    function deleteAnnotation(idAnnotation){
        
        $("#modal-confirm").modal('hide');
        annotations.removeId(idAnnotation);
        myProject.getAnnotations().removeId(idAnnotation, true);
        closeTab(idAnnotation);
        renderAnnotation();
        disabledPreview();
        refreshAnnotationDisplay(myMedia.getCurrentTime());
    }

/* Tab */

    $('#onglet-annotations').on('click', 'a', function(e){
        e.preventDefault();
        $(this).tab('show');
    });

    //open tab
    $(document).on('click', '.open-tab', function(e){
        e.preventDefault();
        var type = $(this).attr('data-type');
        openTab(type);
    });

    function openTab(type, data){
        
        var dataView, isNew = false;
        if(_.isUndefined(data)){//new
            var currentTimePlusUnMin = 60 * 1000 + myMedia.currentTime,
                endAnnotation = (currentTimePlusUnMin<myMedia.duration) ? currentTimePlusUnMin : myMedia.duration;
            var dataAnnotation = {
                title : '',
                begin : myMedia.currentTime,
                end : endAnnotation,
                description : '',
                type : type,
                keywords : []
            };
            dataView = newAnnotation(dataAnnotation);
            renderAnnotation();
            isNew = true;
        }else{//edition
            dataView = data;
        }

        var idAnnotation = dataView.id,
            tabContent = $('<div class="tab-pane" id="tab-annotation-'+idAnnotation+'"></div>'),
            iconTab;

        currentAnnotation = _.find(annotations, function(c){ return c.id == idAnnotation; });
        showCurrentAnnotationInTimeline(idAnnotation);
            //head commun Ă  tous
            var tplHead = getTemplate('#tpl-head');
            var output = Mustache.render(tplHead, dataView);
            $(tabContent).append(output);
            $(tabContent).find(".slider-duration").slider(configSlider(dataView));
            currentSlider = $(tabContent).find(".slider-duration");
            $(tabContent).find(".ui-slider-range.ui-widget-header.ui-corner-all").css('background', dataView.color);
            $(tabContent).find('.tag-it').tagit(tagitParam);
            
            //type
            var viewType = {
                id : idAnnotation,
                content : dataView.content
            };
            var tpl = getTemplate('#tpl-'+type);

            tpl = Mustache.render(tpl, viewType);
            $(tabContent).append(tpl);
            $('.tab-content').append(tabContent);

            //data by type
            switch(type){
                case 'audio':
                    break;
                case 'video':
                    var labelModify = $(tabContent).find('.label-modify-video'),
                        labelAdd = $(tabContent).find('.label-add-video');
                    if(viewType.content.url != ""){
                        var videoWrap = $(tabContent).find('.annotation-video-content');
                        renderVideoInfo(videoWrap, viewType.content);
                        labelModify.show();

                    }else{
                        labelAdd.show();
                    }
                    break;
                case 'text': 
                    var cledit = $(tabContent).find('.wysiwyg').cleditor(wysiwygConfig)[0];
                    break;
                case 'links': 
                    var tbody = $(tabContent).find('tbody.links-rows'),
                        links = viewType.content.links;
                    if(links.length){
                        $.each(links, function(k,v){
                            addLinkRow(tbody, v);
                        });
                    }else{//il n'y a pas de lien on en ajoute 1
                        addLinkRow(tbody);
                    }
                    break;

                case 'slideshow': 

                    $(tabContent).find('.number-spin').val(dataView.content.slideduration/1000);
                    $(tabContent).find('.number-spin').spin(spinParam);
                    $(tabContent).find('.ui-sortable').sortable({
                        start: function (event, ui) {
                            $(ui.item).data("startindex", ui.item.index());
                        },
                        stop : function(event, ui){
                            disabledBtnSortable($(this));
                        },
                        update : function(event, ui){
                            var oldIndex = ui.item.data("startindex"),
                                newIndex = ui.item.index();
                            currentAnnotation.content.images.move(oldIndex, newIndex);
                        },
                    });
                    var slideshow = $(tabContent).find('#slideshow-'+idAnnotation),
                        images = viewType.content.images;
                    if(images.length){
                        $.each(images, function(k,v){
                            addImageToSlideshow(slideshow, v);
                        });
                    }
                    break;
            }

            dataView.iconTab = getIcon(type);
            var tplOnglet = getTemplate('#tpl-onglet');
            var onglet = Mustache.render(tplOnglet, dataView);

            $(".nav-tabs li:last-child").after(onglet);
            $('a[href=#tab-annotation-'+idAnnotation+']').tab('show');

            if(isNew){$(tabContent).find('.head-title').focus();}
  
    }//openTab

    function getIcon(type){
        var icon;
        switch(type){
            case 'audio': icon = 'volume-up';
                break;
            case 'video': icon = 'film';
                break;
            case 'text': icon = 'align-left';
                break;
            case 'html': icon = 'code';
                break;
            case 'links': icon = 'link';
                break;
            case 'slideshow': icon = 'picture';
                break;
        }
        return icon;
    }

    //define currentAnnotation by open tab
    $('#onglet-annotations').on('show', 'a[data-toggle="annotation"]', function (e) {
        var idAnnotation = $(e.target).attr('data-id');
        currentAnnotation = _.find(annotations, function(c){ return c.id == idAnnotation; });
        currentSlider = $('#tab-annotation-'+idAnnotation).find(".slider-duration");
        showCurrentAnnotationInTimeline(idAnnotation);
    });

    //refresh annotation data view when back on annotation list tab
    $('#onglet-annotations').on('show', 'a[data-toggle="list-annotations"]', function (e) {
        currentAnnotation = undefined;
        renderAnnotation();
    });

    //close tab
    function closeTab(idAnnotation){
        $('#onglet-'+idAnnotation).remove();
        $('.tab-content #tab-annotation-'+idAnnotation).remove();
        $('#tab-list-annotation').tab('show');
    }

    $('#onglet-annotations').on('click', 'span.close-tab', function(e){
        e.preventDefault();e.stopPropagation();
        var idAnnotation = $(this).parents('a').attr('data-id');
        closeTab(idAnnotation);
    });

    $('.tab-content').on('click', '.btn-save-annotation', function(e){
        e.preventDefault();
        var idAnnotation = $(this).attr('data-id');
        closeTab(idAnnotation);
    });

/* Video */

    function renderVideoInfo(videoWrap, dataVideo){
        var tplVideo = getTemplate('#tpl-video-row');
        tplVideo = Mustache.render(tplVideo, dataVideo);
        
        videoWrap.empty().append(tplVideo);

        videoWrap = videoWrap.find(".video-container");
        getVideoPlayer(dataVideo.url, videoWrap);
    }

    //select video on modal
    $('.popup').on('click', '.bibliotheque-video a:not(.pagination a)', function(e){
        e.preventDefault();

        var url = $(this).attr('data-url'),
            title = $(this).attr('data-title'),
            description = $(this).attr('data-description');

        currentAnnotation.content.url = url;
        currentAnnotation.content.title = title;
        currentAnnotation.content.description = description;

        $('.popup').modal('hide');

        var videoWrap = $('#tab-annotation-'+currentAnnotation.id).find('.annotation-video-content');
        renderVideoInfo(videoWrap, currentAnnotation.content);

        var labelModify = $('#tab-annotation-'+currentAnnotation.id).find('.label-modify-video'),
            labelAdd = $('#tab-annotation-'+currentAnnotation.id).find('.label-add-video');

        labelModify.show();
        labelAdd.hide();

        disabledPreview();
    });

/* Slideshow */

    //select image on modal 
    $('.popup').on('click', '.bibliotheque-image a:not(.pagination a)', function(e){
        e.preventDefault();

        var url = $(this).attr('data-url'),
            title = $(this).attr('data-title'),
            description = $(this).attr('data-description'),
            image = {
                id : currentAnnotation.id,
                url : url,
                title : title,
                description : description
            };
        currentAnnotation.content.images.push(image);

        var listSlideshow = $('#slideshow-'+currentAnnotation.id);
        addImageToSlideshow(listSlideshow, image);
        $('.popup').modal('hide'); 
        disabledPreview();
    });

    function addImageToSlideshow(slideshow, dataView){
        var tplDiapo = getTemplate('#tpl-slideshow-row');
        dataView.limitLength = function(){
            return function(text, render) {
                if(render(text).length > lengthStringDiapo){
                    return render(text).substr(0,lengthStringDiapo) + '...';
                }else{
                    return render(text);
                }
            }
        }
        tplDiapo = Mustache.render(tplDiapo, dataView);
        slideshow.append(tplDiapo);
        disabledBtnSortable(slideshow);
    };

    //edit 
    $('.tab-content').on('click', '.title-slideshow-row, .description-slideshow-row', function(){
        if($(this).find('input').length) return;
        var index = $(this).parents('.row-image-slideshow').index(),
            inputType = $(this).attr('data-input'),
            name = $(this).attr('data-name'),
            input = $('<'+inputType+'>').attr('name', name),
            html = currentAnnotation.content.images[index][name];
        input.val(html);
        $(this).find('span').replaceWith(input);
        input.focus().keypress(function(e){
            code = (e.keyCode ? e.keyCode : e.which);
            if (code == 13) $(this).blur();
        });
    });

    $(document).on('blur', '.title-slideshow-row input, .description-slideshow-row textarea', function(){
        var newValue = $(this).val(),
            name = $(this).attr('name'),
            indexRow = $(this).parents('.row-image-slideshow').index();
        currentAnnotation.content.images[indexRow][name] = newValue;
        if(newValue.length>lengthStringDiapo){
            newValue = newValue.substr(0,lengthStringDiapo) + '...';
        }
        var span = $('<span>').html(newValue);
        $(this).replaceWith(span);
        
        disabledPreview();
    });

    //button up / down
    $(document).on('click', '.ui-sortable .btn-sort', function(e){
        e.preventDefault();
        var row = $(this).parents('tr.row-image-slideshow'),
            oldIndex = row.index(),
            listSlideshow = $(this).parents('.list-image-slideshow');

        if($(this).hasClass('down'))
            row.insertAfter(row.next());
        else if($(this).hasClass('up'))
            row.insertBefore(row.prev());

        var newIndex = row.index();
        currentAnnotation.content.images.move(oldIndex, newIndex);

        disabledBtnSortable(listSlideshow);
        disabledPreview();
    });

    function disabledBtnSortable(listSlideshow){
        listSlideshow.find('.btn-sort.disabled').removeClass('disabled');
        listSlideshow.find('tr.row-image-slideshow:first-child').find('.btn-sort.up').addClass('disabled');
        listSlideshow.find('tr.row-image-slideshow:last-child').find('.btn-sort.down').addClass('disabled');
    }

    //delete image on slideshow
    $('.tab-content').on('click','.btn-delete-image', function(e){
        e.preventDefault();
        var rowImage = $(this).parents('tr.row-image-slideshow'),
            index = rowImage.index();

        rowImage.remove();
        currentAnnotation.content.images.splice(index, 1);
        disabledPreview();
    });

/* Links */

    //add
    function addLinkRow(tbody, dataView){
        var tplLinkRow = getTemplate('#tpl-links-row');
        var output = Mustache.render(tplLinkRow, dataView);
        tbody.append(output);

    }

    $('.tab-content').on('click', '.add-link', function(e){
        e.preventDefault();
        var tbody = $(this).parents('tfoot').siblings('tbody');
        addLinkRow(tbody);
    });

    //delete
    $('.tab-content').on('click', '.delete-link', function(e){
        e.preventDefault();
        var row = $(this).parents('tr'),
            tbody = $(this).parents('tbody');

        row.remove();
        updateLinks(tbody);
    });
    
    //edit
    $('.tab-content').on('keyup', '.links-rows input', function(e){
        var tbody = $(this).parents('.links-rows');
        updateLinks(tbody);   
    });

    function updateLinks(tbody){
        links = new Array();

        $.each(tbody.find('tr'), function(k, v){
            var urlLink = $(v).find('.url-link').val(),
                titleLink = $(v).find('.title-link').val(),
                link = {
                    url : urlLink,
                    title : titleLink
                };
                links.push(link);

        });
        currentAnnotation.content.links = links;
        disabledPreview();
    }

    $('.tab-content').on('focus', '.url-link', function(){
        var td = $(this).parents('td');
        if(td.hasClass('error')) {
            td.removeClass('error');
            td.find('.help-inline').hide();
        }
    });
    
    $('.tab-content').on('blur', '.url-link', function(){
        var url = $(this).val(),
            td = $(this).parents('td');
        if(!isValidLink(url)){
            td.addClass('error');
            td.find('.help-inline').show();
        }
    });

    function isValidLink(url){
        return /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.test(url);
    }

    //autostart
    $('.tab-content').on('click', '.btn-autostart', function(){
        var autostart = $(this).attr('data-autostart');
        if(autostart == "true"){ autostart = true;}
        else {autostart = false;}
        disabledPreview();
        currentAnnotation.content.autostart = autostart;
    });

    //duration
    $('.tab-content').on('change keyup', '.config-slideshow input[name=duration]', function(){
        var value = $(this).val();
        if(!isNaN(value)){
            disabledPreview();
            currentAnnotation.content.slideduration = value * 1000;
        }
    });

/* Audio */

    $('.tab-content').on('keyup', '.annotation-audio-content input, .annotation-audio-content textarea', function(){
        var name = $(this).attr('name'),
            value = $(this).val();

        currentAnnotation.content[name] = value;
        disabledPreview();
    });

/* Save project */

    $('.btn-save-project').bind('click', function(e){
        e.preventDefault();
        if($(this).hasClass('disabled')) return;

        showAlertByClassName('save-load');
        var that = this;
        $(this).addClass('disabled');

        console.log(myProject.serialize());

        $.ajax({
            type: "POST",
            url: urlSaveProject,
            data: myProject.serialize(),
            contentType: "application/cinelab",
            headers: {
                "X-CSRFToken": tokenSaveProject
            },
            success: function(data, status, request){
                showAlertByClassName('save-ok');
                $('.btn-apercu-projet').removeClass('disabled');
                console.log('data : ', data);
                console.log('status : ', status);
                console.log('request : ', request);

            },
            error: function(jqXHR, textStatus, errorThrown){
                showAlertByClassName('save-error');
                //alert(gettext("Server error\nYour hashcut couldn't be published"));
            },
            complete : function(){
                $(that).removeClass('disabled');
            }
        });
    });
    
    //disabled preview
    function disabledPreview(){
        if(!$('.btn-apercu-projet').hasClass('disabled'))$('.btn-apercu-projet').addClass('disabled');
    }
    $(document).on('click', '.btn-apercu-projet.disabled', function(e){
        e.preventDefault();
    });

    //alert save info
    $('.alert').bind('close', function (e) {
        e.preventDefault();
        $(this).hide();
    });

    function showAlertByClassName(className){
        $('.alert').hide();
        $('.'+className).show();
    }

/* Config */

    //tagit
    function onTagItChange(e, ui) {
        var tagitType = $(this).attr('data-type'), 
            value = $(this).val();

        disabledPreview();

        if(tagitType == 'chapter'){
            var idChapter = $(this).parents('form').attr('data-chapter-id');
            currentChapter.keywords = value.split(',');
            $('#row-list-chapter-'+idChapter).find('.list-chapter-tags').text(value);
        }else{
            currentAnnotation.keywords = value.split(',');
        }
    }

    var tagitParam = {
        allowSpaces: true,
        afterTagRemoved : onTagItChange,
        afterTagAdded : onTagItChange
    }

    //CLEditor (wysiwyg) http://premiumsoftware.net/cleditor/docs/GettingStarted.html#optionalParameters
    var wysiwygConfig = {
        width:        450, 
        height:       250, 
        controls:     "bold italic underline strikethrough | font size " +
                        "style | color highlight removeformat | bullets numbering | source",
        fonts:        "Arial,Arial Black,Comic Sans MS,Courier New,Narrow,Garamond," +
                        "Georgia,Impact,Sans Serif,Serif,Tahoma,Trebuchet MS,Verdana",
        sizes:        "1,2,3,4,5,6,7",
        styles:       [["Paragraph", "<p>"], ["Header 2", "<h2>"],
                        ["Header 3", "<h3>"],  ["Header 4","<h4>"],  ["Header 5","<h5>"],
                        ["Header 6","<h6>"]],
        docType:      '<!DOCTYPE HTML>',
        bodyStyle:    "margin:0; font-family: 'Helvetica Neue',​Helvetica,​Arial,​sans-serif;",
        updateTextArea : updateWysiwigText,
        updateFrame: updateWysiwigText
    };

    function updateWysiwigText(text){
        disabledPreview();
        currentAnnotation.content.markup = "html";
        currentAnnotation.content.text = text;
        return text;
    }

    //slider
    function configSlider(data){
        return {
            range: true,
            values: [ data.begin.milliseconds, data.end.milliseconds ],
            min: 0,
            max: myMedia.duration.milliseconds,
            slide: function( event, ui ) {
                
                data.setBegin(ui.values[0]);
                data.setEnd(ui.values[1]);

                var idSlider = $(this).attr('data-id'),
                    wTimeline = $('.timeline-annotations').width(),
                    annotationTimeline = $('#annotation-timeline-'+ data.id),
                    width = Math.floor(data.getDuration() * wTimeline / myMedia.duration),
                    left = Math.floor(data.begin * wTimeline / myMedia.duration);

                $( '#'+ idSlider +'-begin span' ).html(data.begin.toString());
                $( '#'+ idSlider +'-begin span' ).attr('data-milliseconds', data.begin);
                $( '#'+ idSlider +'-duration' ).html(data.getDuration().toString());
                $( '#'+ idSlider +'-end span' ).html(data.end.toString());
                $( '#'+ idSlider +'-end span' ).attr('data-milliseconds', data.end);

                annotationTimeline.css({
                    left : left,
                    width :width
                });
            },
            start : function(){
                var idSlider = $(this).attr('data-id'),
                    annotationTimeline = $('#annotation-timeline-'+ data.id);
                annotationTimeline.css('z-index',100);
                disabledPreview();
            },
            stop : function(){
                renderAnnotation();
                refreshAnnotationDisplay(myMedia.getCurrentTime());
            }
        };
    }

    //unload
    $(window).on("beforeunload", onLeave);
    function onLeave(){
        if($('.btn-apercu-projet').hasClass('disabled')) return "You have unsaved changes";
    }

/* Tangles */
    var tangleMsPerPixel = 100,
        activeTangle,
        tangleStartX,
        tangleStartVal,
        tangleHasMoved;
    
    $(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) {
                if(activeTangle.hasClass('slider-tangle')){//annotation
                    renderAnnotation();
                    refreshAnnotationDisplay(myMedia.getCurrentTime());
                }
                $(".time-tangle").removeClass("active deactivate");
                activeTangle = undefined;
            }
        });

    //chapters
    $('.chapter-widget-info').on('mousedown', '.time-tangle', function(evt){
        activeTangle = $(this);
        activeTangle.addClass("active");
        tangleStartVal = +activeTangle.attr("data-milliseconds");
        tangleStartX = evt.pageX;
        tangleHasMoved = false;
        $(this).parents('td').siblings('td').find(".time-tangle").addClass("deactivate");
        return false;
    });

    function updateRenderChapter(chapterData){
        var segment = $('.chapter-segments li#'+chapterData.id),
            wChapterSegmentWrap = $('.chapter-segments').width(),
            wSegmentNew = chapterData.getDuration() * wChapterSegmentWrap / myMedia.duration,
            lSegmentNew = chapterData.begin * wChapterSegmentWrap / myMedia.duration,
            row = $('#row-list-chapter-'+chapterData.id),
            form = ($('#form-chapter-edit-'+chapterData.id).length) ? $('#form-chapter-edit-'+chapterData.id) : false;

        segment.css({
            width : wSegmentNew,
            left : lSegmentNew
        });

        row.find('.begin').text(chapterData.begin);
        console.log(chapterData.getDuration())
        row.find('.duration').text(chapterData.getDuration());
        row.find('.end').text(chapterData.end);

        if(form){
            form.find('.begin').text(chapterData.begin);
            form.find('.begin').attr('data-milliseconds',chapterData.begin);
            form.find('.duration').text(chapterData.getDuration());
            form.find('.end').text(chapterData.end);
            form.find('.end').attr('data-milliseconds',chapterData.end);
        }
    }

    function updateChapterDuration(val, chapterBefore, chapterAfter){

        if (val<=chapterAfter.end && val>=chapterBefore.begin && chapterAfter.end-val>secMiniChapter*1000 && val-chapterBefore.begin>secMiniChapter*1000) {
            disabledPreview();
            chapterAfter.setBegin(val);
            chapterBefore.setEnd(val);

            updateRenderChapter(chapterAfter);
            updateRenderChapter(chapterBefore);
        }
    }

    $('.chapter-widget-info').on('valuechange', '.tangle-start', function(evt, val){
        var indexChapter = _.indexOf(chapters, currentChapter);
        if(indexChapter == 0 || chapters.length<=1) return;
        
        var chapterBefore = chapters[indexChapter-1],
            chapterAfter = currentChapter;

        updateChapterDuration(val, chapterBefore, chapterAfter);
    });

    $('.chapter-widget-info').on('valuechange', '.tangle-end', function(evt, val){
        var indexChapter = _.indexOf(chapters, currentChapter);
        if(indexChapter == chapters.length-1 || chapters.length<=1) return;
        
        var chapterAfter = chapters[indexChapter+1],
            chapterBefore = currentChapter;

            updateChapterDuration(val, chapterBefore, chapterAfter);
    });

    //annotations
    $('.tab-content').on('mousedown', '.time-tangle', function(evt){
        activeTangle = $(this);
        activeTangle.addClass("active");
        tangleStartVal = +activeTangle.attr("data-milliseconds");
        tangleStartX = evt.pageX;
        tangleHasMoved = false;
        $(this).parents('td').siblings('td').find(".time-tangle").addClass("deactivate");
        return false;
    });

    $('.tab-content').on('valuechange', '.tangle-start', function(evt, val){
        var max = currentSlider.slider('values')[1],
            min = 0,
            beginOrEnd = 'begin';

        updateAnnotationDuration(val, min, max, beginOrEnd);
    });

    $('.tab-content').on('valuechange', '.tangle-end', function(evt, val){
        var max = myMedia.duration,
            min = currentSlider.slider('values')[0],
            beginOrEnd = 'end';

        updateAnnotationDuration(val, min, max, beginOrEnd);
    });

    function updateAnnotationDuration(val, min, max, beginOrEnd){
        var idAnnotation = currentAnnotation.id,
            tabAnnotation = $('#tab-annotation-'+idAnnotation),
            spanTangleStart = tabAnnotation.find('.tangle-start'),
            spanTangleEnd = tabAnnotation.find('.tangle-end'),
            spanDuration = tabAnnotation.find('#'+idAnnotation+'-duration');

        if(val<max && val>min){
            disabledPreview();
            if(beginOrEnd == 'begin'){currentAnnotation.setBegin(val);}
            if(beginOrEnd == 'end'){currentAnnotation.setEnd(val);}

            spanTangleStart.html(currentAnnotation.begin.toString());
            spanTangleStart.attr('data-milliseconds', currentAnnotation.begin);
            spanDuration.html(currentAnnotation.getDuration().toString());
            spanTangleEnd.html(currentAnnotation.end.toString());
            spanTangleEnd.attr('data-milliseconds', currentAnnotation.end);

            var wTimeline = $('.timeline-annotations').width(),
            annotationTimeline = $('#annotation-timeline-'+ idAnnotation),
            width = Math.floor(currentAnnotation.getDuration() * wTimeline / myMedia.duration),
            left = Math.floor(currentAnnotation.begin * wTimeline / myMedia.duration);

            annotationTimeline.css({
                left : left,
                width :width
            });
            currentSlider.slider('values', [currentAnnotation.begin, currentAnnotation.end])
        }
    }

});//ready

/* Utilitys */

Array.prototype.move = function (old_index, new_index) {
    if (new_index >= this.length) {
        var k = new_index - this.length;
        while ((k--) + 1) {
            this.push(undefined);
        }
    }
    this.splice(new_index, 0, this.splice(old_index, 1)[0]);
    return this; 
};

function getVideoPlayer(src, videoWrap){

    var youtubeTemplate = _.template(
        '<iframe width="<%- width %>" height="<%- height %>" src="http://www.youtube.com/embed/<%- ytid %>?rel=0&autoplay=<%- autoplay %>" frameborder="0"></iframe>'
    );
    
    var htmlTemplate = _.template(
        '<<%- type %> width="<%- width %>" controls="true" autoplay="<%- autoplay %>" src="<%- src %>"/>'
    );
    
    var mediaW = 460,
        mediaH = 345,
        autoplay = false;

    
    if (/^(https?:\/\/)?(www\.)?youtu\.?be/.test(src)) {
        var urlparts = src.split(/[?&]/g),
            ytid = "",
            vtest = /^v=/;
        urlparts.slice(1).forEach(function(p) {
            if (/^v=/.test(p)) {
                ytid = p.replace(vtest,"");
            }
        });
        if (!ytid) {
            ytid = (urlparts[0].match(/[^\/]+$/) || [""])[0];
        }
        videoWrap.html(youtubeTemplate({
            ytid: ytid,
            width: mediaW,
            height: mediaH,
            autoplay: autoplay
        }));
        return;
    }
    
    if (/^(https?:\/\/)?(www\.)?vimeo/.test(src)) {
        $.ajax({
            url: "http://vimeo.com/api/oembed.json",
            dataType: "jsonp",
            data: {
                width: mediaW,
                height: mediaH,
                url: src,
                autoplay: autoplay,
                color: "be4477",
                portrait: false,
                title: false,
                byline: false
            },
            success: function(data) {
                videoWrap.html(data.html);
            }
        });
        return;
    }
    
    if (/^(https?:\/\/)?(www\.)?dailymotion/.test(src)) {
        $.ajax({
            url: "http://www.dailymotion.com/services/oembed",
            dataType: "jsonp",
            data: {
                format: "json",
                maxwidth: mediaW,
                maxheight: mediaH,
                url: src
            },
            success: function(data) {
                videoWrap.html(data.html);
            }
        });
        return;
    }
    
    if (/^(https?:\/\/)?(www\.)?soundcloud\.com/.test(src)) {
        $.ajax({
            url: "http://soundcloud.com/oembed",
            dataType: "jsonp",
            data: {
                format: "js",
                show_comments: false,
                auto_play: autoplay,
                show_artwork: false,
                url: src,
                color: "63be6c"
            },
            success: function(data) {
                videoWrap.html(data.html);
            }
        });
        return;
    }
    
    var extension = (src.match(/\.([\d\w]+)$/) || ["",""])[1],
        mimetype = 'video' + "/" + extension,
        fallbacks = { "video/webm": "mp4", "video/mp4": "webm" },
        canPlay = document.createElement("video").canPlayType(mimetype);
    
    if (!canPlay) {
        src = src.replace(/\.[\d\w]+$/,"." + fallbacks[mimetype]);
    }
    
    console.log(mimetype, canPlay, src);
    
    videoWrap.html(htmlTemplate({
        type: 'video',
        src: src,
        width: mediaW,
        height: mediaH,
        autoplay: "" + autoplay
    }));
                
}//getVideoPlayer