integration/js/edition.js
changeset 115 9144b17b390e
parent 111 c0e4d761bcb6
child 116 fedc0d054b55
equal deleted inserted replaced
111:c0e4d761bcb6 115:9144b17b390e
     1 var myMedia = undefined,
       
     2     currentChapter = undefined,
       
     3     currentAnnotation = undefined,
       
     4     currentSlider = undefined,
       
     5     secMiniChapter = 10;
       
     6 
       
     7 
       
     8 
       
     9 
       
    10 $(function(){
     1 $(function(){
    11 
     2 
       
     3     var myMedia = undefined,
       
     4         currentChapter = undefined,
       
     5         currentAnnotation = undefined,
       
     6         currentSlider = undefined,
       
     7         secMiniChapter = 10;
       
     8 
       
     9 /* Colors */
    12     var annotationsColors = {
    10     var annotationsColors = {
    13         'video' : '#BE4477',
    11         'video' : '#BE4477',
    14         'text' : '#5E90CB',
    12         'text' : '#5E90CB',
    15         'slideshow' : '#F69058',
    13         'slideshow' : '#F69058',
    16         'audio' : '#63BE6C',
    14         'audio' : '#63BE6C',
    17         'links' : '#8985BB'
    15         'links' : '#8985BB'
    18     }
    16         },
    19 
    17         colorsRangeIndex = 0,
    20     var global = {
    18         colorsRange = [
    21         colorsIndex : 0,
    19             '#FF6138', '#FFFF9D', '#BEEB9F', '#79BD8F',  '#00A388',
    22         colors : 
       
    23             ['#FF6138', '#FFFF9D', '#BEEB9F', '#79BD8F',  '#00A388',
       
    24              '#1695A3', '#ACF0F2', '#F3FFE2', '#EB7F00', '#FF8000',
    20              '#1695A3', '#ACF0F2', '#F3FFE2', '#EB7F00', '#FF8000',
    25              '#FFD933', '#CCCC52', '#8FB359', '#FFD393', '#F54F29'
    21              '#FFD933', '#CCCC52', '#8FB359', '#FFD393', '#F54F29'
    26             ]
    22         ];
    27     };
    23 
       
    24     function getRandomColor(){
       
    25         return colorsRange[(colorsRangeIndex<colorsRange.length) ? colorsRangeIndex++ : (colorsRangeIndex=0)];
       
    26     }
    28 
    27 
    29     function getTemplate(idTpl){
    28     function getTemplate(idTpl){
    30         return $('#templates').find(idTpl).html();
    29         return $('#templates').find(idTpl).html();
    31     }
    30     }
    32 
    31 
    36         $(".project-title").text(myProject.title);
    35         $(".project-title").text(myProject.title);
    37         $('.project-title-nav').text(myProject.title);
    36         $('.project-title-nav').text(myProject.title);
    38 
    37 
    39         myMedia = myProject.getCurrentMedia();
    38         myMedia = myProject.getCurrentMedia();
    40 
    39 
       
    40         //load Chapitre
    41         var anntypes = myProject.getAnnotationTypes().searchByTitle("chapitrage");
    41         var anntypes = myProject.getAnnotationTypes().searchByTitle("chapitrage");
    42         if (!anntypes.length) {
    42         if (!anntypes.length) {
    43             chapterAnnType = new IriSP.Model.AnnotationType(false, myProject);
    43             chapterAnnType = new IriSP.Model.AnnotationType(false, myProject);
    44             chapterAnnType.title = "chapitrage";
    44             chapterAnnType.title = "chapitrage";
    45             myProject.getAnnotationTypes().push(chapterAnnType);
    45             myProject.getAnnotationTypes().push(chapterAnnType);
    46         } else {
    46         } else {
    47             chapterAnnType = anntypes[0];
    47             chapterAnnType = anntypes[0];
    48         }
    48         }
    49 
    49 
    50         //load Chapitre
       
    51         chapters = chapterAnnType.getAnnotations();
    50         chapters = chapterAnnType.getAnnotations();
    52         if(!chapters.length){
    51         if(!chapters.length){
    53             var dataChapter = {
    52             var dataChapter = {
    54                 title : '',
    53                 title : '',
    55                 begin : 0,
    54                 begin : 0,
    81             v.type = type;
    80             v.type = type;
    82             v.color = annotationsColors[type];
    81             v.color = annotationsColors[type];
    83         });
    82         });
    84         renderAnnotation();
    83         renderAnnotation();
    85 
    84 
    86 
    85         //player
    87         IriSP.htmlPlayer(
    86         IriSP.htmlPlayer(
    88             myMedia,
    87             myMedia,
    89             $(".main-video"),
    88             $(".main-video"),
    90             {
    89             {
    91                 width: 460,
    90                 width: 460,
   103                 }
   102                 }
   104             }
   103             }
   105         );
   104         );
   106 
   105 
   107         myMedia.on("timeupdate", function(t) {
   106         myMedia.on("timeupdate", function(t) {
   108 
       
   109             //curseur chapitre
   107             //curseur chapitre
   110             var wContainer = $('.chapitre-cut-wrap').width() - 1,
   108             var wContainer = $('.chapitre-cut-wrap').width() - 1,
   111                 pos = wContainer * t / myMedia.duration,
   109                 pos = wContainer * t / myMedia.duration,
   112                 btnCutChapter = $('.btn-cut-chapter'),
   110                 btnCutChapter = $('.btn-cut-chapter'),
   113                 wBtnCutChapter = btnCutChapter.outerWidth();
   111                 wBtnCutChapter = btnCutChapter.outerWidth();
   116             if(pos+wBtnCutChapter>wContainer){
   114             if(pos+wBtnCutChapter>wContainer){
   117                 btnCutChapter.css("left",(pos - wBtnCutChapter));
   115                 btnCutChapter.css("left",(pos - wBtnCutChapter));
   118             }else{
   116             }else{
   119                 btnCutChapter.css("left",pos);
   117                 btnCutChapter.css("left",pos);
   120             }
   118             }
   121             $('.info-time').text(t)
   119             $('.info-time').text(t);
   122             //annotations view
   120 
       
   121             //display annotations
   123             refreshAnnotationDisplay(t);
   122             refreshAnnotationDisplay(t);
   124 
       
   125         });//timeupdate
   123         });//timeupdate
   126         
   124         
   127     });//myProject.onLoad
   125     });//myProject.onLoad
   128 
   126 
   129 /* Display annotation in timeline */
   127 /* Display annotation in timeline */
   130 
   128 
   131     //survol
   129     //hover
   132     $(document).on('mouseover', '.timeline-annotations .annotation, #list-annotations-rows tr, .item-display-annotation' , function(){
   130     $(document).on('mouseover', '.timeline-annotations .annotation, #list-annotations-rows tr, .item-display-annotation' , function(){
   133         if(!$(this).hasClass('shadow')) {
   131         if(!$(this).hasClass('shadow')) {
   134             var idAnnotation = $(this).attr('data-id');
   132             var idAnnotation = $(this).attr('data-id');
   135             $('#annotation-timeline-'+idAnnotation+', #row-list-annotation-'+idAnnotation+', #item-current-annotation-'+idAnnotation).addClass('shadow');
   133             $('#annotation-timeline-'+idAnnotation+', #row-list-annotation-'+idAnnotation+', #item-current-annotation-'+idAnnotation).addClass('shadow');
   136         }
   134         }
   212             if(typeDelete == 'chapter') deleteChapter(idAnnotation);
   210             if(typeDelete == 'chapter') deleteChapter(idAnnotation);
   213             if(typeDelete == 'annotation') deleteAnnotation(idAnnotation);
   211             if(typeDelete == 'annotation') deleteAnnotation(idAnnotation);
   214         }
   212         }
   215     });
   213     });
   216 
   214 
   217 
       
   218 
       
   219 /* Title project */
   215 /* Title project */
   220 
   216 
   221     $(document).on('click', '.project-title-editor i, .project-title', function () {
   217     $(document).on('click', '.project-title-editor i, .project-title', function () {
   222         
   218         
   223         var html = $('.project-title').html();
   219         var html = $('.project-title').html();
   245         e.preventDefault();
   241         e.preventDefault();
   246         var idChapter = $(this).attr('data-chapter-id');
   242         var idChapter = $(this).attr('data-chapter-id');
   247         loadFormChapter(idChapter);
   243         loadFormChapter(idChapter);
   248     });
   244     });
   249 
   245 
   250     $('.chapter-segments').on('click', 'li', function(){
       
   251         var idChapter = $(this).attr('id');
       
   252         loadFormChapter(idChapter);
       
   253     });
       
   254 
       
   255     $('.chapter-widget-info').on('keyup', 'input[name=title], textarea', function(e){
   246     $('.chapter-widget-info').on('keyup', 'input[name=title], textarea', function(e){
   256         var name = $(this).attr('name'),
   247         var name = $(this).attr('name'),
   257             value = $(this).val();
   248             value = $(this).val();
   258         currentChapter[name] = value;
   249         currentChapter[name] = value;
   259         if(name == 'title'){
   250         if(name == 'title'){
   263             $(this).parents('form').find('.btn-delete-chapter').attr('data-title', value);
   254             $(this).parents('form').find('.btn-delete-chapter').attr('data-title', value);
   264         }
   255         }
   265         disabledPreview();
   256         disabledPreview();
   266     });
   257     });
   267 
   258 
       
   259     //form chapter
       
   260     $('.chapter-segments').on('click', 'li', function(){
       
   261         var idChapter = $(this).attr('id');
       
   262         loadFormChapter(idChapter);
       
   263     });
       
   264 
   268     function loadFormChapter(idChapter){
   265     function loadFormChapter(idChapter){
   269         currentChapter = _.find(chapters, function(c){ return c.id == idChapter; });
   266         currentChapter = _.find(chapters, function(c){ return c.id == idChapter; });
   270         var chapterWrap = $('.chapter-widget-info'),
   267         var chapterWrap = $('.chapter-widget-info'),
   271             indexChapter = _.indexOf(chapters, currentChapter),
   268             indexChapter = _.indexOf(chapters, currentChapter),
   272             beginTangle = (indexChapter>0) ? true : false,
   269             beginTangle = (indexChapter>0) ? true : false,
   281             chapterWrap.find('.tag-it').tagit(tagitParam);
   278             chapterWrap.find('.tag-it').tagit(tagitParam);
   282 
   279 
   283         myMedia.setCurrentTime(currentChapter.begin);
   280         myMedia.setCurrentTime(currentChapter.begin);
   284     }
   281     }
   285 
   282 
       
   283     //close chapter form
       
   284     $(document).on('click', '.btn-ok-chapter', function(e){
       
   285         e.preventDefault();
       
   286         $('.form-chapter-edit').remove();
       
   287     });
       
   288 
   286     //delete chapter
   289     //delete chapter
   287     $(document).on('click', '.btn-delete-chapter', function(e){
   290     $(document).on('click', '.btn-delete-chapter', function(e){
   288         e.preventDefault();
   291         e.preventDefault();
   289 
   292 
   290         if(chapters.length == 1){
   293         if(chapters.length == 1){
   302             urlDelete = $(this).attr('href');
   305             urlDelete = $(this).attr('href');
   303         $("#modal-confirm #btn-delete-modal").attr('href', urlDelete).focus();
   306         $("#modal-confirm #btn-delete-modal").attr('href', urlDelete).focus();
   304         $("#modal-confirm .modal-body").find('.titleMedia').text(titleMedia);
   307         $("#modal-confirm .modal-body").find('.titleMedia').text(titleMedia);
   305         $("#modal-confirm").modal('show');
   308         $("#modal-confirm").modal('show');
   306 
   309 
   307     });
       
   308     $(document).on('click', '.btn-ok-chapter', function(e){
       
   309         e.preventDefault();
       
   310         $('.form-chapter-edit').remove();
       
   311     });
   310     });
   312 
   311 
   313     function deleteChapter(idChapter){
   312     function deleteChapter(idChapter){
   314         
   313         
   315         $("#modal-confirm").modal('hide');
   314         $("#modal-confirm").modal('hide');
   332             $('#form-chapter-edit-'+idChapter).remove();
   331             $('#form-chapter-edit-'+idChapter).remove();
   333         }
   332         }
   334         disabledPreview();
   333         disabledPreview();
   335     }
   334     }
   336 
   335 
   337     function getRandomColor(){
   336     //new chapter
   338         return global.colors[(global.colorsIndex<global.colors.length) ? global.colorsIndex++ : (global.colorsIndex=0)];
       
   339     }
       
   340     //nouveau chapitre
       
   341     function newChapter(dataChapter, render){
   337     function newChapter(dataChapter, render){
   342         var chapter = new IriSP.Model.Annotation(false, myProject);
   338         var chapter = new IriSP.Model.Annotation(false, myProject);
   343             chapter.setMedia(myMedia.id);
   339             chapter.setMedia(myMedia.id);
   344             chapter.setBegin(dataChapter.begin);
   340             chapter.setBegin(dataChapter.begin);
   345             chapter.setEnd(dataChapter.end);
   341             chapter.setEnd(dataChapter.end);
   375             description : '',
   371             description : '',
   376             keywords : []
   372             keywords : []
   377         };
   373         };
   378 
   374 
   379         newChapter(dataChapter, true);
   375         newChapter(dataChapter, true);
   380 
       
   381     });
   376     });
   382     
   377     
   383     function organizeNewChapter(beginNew){
   378     function organizeNewChapter(beginNew){
   384 
   379 
   385         var returnEnd = false;
   380         var returnEnd = false;
   453         disabledPreview();
   448         disabledPreview();
   454 
   449 
   455         return annotation;
   450         return annotation;
   456     }
   451     }
   457 
   452 
   458     function renderAnnotation(){
   453     //annotation content data init
   459         
       
   460 
       
   461         var timeline = $('.timeline-annotations'),
       
   462             wTimeline = timeline.width(),
       
   463             annotationList = $('#list-annotations-rows');
       
   464 
       
   465         annotations = annotations.sortBy(function(c){
       
   466             return c.begin;
       
   467         });
       
   468 
       
   469         timeline.empty().append('<li>');
       
   470         annotationList.empty();
       
   471 
       
   472         $.each(annotations, function(k, v){
       
   473 
       
   474             //timeline
       
   475             var width = Math.floor(v.getDuration() * wTimeline / myMedia.duration),
       
   476                 left = Math.floor(v.begin * wTimeline / myMedia.duration),
       
   477                 dataAnntim = {
       
   478                     left : left,
       
   479                     width : width,
       
   480                     color : v.color,
       
   481                     id : v.id,
       
   482                     title : v.title
       
   483                 },
       
   484                 segment = getTemplate('#tpl-annotation-in-timeline');
       
   485                 segment = Mustache.render(segment, dataAnntim);
       
   486 
       
   487 
       
   488             var isInTimeline = false;
       
   489             $.each(timeline.find('li'), function(a, b){
       
   490                 if(isInTimeline) return;
       
   491                 var row = $(this);
       
   492                 if(row.children().length){
       
   493                     var canBeInRow = true;
       
   494                     $.each(row.find('.annotation'), function(c, d){
       
   495                         var oAL = parseInt($(d).css('left')),
       
   496                             oAR = oAL + $(d).width(),
       
   497                             segmentR = left + width;
       
   498                         if(oAL<=left && oAR>=left || oAL<=segmentR && oAR>= segmentR){
       
   499                             canBeInRow = false;
       
   500                         }
       
   501                     });
       
   502                     if(canBeInRow){
       
   503                         row.append(segment);
       
   504                         isInTimeline = true;
       
   505                     }
       
   506                 }else{
       
   507                     row.append(segment);
       
   508                     isInTimeline = true;
       
   509                 }
       
   510             });
       
   511 
       
   512             if(!isInTimeline){
       
   513                 timeline.append('<li>');
       
   514                 timeline.find('li:last-child').append(segment);
       
   515             }
       
   516             
       
   517            
       
   518             //liste
       
   519                 v.iconTab = getIcon(v.type);
       
   520                 var tplAnnotationRow = getTemplate('#tpl-list-annotation-row');
       
   521                 tplAnnotationRow = Mustache.render(tplAnnotationRow, v);
       
   522                 annotationList.append(tplAnnotationRow);
       
   523 
       
   524         });
       
   525 
       
   526 
       
   527     }//renderAnnotation
       
   528 
       
   529     //edit annotation
       
   530     $('#list-annotations').on('click', 'a.btn-edit-annotation', function(e){
       
   531         e.preventDefault();
       
   532         
       
   533         var idAnnotation = $(this).attr('data-id');
       
   534         //si il est déjà ouvert
       
   535         if($('#tab-annotation-'+idAnnotation).length){
       
   536             $('a[href=#tab-annotation-'+idAnnotation+']').tab('show');
       
   537         }else{
       
   538             var data = _.find(annotations, function(c){ return c.id == idAnnotation; });
       
   539             openTab(data.type, data);
       
   540         } 
       
   541     });
       
   542 
       
   543     $('.tab-content').on('keyup', '.form-info-general-annotation input[name=title], .form-info-general-annotation textarea', function(e){
       
   544         
       
   545         var name = $(this).attr('name'),
       
   546             value = $(this).val();
       
   547         currentAnnotation[name] = value;
       
   548         if(name == 'title'){
       
   549             var idAnnotation = $(this).parents('form').attr('data-id');
       
   550             $('#onglet-title-'+idAnnotation).text(value);
       
   551             $(this).parents('form').find('.btn-delete-annotation').attr('data-title', value);
       
   552             $('#annotation-timeline-'+ idAnnotation).attr('title', value);
       
   553             $('#annotation-timeline-'+ idAnnotation+' span').text(value);
       
   554         }
       
   555         disabledPreview();
       
   556     });
       
   557 
       
   558     //delete annotation
       
   559     $(document).on('click','.btn-delete-annotation', function(e){
       
   560         e.preventDefault();
       
   561 
       
   562         var idAnnotation = $(this).attr('data-id'),
       
   563             btnDeleteModal = $("#modal-confirm #btn-delete-modal");
       
   564         btnDeleteModal.attr('data-type-delete', 'annotation');
       
   565         btnDeleteModal.attr('data-id', idAnnotation);
       
   566     });
       
   567 
       
   568     function deleteAnnotation(idAnnotation){
       
   569         
       
   570         $("#modal-confirm").modal('hide');
       
   571         annotations.removeId(idAnnotation);
       
   572         myProject.getAnnotations().removeId(idAnnotation, true);
       
   573         closeTab(idAnnotation);
       
   574         renderAnnotation();
       
   575         disabledPreview();
       
   576     }
       
   577 
       
   578 /* Tab */
       
   579 
       
   580     $('#onglet-annotations').on('click', 'a', function(e){
       
   581         e.preventDefault();
       
   582         $(this).tab('show');
       
   583     });
       
   584 
       
   585     //ouvrir tab
       
   586     $(document).on('click', '.open-tab', function(e){
       
   587         e.preventDefault();
       
   588         var type = $(this).attr('data-type');
       
   589         openTab(type);
       
   590     });
       
   591 
       
   592     function openTab(type, data){
       
   593         
       
   594         var dataView, isNew = false;
       
   595         if(_.isUndefined(data)){//nouveau
       
   596 
       
   597             var currentTimePlusUnMin = 60 * 1000 + myMedia.currentTime,
       
   598                 endAnnotation = (currentTimePlusUnMin<myMedia.duration) ? currentTimePlusUnMin : myMedia.duration;
       
   599             var dataAnnotation = {
       
   600                 title : '',
       
   601                 begin : myMedia.currentTime,
       
   602                 end : endAnnotation,
       
   603                 description : '',
       
   604                 type : type,
       
   605                 keywords : []
       
   606             };
       
   607             dataView = newAnnotation(dataAnnotation);
       
   608             renderAnnotation();
       
   609             isNew = true;
       
   610         }else{//édition
       
   611             dataView = data;
       
   612         }
       
   613 
       
   614         var idAnnotation = dataView.id,
       
   615             tabContent = $('<div class="tab-pane" id="tab-annotation-'+idAnnotation+'"></div>'),
       
   616             iconTab;
       
   617 
       
   618         currentAnnotation = _.find(annotations, function(c){ return c.id == idAnnotation; });
       
   619         showCurrentAnnotationInTimeline(idAnnotation);
       
   620             //head commun à tous
       
   621             var tplHead = getTemplate('#tpl-head');
       
   622             var output = Mustache.render(tplHead, dataView);
       
   623             $(tabContent).append(output);
       
   624             $(tabContent).find(".slider-duration").slider(configSlider(dataView));
       
   625             currentSlider = $(tabContent).find(".slider-duration");
       
   626             $(tabContent).find(".ui-slider-range.ui-widget-header.ui-corner-all").css('background', dataView.color);
       
   627             $(tabContent).find('.tag-it').tagit(tagitParam);
       
   628             
       
   629             //type
       
   630             var viewType = {
       
   631                 id : idAnnotation,
       
   632                 content : dataView.content
       
   633             };
       
   634             var tpl = getTemplate('#tpl-'+type);
       
   635 
       
   636             tpl = Mustache.render(tpl, viewType);
       
   637             $(tabContent).append(tpl);
       
   638             $('.tab-content').append(tabContent);
       
   639 
       
   640             //particularité selon type
       
   641             switch(type){
       
   642                 case 'audio':
       
   643                     break;
       
   644                 case 'video':
       
   645                     var labelModify = $(tabContent).find('.label-modify-video'),
       
   646                         labelAdd = $(tabContent).find('.label-add-video');
       
   647                     if(viewType.content.url != ""){
       
   648                         var videoWrap = $(tabContent).find('.annotation-video-content');
       
   649                         renderVideoInfo(videoWrap, viewType.content);
       
   650                         labelModify.show();
       
   651 
       
   652                     }else{
       
   653                         labelAdd.show();
       
   654                     }
       
   655                     break;
       
   656                 case 'text': 
       
   657                     var cledit = $(tabContent).find('.wysiwyg').cleditor(wysiwygConfig)[0];
       
   658                     break;
       
   659                 case 'links': 
       
   660                     var tbody = $(tabContent).find('tbody.links-rows'),
       
   661                         links = viewType.content.links;
       
   662                     if(links.length){
       
   663                         $.each(links, function(k,v){
       
   664                             addLinkRow(tbody, v);
       
   665                         });
       
   666                     }else{//il n'y a pas de lien on en ajoute 1
       
   667                         addLinkRow(tbody);
       
   668                     }
       
   669                     break;
       
   670 
       
   671                 case 'slideshow': 
       
   672                     console.log(currentAnnotation)
       
   673                     $(tabContent).find('.number-spin').val(dataView.content.slideduration/1000);
       
   674                     $(tabContent).find('.number-spin').spin(spinParam);
       
   675                     $(tabContent).find('.ui-sortable').sortable({
       
   676                         start: function (event, ui) {
       
   677                             $(ui.item).data("startindex", ui.item.index());
       
   678                         },
       
   679                         stop : function(event, ui){
       
   680                             disabledBtnSortable($(this));
       
   681                         },
       
   682                         update : function(event, ui){
       
   683                             var oldIndex = ui.item.data("startindex"),
       
   684                                 newIndex = ui.item.index();
       
   685                             currentAnnotation.content.images.move(oldIndex, newIndex);
       
   686                         },
       
   687                     });
       
   688                     var diaporama = $(tabContent).find('#diaporama-'+idAnnotation),
       
   689                         images = viewType.content.images;
       
   690                     if(images.length){
       
   691                         $.each(images, function(k,v){
       
   692                             addImageToDiaporama(diaporama, v);
       
   693                         });
       
   694                     }
       
   695                     break;
       
   696             }
       
   697 
       
   698             dataView.iconTab = getIcon(type);
       
   699             var tplOnglet = getTemplate('#tpl-onglet');
       
   700             var onglet = Mustache.render(tplOnglet, dataView);
       
   701 
       
   702             $(".nav-tabs li:last-child").after(onglet);
       
   703             $('a[href=#tab-annotation-'+idAnnotation+']').tab('show');
       
   704 
       
   705             if(isNew){$(tabContent).find('.head-title').focus();}
       
   706   
       
   707     }//openTab()
       
   708 
       
   709     function getIcon(type){
       
   710         var icon;
       
   711         switch(type){
       
   712             case 'audio': icon = 'volume-up';
       
   713                 break;
       
   714             case 'video': icon = 'film';
       
   715                 break;
       
   716             case 'text': icon = 'align-left';
       
   717                 break;
       
   718             case 'html': icon = 'code';
       
   719                 break;
       
   720             case 'links': icon = 'link';
       
   721                 break;
       
   722             case 'slideshow': icon = 'picture';
       
   723                 break;
       
   724         }
       
   725         return icon;
       
   726     }
       
   727 
       
   728     //définit currentAnnotation quand la tab s'ouvre
       
   729     $('#onglet-annotations').on('show', 'a[data-toggle="annotation"]', function (e) {
       
   730         var idAnnotation = $(e.target).attr('data-id');
       
   731         currentAnnotation = _.find(annotations, function(c){ return c.id == idAnnotation; });
       
   732         currentSlider = $('#tab-annotation-'+idAnnotation).find(".slider-duration");
       
   733         showCurrentAnnotationInTimeline(idAnnotation);
       
   734     });
       
   735 
       
   736     //rafraichit annotations au retour sur la liste
       
   737     $('#onglet-annotations').on('show', 'a[data-toggle="list-annotations"]', function (e) {
       
   738         currentAnnotation = undefined;
       
   739         renderAnnotation();
       
   740     });
       
   741 
       
   742     //fermer tab
       
   743     $('#onglet-annotations').on('click', 'span.close-tab', function(e){
       
   744         e.preventDefault();e.stopPropagation();
       
   745         var idAnnotation = $(this).parents('a').attr('data-id');
       
   746         closeTab(idAnnotation);
       
   747     });
       
   748 
       
   749     $('.tab-content').on('click', '.btn-save-annotation', function(e){
       
   750         e.preventDefault();
       
   751         var idAnnotation = $(this).attr('data-id');
       
   752         closeTab(idAnnotation);
       
   753     });
       
   754 
       
   755     function closeTab(idAnnotation){
       
   756         $('#onglet-'+idAnnotation).remove();
       
   757         $('.tab-content #tab-annotation-'+idAnnotation).remove();
       
   758         $('#tab-list-annotation').tab('show');
       
   759     }
       
   760 
       
   761     //video
       
   762     function renderVideoInfo(videoWrap, dataVideo){
       
   763     
       
   764         var tplVideo = getTemplate('#tpl-video-row');
       
   765         tplVideo = Mustache.render(tplVideo, dataVideo);
       
   766         
       
   767         videoWrap.empty().append(tplVideo);
       
   768 
       
   769         videoWrap = videoWrap.find(".video-container");
       
   770         getVideoPlayer(dataVideo.url, videoWrap);
       
   771      
       
   772     }
       
   773     $('.popup').on('click', '.bibliotheque-video a:not(.pagination a)', function(e){
       
   774         e.preventDefault();
       
   775 
       
   776         var url = $(this).attr('data-url'),
       
   777             title = $(this).attr('data-title'),
       
   778             description = $(this).attr('data-description');
       
   779 
       
   780         currentAnnotation.content.url = url;
       
   781         currentAnnotation.content.title = title;
       
   782         currentAnnotation.content.description = description;
       
   783 
       
   784         $('.popup').modal('hide');
       
   785 
       
   786         var videoWrap = $('#tab-annotation-'+currentAnnotation.id).find('.annotation-video-content');
       
   787         renderVideoInfo(videoWrap, currentAnnotation.content);
       
   788 
       
   789         var labelModify = $('#tab-annotation-'+currentAnnotation.id).find('.label-modify-video'),
       
   790             labelAdd = $('#tab-annotation-'+currentAnnotation.id).find('.label-add-video');
       
   791 
       
   792         labelModify.show();
       
   793         labelAdd.hide();
       
   794 
       
   795         disabledPreview();
       
   796     });
       
   797 
       
   798 /* Slideshow */
       
   799 
       
   800     //bibliotheque
       
   801     $('.popup').on('click', '.bibliotheque-image a:not(.pagination a)', function(e){
       
   802         e.preventDefault();
       
   803 
       
   804         var url = $(this).attr('data-url'),
       
   805             title = $(this).attr('data-title'),
       
   806             description = $(this).attr('data-description'),
       
   807             image = {
       
   808                 id : currentAnnotation.id,
       
   809                 url : url,
       
   810                 title : title,
       
   811                 description : description
       
   812             };
       
   813         currentAnnotation.content.images.push(image);
       
   814 
       
   815         var listDiaporama = $('#diaporama-'+currentAnnotation.id);
       
   816         addImageToDiaporama(listDiaporama, image);
       
   817         $('.popup').modal('hide'); 
       
   818         disabledPreview();
       
   819     });
       
   820 
       
   821     function addImageToDiaporama(diaporama, dataView){
       
   822    
       
   823         var tplDiapo = getTemplate('#tpl-diaporama-row');
       
   824         tplDiapo = Mustache.render(tplDiapo, dataView);
       
   825         diaporama.append(tplDiapo);
       
   826         disabledBtnSortable(diaporama);
       
   827     
       
   828     };
       
   829 
       
   830     //edit title / description
       
   831     $('.tab-content').on('click', '.title-slideshow-row, .description-slideshow-row, .video-title-edit, .video-description-edit', function(){
       
   832         if($(this).find('input').length) return;
       
   833         var html = $(this).find('span').html(),
       
   834             inputType = $(this).attr('data-input'),
       
   835             name = $(this).attr('data-name'),
       
   836             input = $('<'+inputType+'>').attr('name', name);
       
   837         input.val(html);
       
   838         $(this).find('span').replaceWith(input);
       
   839         input.focus().keypress(function(e){
       
   840             code = (e.keyCode ? e.keyCode : e.which);
       
   841             if (code == 13) $(this).blur();
       
   842         });
       
   843     });
       
   844 
       
   845     $(document).on('blur', '.title-slideshow-row input, .description-slideshow-row textarea', function(){
       
   846         var newValue = $(this).val(),
       
   847             name = $(this).attr('name'),
       
   848             span = $('<span>').html(newValue),
       
   849             indexRow = $(this).parents('.row-image-diaporama').index();
       
   850         $(this).replaceWith(span);
       
   851         currentAnnotation.content.images[indexRow][name] = newValue;
       
   852         disabledPreview();
       
   853     });
       
   854 
       
   855     $(document).on('blur', '.video-title-edit input, .video-description-edit textarea', function(){
       
   856         var newValue = $(this).val(),
       
   857             name = $(this).attr('name'),
       
   858             span = $('<span>').html(newValue);
       
   859         $(this).replaceWith(span);
       
   860         currentAnnotation.content[name] = newValue;
       
   861         disabledPreview();
       
   862     });
       
   863 
       
   864     //bouton up / down
       
   865     $(document).on('click', '.ui-sortable .btn-sort', function(e){
       
   866         e.preventDefault();
       
   867         var row = $(this).parents('tr.row-image-diaporama'),
       
   868             oldIndex = row.index(),
       
   869             listDiaporama = $(this).parents('.list-image-diaporama');
       
   870 
       
   871         if($(this).hasClass('down'))
       
   872             row.insertAfter(row.next());
       
   873         else if($(this).hasClass('up'))
       
   874             row.insertBefore(row.prev());
       
   875 
       
   876         var newIndex = row.index();
       
   877         currentAnnotation.content.images.move(oldIndex, newIndex);
       
   878 
       
   879         disabledBtnSortable(listDiaporama);
       
   880         disabledPreview();
       
   881     });
       
   882 
       
   883     $('.tab-content').on('click','.btn-delete-image', function(e){
       
   884         e.preventDefault();
       
   885         var rowImage = $(this).parents('tr.row-image-diaporama'),
       
   886             index = rowImage.index();
       
   887 
       
   888         rowImage.remove();
       
   889         currentAnnotation.content.images.splice(index, 1);
       
   890         disabledPreview();
       
   891     });
       
   892 
       
   893     function disabledBtnSortable(listDiaporama){
       
   894         listDiaporama.find('.btn-sort.disabled').removeClass('disabled');
       
   895         listDiaporama.find('tr.row-image-diaporama:first-child').find('.btn-sort.up').addClass('disabled');
       
   896         listDiaporama.find('tr.row-image-diaporama:last-child').find('.btn-sort.down').addClass('disabled');
       
   897     }
       
   898 
       
   899     //links
       
   900     $('.tab-content').on('click', '.add-link', function(e){
       
   901         e.preventDefault();
       
   902         var tbody = $(this).parents('tfoot').siblings('tbody');
       
   903         addLinkRow(tbody);
       
   904     });
       
   905     $('.tab-content').on('click', '.delete-link', function(e){
       
   906         e.preventDefault();
       
   907         var row = $(this).parents('tr'),
       
   908             tbody = $(this).parents('tbody');
       
   909 
       
   910         row.remove();
       
   911         updateLinks(tbody);
       
   912     });
       
   913     function addLinkRow(tbody, dataView){
       
   914 
       
   915         //head commun à tous
       
   916         var tplLinkRow = getTemplate('#tpl-links-row');
       
   917         var output = Mustache.render(tplLinkRow, dataView);
       
   918         tbody.append(output);
       
   919 
       
   920     }
       
   921     $('.tab-content').on('keyup', '.links-rows input', function(e){
       
   922         var tbody = $(this).parents('.links-rows');
       
   923         updateLinks(tbody);   
       
   924     });
       
   925     function updateLinks(tbody){
       
   926         links = new Array();
       
   927 
       
   928         $.each(tbody.find('tr'), function(k, v){
       
   929             var urlLink = $(v).find('.url-link').val(),
       
   930                 titleLink = $(v).find('.title-link').val(),
       
   931                 link = {
       
   932                     url : urlLink,
       
   933                     title : titleLink
       
   934                 };
       
   935                 links.push(link);
       
   936 
       
   937         });
       
   938         currentAnnotation.content.links = links;
       
   939         disabledPreview();
       
   940     }
       
   941     $('.tab-content').on('focus', '.url-link', function(){
       
   942         var td = $(this).parents('td');
       
   943         if(td.hasClass('error')) td.removeClass('error')
       
   944     });
       
   945     
       
   946     $('.tab-content').on('blur', '.url-link', function(){
       
   947         var url = $(this).val(),
       
   948             td = $(this).parents('td');
       
   949         if(!isValidLink(url)){
       
   950             td.addClass('error');
       
   951         }
       
   952     });
       
   953 
       
   954     function isValidLink(url){
       
   955         return /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.test(url);
       
   956     }
       
   957 
       
   958     //annotation audio
       
   959     $('.tab-content').on('keyup', '.annotation-audio-content input, .annotation-audio-content textarea', function(){
       
   960         var name = $(this).attr('name'),
       
   961             value = $(this).val();
       
   962 
       
   963         currentAnnotation.content[name] = value;
       
   964         disabledPreview();
       
   965     });
       
   966 
       
   967     //annotation slideshow
       
   968     $('.tab-content').on('click', '.btn-autostart', function(){
       
   969         var autostart = $(this).attr('data-autostart');
       
   970         if(autostart == "true"){ autostart = true;}
       
   971         else {autostart = false;}
       
   972         disabledPreview();
       
   973         currentAnnotation.content.autostart = autostart;
       
   974     });
       
   975 
       
   976     $('.tab-content').on('change keyup', '.config-diaporama input[name=duration]', function(){
       
   977         var value = $(this).val();
       
   978         if(!isNaN(value)){
       
   979             disabledPreview();
       
   980             currentAnnotation.content.slideduration = value * 1000;
       
   981         }
       
   982     });
       
   983 
       
   984     
       
   985     //save project
       
   986     $('.btn-save-project').bind('click', function(e){
       
   987         e.preventDefault();
       
   988         if($(this).hasClass('disabled')) return;
       
   989 
       
   990         showAlertByClassName('save-load');
       
   991         var that = this;
       
   992         $(this).addClass('disabled');
       
   993 
       
   994         console.log(myProject.serialize());
       
   995 
       
   996         $.ajax({
       
   997             type: "POST",
       
   998             url: urlSaveProject,
       
   999             data: myProject.serialize(),
       
  1000             contentType: "application/cinelab",
       
  1001             headers: {
       
  1002                 "X-CSRFToken": tokenSaveProject
       
  1003             },
       
  1004             success: function(data, status, request){
       
  1005                 showAlertByClassName('save-ok');
       
  1006                 $('.btn-apercu-projet').removeClass('disabled');
       
  1007                 console.log('data : ', data);
       
  1008                 console.log('status : ', status);
       
  1009                 console.log('request : ', request);
       
  1010 
       
  1011             },
       
  1012             error: function(jqXHR, textStatus, errorThrown){
       
  1013                 showAlertByClassName('save-error');
       
  1014                 //alert(gettext("Server error\nYour hashcut couldn't be published"));
       
  1015             },
       
  1016             complete : function(){
       
  1017                 $(that).removeClass('disabled');
       
  1018             }
       
  1019         });
       
  1020     });
       
  1021     
       
  1022     //disabled preview
       
  1023     function disabledPreview(){
       
  1024         if(!$('.btn-apercu-projet').hasClass('disabled'))$('.btn-apercu-projet').addClass('disabled');
       
  1025     }
       
  1026     $(document).on('click', '.btn-apercu-projet.disabled', function(e){
       
  1027         e.preventDefault();
       
  1028     });
       
  1029 
       
  1030     //alert
       
  1031     $('.alert').bind('close', function (e) {
       
  1032         e.preventDefault();
       
  1033         $(this).hide();
       
  1034     });
       
  1035 
       
  1036     function showAlertByClassName(className){
       
  1037         $('.alert').hide();
       
  1038         $('.'+className).show();
       
  1039     }
       
  1040 //################ config
       
  1041     //tagit
       
  1042     function onTagItChange(e, ui) {
       
  1043         var tagitType = $(this).attr('data-type'), 
       
  1044             value = $(this).val();
       
  1045 
       
  1046         disabledPreview();
       
  1047 
       
  1048         if(tagitType == 'chapter'){
       
  1049             var idChapter = $(this).parents('form').attr('data-chapter-id');
       
  1050             currentChapter.keywords = value.split(',');
       
  1051             $('#row-list-chapter-'+idChapter).find('.list-chapter-tags').text(value);
       
  1052         }else{
       
  1053             currentAnnotation.keywords = value.split(',');
       
  1054         }
       
  1055     }
       
  1056 
       
  1057     var tagitParam = {
       
  1058         allowSpaces: true,
       
  1059         afterTagRemoved : onTagItChange,
       
  1060         afterTagAdded : onTagItChange
       
  1061     }
       
  1062 
       
  1063     //CLEditor annotation > text (wysiwyg) http://premiumsoftware.net/cleditor/docs/GettingStarted.html#optionalParameters
       
  1064     var wysiwygConfig = {
       
  1065         width:        450, 
       
  1066         height:       250, 
       
  1067         controls:     "bold italic underline strikethrough | font size " +
       
  1068                         "style | color highlight removeformat | bullets numbering | source",
       
  1069         fonts:        "Arial,Arial Black,Comic Sans MS,Courier New,Narrow,Garamond," +
       
  1070                         "Georgia,Impact,Sans Serif,Serif,Tahoma,Trebuchet MS,Verdana",
       
  1071         sizes:        "1,2,3,4,5,6,7",
       
  1072         styles:       [["Paragraph", "<p>"], ["Header 2", "<h2>"],
       
  1073                         ["Header 3", "<h3>"],  ["Header 4","<h4>"],  ["Header 5","<h5>"],
       
  1074                         ["Header 6","<h6>"]],
       
  1075         docType:      '<!DOCTYPE HTML>',
       
  1076         bodyStyle:    "margin:0; font-family: 'Helvetica Neue',​Helvetica,​Arial,​sans-serif;",
       
  1077         updateTextArea : function(text){
       
  1078             disabledPreview();
       
  1079             currentAnnotation.content.text = text;
       
  1080             return text;
       
  1081         },
       
  1082         updateFrame: function(text){
       
  1083             disabledPreview();
       
  1084             currentAnnotation.content.text = text;
       
  1085             return text;
       
  1086         }
       
  1087     };
       
  1088 
       
  1089     //slider
       
  1090     function configSlider(data){
       
  1091         return {
       
  1092             range: true,
       
  1093             values: [ data.begin.milliseconds, data.end.milliseconds ],
       
  1094             min: 0,
       
  1095             max: myMedia.duration.milliseconds,
       
  1096             slide: function( event, ui ) {
       
  1097                 
       
  1098                 data.setBegin(ui.values[0]);
       
  1099                 data.setEnd(ui.values[1]);
       
  1100 
       
  1101                 var idSlider = $(this).attr('data-id'),
       
  1102                     wTimeline = $('.timeline-annotations').width(),
       
  1103                     annotationTimeline = $('#annotation-timeline-'+ data.id),
       
  1104                     width = Math.floor(data.getDuration() * wTimeline / myMedia.duration),
       
  1105                     left = Math.floor(data.begin * wTimeline / myMedia.duration);
       
  1106 
       
  1107                 $( '#'+ idSlider +'-begin span' ).html(data.begin.toString());
       
  1108                 $( '#'+ idSlider +'-begin span' ).attr('data-milliseconds', data.begin);
       
  1109                 $( '#'+ idSlider +'-duration' ).html(data.getDuration().toString());
       
  1110                 $( '#'+ idSlider +'-end span' ).html(data.end.toString());
       
  1111                 $( '#'+ idSlider +'-end span' ).attr('data-milliseconds', data.end);
       
  1112 
       
  1113                 annotationTimeline.css({
       
  1114                     left : left,
       
  1115                     width :width
       
  1116                 });
       
  1117             },
       
  1118             start : function(){
       
  1119                 var idSlider = $(this).attr('data-id'),
       
  1120                     annotationTimeline = $('#annotation-timeline-'+ data.id);
       
  1121                 annotationTimeline.css('z-index',100);
       
  1122                 disabledPreview();
       
  1123             },
       
  1124             stop : function(){
       
  1125                 renderAnnotation();
       
  1126                 refreshAnnotationDisplay(myMedia.getCurrentTime());
       
  1127             }
       
  1128         };
       
  1129     }
       
  1130 
       
  1131     //init annotation content data
       
  1132     function getContentAnnotationByType(type){
   454     function getContentAnnotationByType(type){
  1133         var content;
   455         var content;
  1134         switch(type){
   456         switch(type){
  1135             case 'audio':
   457             case 'audio':
  1136                 content = {
   458                 content = {
  1167                     images : []
   489                     images : []
  1168                 };
   490                 };
  1169                 break;
   491                 break;
  1170         }
   492         }
  1171         return content;
   493         return content;
  1172     }//getContentAnnotationByType
   494     }
       
   495 
       
   496     function renderAnnotation(){
       
   497         
       
   498         var timeline = $('.timeline-annotations'),
       
   499             wTimeline = timeline.width(),
       
   500             annotationList = $('#list-annotations-rows');
       
   501 
       
   502         annotations = annotations.sortBy(function(c){
       
   503             return c.begin;
       
   504         });
       
   505 
       
   506         timeline.empty().append('<li>');
       
   507         annotationList.empty();
       
   508 
       
   509         $.each(annotations, function(k, v){
       
   510 
       
   511             //timeline
       
   512             var width = Math.floor(v.getDuration() * wTimeline / myMedia.duration),
       
   513                 left = Math.floor(v.begin * wTimeline / myMedia.duration),
       
   514                 dataAnntim = {
       
   515                     left : left,
       
   516                     width : width,
       
   517                     color : v.color,
       
   518                     id : v.id,
       
   519                     title : v.title
       
   520                 },
       
   521                 segment = getTemplate('#tpl-annotation-in-timeline');
       
   522                 segment = Mustache.render(segment, dataAnntim);
       
   523 
       
   524 
       
   525             var isInTimeline = false;
       
   526             $.each(timeline.find('li'), function(a, b){
       
   527                 if(isInTimeline) return;
       
   528                 var row = $(this);
       
   529                 if(row.children().length){
       
   530                     var canBeInRow = true;
       
   531                     $.each(row.find('.annotation'), function(c, d){
       
   532                         var oAL = parseInt($(d).css('left')),
       
   533                             oAR = oAL + $(d).width(),
       
   534                             segmentR = left + width;
       
   535                         if(oAL<=left && oAR>=left || oAL<=segmentR && oAR>= segmentR){
       
   536                             canBeInRow = false;
       
   537                         }
       
   538                     });
       
   539                     if(canBeInRow){
       
   540                         row.append(segment);
       
   541                         isInTimeline = true;
       
   542                     }
       
   543                 }else{
       
   544                     row.append(segment);
       
   545                     isInTimeline = true;
       
   546                 }
       
   547             });
       
   548 
       
   549             if(!isInTimeline){
       
   550                 timeline.append('<li>');
       
   551                 timeline.find('li:last-child').append(segment);
       
   552             }
       
   553             
       
   554             //liste
       
   555                 v.iconTab = getIcon(v.type);
       
   556                 var tplAnnotationRow = getTemplate('#tpl-list-annotation-row');
       
   557                 tplAnnotationRow = Mustache.render(tplAnnotationRow, v);
       
   558                 annotationList.append(tplAnnotationRow);
       
   559         });
       
   560     }//renderAnnotation
       
   561 
       
   562     //edit annotation
       
   563     $('#list-annotations').on('click', 'a.btn-edit-annotation', function(e){
       
   564         e.preventDefault();
       
   565         
       
   566         var idAnnotation = $(this).attr('data-id');
       
   567         //si il est déjà ouvert
       
   568         if($('#tab-annotation-'+idAnnotation).length){
       
   569             $('a[href=#tab-annotation-'+idAnnotation+']').tab('show');
       
   570         }else{
       
   571             var data = _.find(annotations, function(c){ return c.id == idAnnotation; });
       
   572             openTab(data.type, data);
       
   573         } 
       
   574     });
       
   575 
       
   576     $('.tab-content').on('keyup', '.form-info-general-annotation input[name=title], .form-info-general-annotation textarea', function(e){
       
   577         var name = $(this).attr('name'),
       
   578             value = $(this).val();
       
   579         currentAnnotation[name] = value;
       
   580         if(name == 'title'){
       
   581             var idAnnotation = $(this).parents('form').attr('data-id');
       
   582             $('#onglet-title-'+idAnnotation).text(value);
       
   583             $(this).parents('form').find('.btn-delete-annotation').attr('data-title', value);
       
   584             $('#annotation-timeline-'+ idAnnotation).attr('title', value);
       
   585             $('#annotation-timeline-'+ idAnnotation+' span').text(value);
       
   586         }
       
   587         disabledPreview();
       
   588     });
       
   589 
       
   590     //delete annotation
       
   591     $(document).on('click','.btn-delete-annotation', function(e){
       
   592         e.preventDefault();
       
   593 
       
   594         var idAnnotation = $(this).attr('data-id'),
       
   595             btnDeleteModal = $("#modal-confirm #btn-delete-modal");
       
   596         btnDeleteModal.attr('data-type-delete', 'annotation');
       
   597         btnDeleteModal.attr('data-id', idAnnotation);
       
   598     });
       
   599 
       
   600     function deleteAnnotation(idAnnotation){
       
   601         
       
   602         $("#modal-confirm").modal('hide');
       
   603         annotations.removeId(idAnnotation);
       
   604         myProject.getAnnotations().removeId(idAnnotation, true);
       
   605         closeTab(idAnnotation);
       
   606         renderAnnotation();
       
   607         disabledPreview();
       
   608     }
       
   609 
       
   610 /* Tab */
       
   611 
       
   612     $('#onglet-annotations').on('click', 'a', function(e){
       
   613         e.preventDefault();
       
   614         $(this).tab('show');
       
   615     });
       
   616 
       
   617     //open tab
       
   618     $(document).on('click', '.open-tab', function(e){
       
   619         e.preventDefault();
       
   620         var type = $(this).attr('data-type');
       
   621         openTab(type);
       
   622     });
       
   623 
       
   624     function openTab(type, data){
       
   625         
       
   626         var dataView, isNew = false;
       
   627         if(_.isUndefined(data)){//new
       
   628             var currentTimePlusUnMin = 60 * 1000 + myMedia.currentTime,
       
   629                 endAnnotation = (currentTimePlusUnMin<myMedia.duration) ? currentTimePlusUnMin : myMedia.duration;
       
   630             var dataAnnotation = {
       
   631                 title : '',
       
   632                 begin : myMedia.currentTime,
       
   633                 end : endAnnotation,
       
   634                 description : '',
       
   635                 type : type,
       
   636                 keywords : []
       
   637             };
       
   638             dataView = newAnnotation(dataAnnotation);
       
   639             renderAnnotation();
       
   640             isNew = true;
       
   641         }else{//edition
       
   642             dataView = data;
       
   643         }
       
   644 
       
   645         var idAnnotation = dataView.id,
       
   646             tabContent = $('<div class="tab-pane" id="tab-annotation-'+idAnnotation+'"></div>'),
       
   647             iconTab;
       
   648 
       
   649         currentAnnotation = _.find(annotations, function(c){ return c.id == idAnnotation; });
       
   650         showCurrentAnnotationInTimeline(idAnnotation);
       
   651             //head commun à tous
       
   652             var tplHead = getTemplate('#tpl-head');
       
   653             var output = Mustache.render(tplHead, dataView);
       
   654             $(tabContent).append(output);
       
   655             $(tabContent).find(".slider-duration").slider(configSlider(dataView));
       
   656             currentSlider = $(tabContent).find(".slider-duration");
       
   657             $(tabContent).find(".ui-slider-range.ui-widget-header.ui-corner-all").css('background', dataView.color);
       
   658             $(tabContent).find('.tag-it').tagit(tagitParam);
       
   659             
       
   660             //type
       
   661             var viewType = {
       
   662                 id : idAnnotation,
       
   663                 content : dataView.content
       
   664             };
       
   665             var tpl = getTemplate('#tpl-'+type);
       
   666 
       
   667             tpl = Mustache.render(tpl, viewType);
       
   668             $(tabContent).append(tpl);
       
   669             $('.tab-content').append(tabContent);
       
   670 
       
   671             //data by type
       
   672             switch(type){
       
   673                 case 'audio':
       
   674                     break;
       
   675                 case 'video':
       
   676                     var labelModify = $(tabContent).find('.label-modify-video'),
       
   677                         labelAdd = $(tabContent).find('.label-add-video');
       
   678                     if(viewType.content.url != ""){
       
   679                         var videoWrap = $(tabContent).find('.annotation-video-content');
       
   680                         renderVideoInfo(videoWrap, viewType.content);
       
   681                         labelModify.show();
       
   682 
       
   683                     }else{
       
   684                         labelAdd.show();
       
   685                     }
       
   686                     break;
       
   687                 case 'text': 
       
   688                     var cledit = $(tabContent).find('.wysiwyg').cleditor(wysiwygConfig)[0];
       
   689                     break;
       
   690                 case 'links': 
       
   691                     var tbody = $(tabContent).find('tbody.links-rows'),
       
   692                         links = viewType.content.links;
       
   693                     if(links.length){
       
   694                         $.each(links, function(k,v){
       
   695                             addLinkRow(tbody, v);
       
   696                         });
       
   697                     }else{//il n'y a pas de lien on en ajoute 1
       
   698                         addLinkRow(tbody);
       
   699                     }
       
   700                     break;
       
   701 
       
   702                 case 'slideshow': 
       
   703                     console.log(currentAnnotation)
       
   704                     $(tabContent).find('.number-spin').val(dataView.content.slideduration/1000);
       
   705                     $(tabContent).find('.number-spin').spin(spinParam);
       
   706                     $(tabContent).find('.ui-sortable').sortable({
       
   707                         start: function (event, ui) {
       
   708                             $(ui.item).data("startindex", ui.item.index());
       
   709                         },
       
   710                         stop : function(event, ui){
       
   711                             disabledBtnSortable($(this));
       
   712                         },
       
   713                         update : function(event, ui){
       
   714                             var oldIndex = ui.item.data("startindex"),
       
   715                                 newIndex = ui.item.index();
       
   716                             currentAnnotation.content.images.move(oldIndex, newIndex);
       
   717                         },
       
   718                     });
       
   719                     var diaporama = $(tabContent).find('#diaporama-'+idAnnotation),
       
   720                         images = viewType.content.images;
       
   721                     if(images.length){
       
   722                         $.each(images, function(k,v){
       
   723                             addImageToDiaporama(diaporama, v);
       
   724                         });
       
   725                     }
       
   726                     break;
       
   727             }
       
   728 
       
   729             dataView.iconTab = getIcon(type);
       
   730             var tplOnglet = getTemplate('#tpl-onglet');
       
   731             var onglet = Mustache.render(tplOnglet, dataView);
       
   732 
       
   733             $(".nav-tabs li:last-child").after(onglet);
       
   734             $('a[href=#tab-annotation-'+idAnnotation+']').tab('show');
       
   735 
       
   736             if(isNew){$(tabContent).find('.head-title').focus();}
       
   737   
       
   738     }//openTab
       
   739 
       
   740     function getIcon(type){
       
   741         var icon;
       
   742         switch(type){
       
   743             case 'audio': icon = 'volume-up';
       
   744                 break;
       
   745             case 'video': icon = 'film';
       
   746                 break;
       
   747             case 'text': icon = 'align-left';
       
   748                 break;
       
   749             case 'html': icon = 'code';
       
   750                 break;
       
   751             case 'links': icon = 'link';
       
   752                 break;
       
   753             case 'slideshow': icon = 'picture';
       
   754                 break;
       
   755         }
       
   756         return icon;
       
   757     }
       
   758 
       
   759     //define currentAnnotation by open tab
       
   760     $('#onglet-annotations').on('show', 'a[data-toggle="annotation"]', function (e) {
       
   761         var idAnnotation = $(e.target).attr('data-id');
       
   762         currentAnnotation = _.find(annotations, function(c){ return c.id == idAnnotation; });
       
   763         currentSlider = $('#tab-annotation-'+idAnnotation).find(".slider-duration");
       
   764         showCurrentAnnotationInTimeline(idAnnotation);
       
   765     });
       
   766 
       
   767     //refresh annotation data view when back on annotation list tab
       
   768     $('#onglet-annotations').on('show', 'a[data-toggle="list-annotations"]', function (e) {
       
   769         currentAnnotation = undefined;
       
   770         renderAnnotation();
       
   771     });
       
   772 
       
   773     //close tab
       
   774     function closeTab(idAnnotation){
       
   775         $('#onglet-'+idAnnotation).remove();
       
   776         $('.tab-content #tab-annotation-'+idAnnotation).remove();
       
   777         $('#tab-list-annotation').tab('show');
       
   778     }
       
   779 
       
   780     $('#onglet-annotations').on('click', 'span.close-tab', function(e){
       
   781         e.preventDefault();e.stopPropagation();
       
   782         var idAnnotation = $(this).parents('a').attr('data-id');
       
   783         closeTab(idAnnotation);
       
   784     });
       
   785 
       
   786     $('.tab-content').on('click', '.btn-save-annotation', function(e){
       
   787         e.preventDefault();
       
   788         var idAnnotation = $(this).attr('data-id');
       
   789         closeTab(idAnnotation);
       
   790     });
       
   791 
       
   792 /* Video */
       
   793 
       
   794     function renderVideoInfo(videoWrap, dataVideo){
       
   795         var tplVideo = getTemplate('#tpl-video-row');
       
   796         tplVideo = Mustache.render(tplVideo, dataVideo);
       
   797         
       
   798         videoWrap.empty().append(tplVideo);
       
   799 
       
   800         videoWrap = videoWrap.find(".video-container");
       
   801         getVideoPlayer(dataVideo.url, videoWrap);
       
   802     }
       
   803 
       
   804     //select video on modal
       
   805     $('.popup').on('click', '.bibliotheque-video a:not(.pagination a)', function(e){
       
   806         e.preventDefault();
       
   807 
       
   808         var url = $(this).attr('data-url'),
       
   809             title = $(this).attr('data-title'),
       
   810             description = $(this).attr('data-description');
       
   811 
       
   812         currentAnnotation.content.url = url;
       
   813         currentAnnotation.content.title = title;
       
   814         currentAnnotation.content.description = description;
       
   815 
       
   816         $('.popup').modal('hide');
       
   817 
       
   818         var videoWrap = $('#tab-annotation-'+currentAnnotation.id).find('.annotation-video-content');
       
   819         renderVideoInfo(videoWrap, currentAnnotation.content);
       
   820 
       
   821         var labelModify = $('#tab-annotation-'+currentAnnotation.id).find('.label-modify-video'),
       
   822             labelAdd = $('#tab-annotation-'+currentAnnotation.id).find('.label-add-video');
       
   823 
       
   824         labelModify.show();
       
   825         labelAdd.hide();
       
   826 
       
   827         disabledPreview();
       
   828     });
       
   829 
       
   830 /* Slideshow */
       
   831 
       
   832     //select image on modal 
       
   833     $('.popup').on('click', '.bibliotheque-image a:not(.pagination a)', function(e){
       
   834         e.preventDefault();
       
   835 
       
   836         var url = $(this).attr('data-url'),
       
   837             title = $(this).attr('data-title'),
       
   838             description = $(this).attr('data-description'),
       
   839             image = {
       
   840                 id : currentAnnotation.id,
       
   841                 url : url,
       
   842                 title : title,
       
   843                 description : description
       
   844             };
       
   845         currentAnnotation.content.images.push(image);
       
   846 
       
   847         var listDiaporama = $('#diaporama-'+currentAnnotation.id);
       
   848         addImageToDiaporama(listDiaporama, image);
       
   849         $('.popup').modal('hide'); 
       
   850         disabledPreview();
       
   851     });
       
   852 
       
   853     function addImageToDiaporama(diaporama, dataView){
       
   854         var tplDiapo = getTemplate('#tpl-diaporama-row');
       
   855         tplDiapo = Mustache.render(tplDiapo, dataView);
       
   856         diaporama.append(tplDiapo);
       
   857         disabledBtnSortable(diaporama);
       
   858     };
       
   859 
       
   860     //edit 
       
   861     $('.tab-content').on('click', '.title-slideshow-row, .description-slideshow-row, .video-title-edit, .video-description-edit', function(){
       
   862         if($(this).find('input').length) return;
       
   863         var html = $(this).find('span').html(),
       
   864             inputType = $(this).attr('data-input'),
       
   865             name = $(this).attr('data-name'),
       
   866             input = $('<'+inputType+'>').attr('name', name);
       
   867         input.val(html);
       
   868         $(this).find('span').replaceWith(input);
       
   869         input.focus().keypress(function(e){
       
   870             code = (e.keyCode ? e.keyCode : e.which);
       
   871             if (code == 13) $(this).blur();
       
   872         });
       
   873     });
       
   874 
       
   875     $(document).on('blur', '.title-slideshow-row input, .description-slideshow-row textarea', function(){
       
   876         var newValue = $(this).val(),
       
   877             name = $(this).attr('name'),
       
   878             span = $('<span>').html(newValue),
       
   879             indexRow = $(this).parents('.row-image-diaporama').index();
       
   880         $(this).replaceWith(span);
       
   881         currentAnnotation.content.images[indexRow][name] = newValue;
       
   882         disabledPreview();
       
   883     });
       
   884 
       
   885     $(document).on('blur', '.video-title-edit input, .video-description-edit textarea', function(){
       
   886         var newValue = $(this).val(),
       
   887             name = $(this).attr('name'),
       
   888             span = $('<span>').html(newValue);
       
   889         $(this).replaceWith(span);
       
   890         currentAnnotation.content[name] = newValue;
       
   891         disabledPreview();
       
   892     });
       
   893 
       
   894     //button up / down
       
   895     $(document).on('click', '.ui-sortable .btn-sort', function(e){
       
   896         e.preventDefault();
       
   897         var row = $(this).parents('tr.row-image-diaporama'),
       
   898             oldIndex = row.index(),
       
   899             listDiaporama = $(this).parents('.list-image-diaporama');
       
   900 
       
   901         if($(this).hasClass('down'))
       
   902             row.insertAfter(row.next());
       
   903         else if($(this).hasClass('up'))
       
   904             row.insertBefore(row.prev());
       
   905 
       
   906         var newIndex = row.index();
       
   907         currentAnnotation.content.images.move(oldIndex, newIndex);
       
   908 
       
   909         disabledBtnSortable(listDiaporama);
       
   910         disabledPreview();
       
   911     });
       
   912 
       
   913     function disabledBtnSortable(listDiaporama){
       
   914         listDiaporama.find('.btn-sort.disabled').removeClass('disabled');
       
   915         listDiaporama.find('tr.row-image-diaporama:first-child').find('.btn-sort.up').addClass('disabled');
       
   916         listDiaporama.find('tr.row-image-diaporama:last-child').find('.btn-sort.down').addClass('disabled');
       
   917     }
       
   918 
       
   919     //delete image on slideshow
       
   920     $('.tab-content').on('click','.btn-delete-image', function(e){
       
   921         e.preventDefault();
       
   922         var rowImage = $(this).parents('tr.row-image-diaporama'),
       
   923             index = rowImage.index();
       
   924 
       
   925         rowImage.remove();
       
   926         currentAnnotation.content.images.splice(index, 1);
       
   927         disabledPreview();
       
   928     });
       
   929 
       
   930 /* Links */
       
   931 
       
   932     //add
       
   933     function addLinkRow(tbody, dataView){
       
   934         var tplLinkRow = getTemplate('#tpl-links-row');
       
   935         var output = Mustache.render(tplLinkRow, dataView);
       
   936         tbody.append(output);
       
   937 
       
   938     }
       
   939 
       
   940     $('.tab-content').on('click', '.add-link', function(e){
       
   941         e.preventDefault();
       
   942         var tbody = $(this).parents('tfoot').siblings('tbody');
       
   943         addLinkRow(tbody);
       
   944     });
       
   945 
       
   946     //delete
       
   947     $('.tab-content').on('click', '.delete-link', function(e){
       
   948         e.preventDefault();
       
   949         var row = $(this).parents('tr'),
       
   950             tbody = $(this).parents('tbody');
       
   951 
       
   952         row.remove();
       
   953         updateLinks(tbody);
       
   954     });
       
   955     
       
   956     //edit
       
   957     $('.tab-content').on('keyup', '.links-rows input', function(e){
       
   958         var tbody = $(this).parents('.links-rows');
       
   959         updateLinks(tbody);   
       
   960     });
       
   961 
       
   962     function updateLinks(tbody){
       
   963         links = new Array();
       
   964 
       
   965         $.each(tbody.find('tr'), function(k, v){
       
   966             var urlLink = $(v).find('.url-link').val(),
       
   967                 titleLink = $(v).find('.title-link').val(),
       
   968                 link = {
       
   969                     url : urlLink,
       
   970                     title : titleLink
       
   971                 };
       
   972                 links.push(link);
       
   973 
       
   974         });
       
   975         currentAnnotation.content.links = links;
       
   976         disabledPreview();
       
   977     }
       
   978 
       
   979     $('.tab-content').on('focus', '.url-link', function(){
       
   980         var td = $(this).parents('td');
       
   981         if(td.hasClass('error')) {
       
   982             td.removeClass('error');
       
   983             td.find('.help-inline').hide();
       
   984         }
       
   985     });
       
   986     
       
   987     $('.tab-content').on('blur', '.url-link', function(){
       
   988         var url = $(this).val(),
       
   989             td = $(this).parents('td');
       
   990         if(!isValidLink(url)){
       
   991             td.addClass('error');
       
   992             td.find('.help-inline').show();
       
   993         }
       
   994     });
       
   995 
       
   996     function isValidLink(url){
       
   997         return /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.test(url);
       
   998     }
       
   999 
       
  1000     //autostart
       
  1001     $('.tab-content').on('click', '.btn-autostart', function(){
       
  1002         var autostart = $(this).attr('data-autostart');
       
  1003         if(autostart == "true"){ autostart = true;}
       
  1004         else {autostart = false;}
       
  1005         disabledPreview();
       
  1006         currentAnnotation.content.autostart = autostart;
       
  1007     });
       
  1008 
       
  1009     //duration
       
  1010     $('.tab-content').on('change keyup', '.config-diaporama input[name=duration]', function(){
       
  1011         var value = $(this).val();
       
  1012         if(!isNaN(value)){
       
  1013             disabledPreview();
       
  1014             currentAnnotation.content.slideduration = value * 1000;
       
  1015         }
       
  1016     });
       
  1017 
       
  1018 /* Audio */
       
  1019 
       
  1020     $('.tab-content').on('keyup', '.annotation-audio-content input, .annotation-audio-content textarea', function(){
       
  1021         var name = $(this).attr('name'),
       
  1022             value = $(this).val();
       
  1023 
       
  1024         currentAnnotation.content[name] = value;
       
  1025         disabledPreview();
       
  1026     });
       
  1027 
       
  1028 /* Save project */
       
  1029 
       
  1030     $('.btn-save-project').bind('click', function(e){
       
  1031         e.preventDefault();
       
  1032         if($(this).hasClass('disabled')) return;
       
  1033 
       
  1034         showAlertByClassName('save-load');
       
  1035         var that = this;
       
  1036         $(this).addClass('disabled');
       
  1037 
       
  1038         console.log(myProject.serialize());
       
  1039 
       
  1040         $.ajax({
       
  1041             type: "POST",
       
  1042             url: urlSaveProject,
       
  1043             data: myProject.serialize(),
       
  1044             contentType: "application/cinelab",
       
  1045             headers: {
       
  1046                 "X-CSRFToken": tokenSaveProject
       
  1047             },
       
  1048             success: function(data, status, request){
       
  1049                 showAlertByClassName('save-ok');
       
  1050                 $('.btn-apercu-projet').removeClass('disabled');
       
  1051                 console.log('data : ', data);
       
  1052                 console.log('status : ', status);
       
  1053                 console.log('request : ', request);
       
  1054 
       
  1055             },
       
  1056             error: function(jqXHR, textStatus, errorThrown){
       
  1057                 showAlertByClassName('save-error');
       
  1058                 //alert(gettext("Server error\nYour hashcut couldn't be published"));
       
  1059             },
       
  1060             complete : function(){
       
  1061                 $(that).removeClass('disabled');
       
  1062             }
       
  1063         });
       
  1064     });
       
  1065     
       
  1066     //disabled preview
       
  1067     function disabledPreview(){
       
  1068         if(!$('.btn-apercu-projet').hasClass('disabled'))$('.btn-apercu-projet').addClass('disabled');
       
  1069     }
       
  1070     $(document).on('click', '.btn-apercu-projet.disabled', function(e){
       
  1071         e.preventDefault();
       
  1072     });
       
  1073 
       
  1074     //alert save info
       
  1075     $('.alert').bind('close', function (e) {
       
  1076         e.preventDefault();
       
  1077         $(this).hide();
       
  1078     });
       
  1079 
       
  1080     function showAlertByClassName(className){
       
  1081         $('.alert').hide();
       
  1082         $('.'+className).show();
       
  1083     }
       
  1084 
       
  1085 /* Config */
       
  1086 
       
  1087     //tagit
       
  1088     function onTagItChange(e, ui) {
       
  1089         var tagitType = $(this).attr('data-type'), 
       
  1090             value = $(this).val();
       
  1091 
       
  1092         disabledPreview();
       
  1093 
       
  1094         if(tagitType == 'chapter'){
       
  1095             var idChapter = $(this).parents('form').attr('data-chapter-id');
       
  1096             currentChapter.keywords = value.split(',');
       
  1097             $('#row-list-chapter-'+idChapter).find('.list-chapter-tags').text(value);
       
  1098         }else{
       
  1099             currentAnnotation.keywords = value.split(',');
       
  1100         }
       
  1101     }
       
  1102 
       
  1103     var tagitParam = {
       
  1104         allowSpaces: true,
       
  1105         afterTagRemoved : onTagItChange,
       
  1106         afterTagAdded : onTagItChange
       
  1107     }
       
  1108 
       
  1109     //CLEditor (wysiwyg) http://premiumsoftware.net/cleditor/docs/GettingStarted.html#optionalParameters
       
  1110     var wysiwygConfig = {
       
  1111         width:        450, 
       
  1112         height:       250, 
       
  1113         controls:     "bold italic underline strikethrough | font size " +
       
  1114                         "style | color highlight removeformat | bullets numbering | source",
       
  1115         fonts:        "Arial,Arial Black,Comic Sans MS,Courier New,Narrow,Garamond," +
       
  1116                         "Georgia,Impact,Sans Serif,Serif,Tahoma,Trebuchet MS,Verdana",
       
  1117         sizes:        "1,2,3,4,5,6,7",
       
  1118         styles:       [["Paragraph", "<p>"], ["Header 2", "<h2>"],
       
  1119                         ["Header 3", "<h3>"],  ["Header 4","<h4>"],  ["Header 5","<h5>"],
       
  1120                         ["Header 6","<h6>"]],
       
  1121         docType:      '<!DOCTYPE HTML>',
       
  1122         bodyStyle:    "margin:0; font-family: 'Helvetica Neue',​Helvetica,​Arial,​sans-serif;",
       
  1123         updateTextArea : function(text){
       
  1124             disabledPreview();
       
  1125             currentAnnotation.content.text = text;
       
  1126             return text;
       
  1127         },
       
  1128         updateFrame: function(text){
       
  1129             disabledPreview();
       
  1130             currentAnnotation.content.text = text;
       
  1131             return text;
       
  1132         }
       
  1133     };
       
  1134 
       
  1135     //slider
       
  1136     function configSlider(data){
       
  1137         return {
       
  1138             range: true,
       
  1139             values: [ data.begin.milliseconds, data.end.milliseconds ],
       
  1140             min: 0,
       
  1141             max: myMedia.duration.milliseconds,
       
  1142             slide: function( event, ui ) {
       
  1143                 
       
  1144                 data.setBegin(ui.values[0]);
       
  1145                 data.setEnd(ui.values[1]);
       
  1146 
       
  1147                 var idSlider = $(this).attr('data-id'),
       
  1148                     wTimeline = $('.timeline-annotations').width(),
       
  1149                     annotationTimeline = $('#annotation-timeline-'+ data.id),
       
  1150                     width = Math.floor(data.getDuration() * wTimeline / myMedia.duration),
       
  1151                     left = Math.floor(data.begin * wTimeline / myMedia.duration);
       
  1152 
       
  1153                 $( '#'+ idSlider +'-begin span' ).html(data.begin.toString());
       
  1154                 $( '#'+ idSlider +'-begin span' ).attr('data-milliseconds', data.begin);
       
  1155                 $( '#'+ idSlider +'-duration' ).html(data.getDuration().toString());
       
  1156                 $( '#'+ idSlider +'-end span' ).html(data.end.toString());
       
  1157                 $( '#'+ idSlider +'-end span' ).attr('data-milliseconds', data.end);
       
  1158 
       
  1159                 annotationTimeline.css({
       
  1160                     left : left,
       
  1161                     width :width
       
  1162                 });
       
  1163             },
       
  1164             start : function(){
       
  1165                 var idSlider = $(this).attr('data-id'),
       
  1166                     annotationTimeline = $('#annotation-timeline-'+ data.id);
       
  1167                 annotationTimeline.css('z-index',100);
       
  1168                 disabledPreview();
       
  1169             },
       
  1170             stop : function(){
       
  1171                 renderAnnotation();
       
  1172                 refreshAnnotationDisplay(myMedia.getCurrentTime());
       
  1173             }
       
  1174         };
       
  1175     }
  1173 
  1176 
  1174     //unload
  1177     //unload
  1175     $(window).on("beforeunload", onLeave);
  1178     $(window).on("beforeunload", onLeave);
  1176     function onLeave(){
  1179     function onLeave(){
  1177         if($('.btn-apercu-projet').hasClass('disabled')) return "You have unsaved changes";
  1180         if($('.btn-apercu-projet').hasClass('disabled')) return "You have unsaved changes";
  1182         activeTangle,
  1185         activeTangle,
  1183         tangleStartX,
  1186         tangleStartX,
  1184         tangleStartVal,
  1187         tangleStartVal,
  1185         tangleHasMoved;
  1188         tangleHasMoved;
  1186     
  1189     
  1187     $('.chapter-widget-info').on('mousedown', '.time-tangle', function(evt){
       
  1188         activeTangle = $(this);
       
  1189         activeTangle.addClass("active");
       
  1190         tangleStartVal = +activeTangle.attr("data-milliseconds");
       
  1191         tangleStartX = evt.pageX;
       
  1192         tangleHasMoved = false;
       
  1193         $(this).parents('td').siblings('td').find(".time-tangle").addClass("deactivate");
       
  1194         return false;
       
  1195     });
       
  1196 
       
  1197     $('.tab-content').on('mousedown', '.time-tangle', function(evt){
       
  1198         activeTangle = $(this);
       
  1199         activeTangle.addClass("active");
       
  1200         tangleStartVal = +activeTangle.attr("data-milliseconds");
       
  1201         tangleStartX = evt.pageX;
       
  1202         tangleHasMoved = false;
       
  1203         $(this).parents('td').siblings('td').find(".time-tangle").addClass("deactivate");
       
  1204         return false;
       
  1205     });
       
  1206 
       
  1207     $(document)
  1190     $(document)
  1208         .mousemove(function(evt) {
  1191         .mousemove(function(evt) {
  1209             if (activeTangle) {
  1192             if (activeTangle) {
  1210                 tangleHasMoved = true;
  1193                 tangleHasMoved = true;
  1211                 var newval = new IriSP.Model.Time(tangleMsPerPixel * (evt.pageX - tangleStartX) + tangleStartVal);
  1194                 var newval = new IriSP.Model.Time(tangleMsPerPixel * (evt.pageX - tangleStartX) + tangleStartVal);
  1214             }
  1197             }
  1215         })
  1198         })
  1216         .mouseup(function() {
  1199         .mouseup(function() {
  1217 
  1200 
  1218             if (activeTangle) {
  1201             if (activeTangle) {
  1219                 if(activeTangle.hasClass('slider-tangle')){
  1202                 if(activeTangle.hasClass('slider-tangle')){//annotation
  1220                     renderAnnotation();
  1203                     renderAnnotation();
  1221                     refreshAnnotationDisplay(myMedia.getCurrentTime());
  1204                     refreshAnnotationDisplay(myMedia.getCurrentTime());
  1222                 }
  1205                 }
  1223                 $(".time-tangle").removeClass("active deactivate");
  1206                 $(".time-tangle").removeClass("active deactivate");
  1224                 activeTangle = undefined;
  1207                 activeTangle = undefined;
  1225             }
  1208             }
  1226         });
  1209         });
  1227 
  1210 
  1228     //chapters
  1211     //chapters
       
  1212     $('.chapter-widget-info').on('mousedown', '.time-tangle', function(evt){
       
  1213         activeTangle = $(this);
       
  1214         activeTangle.addClass("active");
       
  1215         tangleStartVal = +activeTangle.attr("data-milliseconds");
       
  1216         tangleStartX = evt.pageX;
       
  1217         tangleHasMoved = false;
       
  1218         $(this).parents('td').siblings('td').find(".time-tangle").addClass("deactivate");
       
  1219         return false;
       
  1220     });
       
  1221 
  1229     function updateRenderChapter(chapterData){
  1222     function updateRenderChapter(chapterData){
  1230         var segment = $('.chapter-segments li#'+chapterData.id),
  1223         var segment = $('.chapter-segments li#'+chapterData.id),
  1231             wChapterSegmentWrap = $('.chapter-segments').width(),
  1224             wChapterSegmentWrap = $('.chapter-segments').width(),
  1232             wSegmentNew = chapterData.getDuration() * wChapterSegmentWrap / myMedia.duration,
  1225             wSegmentNew = chapterData.getDuration() * wChapterSegmentWrap / myMedia.duration,
  1233             lSegmentNew = chapterData.begin * wChapterSegmentWrap / myMedia.duration,
  1226             lSegmentNew = chapterData.begin * wChapterSegmentWrap / myMedia.duration,
  1283             chapterBefore = currentChapter;
  1276             chapterBefore = currentChapter;
  1284 
  1277 
  1285             updateChapterDuration(val, chapterBefore, chapterAfter);
  1278             updateChapterDuration(val, chapterBefore, chapterAfter);
  1286     });
  1279     });
  1287 
  1280 
  1288 //annotations
  1281     //annotations
       
  1282     $('.tab-content').on('mousedown', '.time-tangle', function(evt){
       
  1283         activeTangle = $(this);
       
  1284         activeTangle.addClass("active");
       
  1285         tangleStartVal = +activeTangle.attr("data-milliseconds");
       
  1286         tangleStartX = evt.pageX;
       
  1287         tangleHasMoved = false;
       
  1288         $(this).parents('td').siblings('td').find(".time-tangle").addClass("deactivate");
       
  1289         return false;
       
  1290     });
  1289 
  1291 
  1290     $('.tab-content').on('valuechange', '.tangle-start', function(evt, val){
  1292     $('.tab-content').on('valuechange', '.tangle-start', function(evt, val){
  1291         var max = currentSlider.slider('values')[1],
  1293         var max = currentSlider.slider('values')[1],
  1292             min = 0,
  1294             min = 0,
  1293             beginOrEnd = 'begin';
  1295             beginOrEnd = 'begin';
  1332             });
  1334             });
  1333             currentSlider.slider('values', [currentAnnotation.begin, currentAnnotation.end])
  1335             currentSlider.slider('values', [currentAnnotation.begin, currentAnnotation.end])
  1334         }
  1336         }
  1335     }
  1337     }
  1336 
  1338 
  1337     //test
       
  1338     $('.log-annotations').bind('click', function(e){
       
  1339         e.preventDefault();
       
  1340         console.log(annotations.length + ' annotations', annotations);
       
  1341         currentSlider.slider( "values", 0, 55 );
       
  1342     });
       
  1343 
       
  1344     $('.log-chapters').bind('click', function(e){
       
  1345         e.preventDefault();
       
  1346         console.log(chapters.length + ' chapitres',chapters);
       
  1347     });
       
  1348 
       
  1349 });//ready
  1339 });//ready
  1350 
  1340 
  1351 //Utilitaires
  1341 /* Utility */
       
  1342 
  1352 Array.prototype.move = function (old_index, new_index) {
  1343 Array.prototype.move = function (old_index, new_index) {
  1353     if (new_index >= this.length) {
  1344     if (new_index >= this.length) {
  1354         var k = new_index - this.length;
  1345         var k = new_index - this.length;
  1355         while ((k--) + 1) {
  1346         while ((k--) + 1) {
  1356             this.push(undefined);
  1347             this.push(undefined);