677a01e82abb4c74e82c39cd793c5241f74543b2
[atutor.git] / mods / atutor_opencaps / opencaps / js / editor.js
1 /*\r
2  * OpenCaps\r
3  * http://opencaps.atrc.utoronto.ca\r
4  * \r
5  * Copyright 2009 Heidi Hazelton\r
6  * Adaptive Technology Resource Centre, University of Toronto\r
7  * \r
8  * Licensed under the Educational Community License (ECL), Version 2.0. \r
9  * You may not use this file except in compliance with this License.\r
10  * http://www.opensource.org/licenses/ecl2.php\r
11  * \r
12  */\r
13 \r
14 /* GLOBALS */\r
15 \r
16 var proj = proj || {};\r
17 \r
18 var MIN_CLIP_DUR = 400;\r
19 \r
20 var clip_playing = false;\r
21 \r
22 var movie = movie || {};\r
23 var clip = clip || {};\r
24 var movieObj = movieObj || {};\r
25 \r
26 num_clips = 0;\r
27 clips = new Array();\r
28 \r
29 this_location = new Object;\r
30 \r
31 var json;\r
32 var inClip;\r
33 \r
34 \r
35 /* ****** */\r
36 tab = 'clips';\r
37 lastplay = 0;\r
38 new_flag = 0;\r
39 clocktimer = 0;\r
40 curTime = 0;\r
41 clipTime = 0;\r
42 curClip = 0;\r
43 curIn = 0;\r
44 lastLoc = 1;\r
45 \r
46 pace = 0;\r
47 timer = 0;\r
48 numclips = 0;\r
49 marker = "";\r
50 clip_marker = "";\r
51 \r
52 //set values in seconds\r
53 onemin  = 60;\r
54 onehr   = onemin*60;\r
55 \r
56 /* clip vars */\r
57 temp_in = 0;\r
58 temp_out = 0;\r
59 temp_caps = '';\r
60 dur = 0;\r
61 extend = false;\r
62 \r
63 \r
64 /*************************************** initialize */\r
65 \r
66 $(document).ready(function () {\r
67         $("#movie-controls").css("visibility", "hidden");\r
68         $("#clip-controls").css("visibility", "hidden");\r
69         $("#make-clip").css("visibility", "hidden");\r
70         $("#clip-info").css("visibility", "hidden");\r
71 \r
72         $.get("include/workflow.php", { task: 'get_json' }, function(json) {\r
73                 if (json) {                     \r
74                         proj = JSON.parse(json);\r
75                         startEditor();\r
76                 }\r
77         });\r
78         \r
79         $("#caption-text").keyup( function(event) {             \r
80                 //if ($("#caption-text").text() != this_location.caption_text) {\r
81                         $("#makeclip").removeAttr("disabled");\r
82                         temp_caps = 1;\r
83                 //}\r
84         });\r
85 });\r
86 \r
87 \r
88 function confirmDelete(clipnum) {\r
89         if (confirm("Are you sure you want to delete Clip "+clipnum+"?")) {\r
90                 deleteClip(clipnum);\r
91         }\r
92 }\r
93 \r
94 function startEditor() {\r
95         movieObj = document.mymovie;\r
96         \r
97         //register listeners\r
98         RegisterListener('qt_play', 'mymovie', 'mymovie_embed', startTimeline);\r
99         RegisterListener('qt_pause', 'mymovie', 'mymovie_embed', pauseTimeline);\r
100         RegisterListener('qt_ended', 'mymovie', 'mymovie_embed', pauseTimeline);\r
101 \r
102         /* show or hide side bar action */\r
103         $("#show_hide_caps").click(function() {\r
104                 if ($("#info-tab").css("display") == "none") {\r
105                         $("#info-tab").show();\r
106                         $("#info-container").css("margin-left", "71%");\r
107                         $("#movie-container").css("width", "70%");\r
108                         \r
109                         $(this).html('<h4 style="margin:0px">Clips <img style="float:right" src="images/application_get.png" alt="hide clips" title="hide clips" /></h4>');\r
110                 } else {\r
111                         $("#info-tab").hide();\r
112                         $("#info-container").css("margin-left", "97%");\r
113                         $("#movie-container").css("width", "96%");\r
114                         \r
115                         $(this).html('<img src="images/application_put.png" alt="show clips" title="show clips" />');   \r
116                 }\r
117         });\r
118 \r
119         /* hide clip side bar */\r
120         $("#info-tab").hide();\r
121         $("#info-container").css("margin-left", "97%");\r
122         $("#movie-container").css("width", "96%");\r
123         $("#show_hide_caps").html('<img src="images/application_put.png" alt="show clips" title="show clips" />');      \r
124                 \r
125         \r
126         $("#editor-tab").addClass('current');\r
127         $("#clips-subtab").addClass('current');\r
128         \r
129         /* global proj related vars */\r
130         if (proj.clip_collection)\r
131                 num_clips = proj.clip_collection.clips.length;\r
132 \r
133         interval = window.setInterval("QTStatus()",100);        \r
134 }\r
135 \r
136 function QTStatus() {\r
137         try {\r
138                 if (movieObj.GetPluginStatus() == "Complete") {\r
139                         window.clearInterval(interval);\r
140                         $("#movie_status").html("");\r
141                         setDisplay();\r
142                 } else {\r
143                         $("#movie_status").html("<strong>Loading media...</strong>");\r
144                 }\r
145         } catch (err) {\r
146         }\r
147 }\r
148 \r
149 function setDisplay() {\r
150         $("#movie-controls").css("visibility", "visible");\r
151         $("#clip-controls").css("visibility", "visible");\r
152         $("#make-clip").css("visibility", "visible");\r
153         $("#clip-info").css("visibility", "visible");\r
154         \r
155         $("#source-file").text(movieObj.GetURL());      \r
156 \r
157         $("#duration").text(getFormattedTime(movieObj.GetDuration()));  \r
158         dur = parseInt(movieObj.GetDuration()/movieObj.GetTimeScale()*1000);\r
159 \r
160         var mysize = movieObj.GetRectangle().split(',');\r
161         \r
162         /* set if audio file: min 250x100 */\r
163         if (mysize[3] >= 1)\r
164                 proj.media_height = mysize[3];\r
165         else \r
166                 proj.media_height = 1;\r
167         \r
168         if (mysize[2] >= 250)\r
169                 proj.media_width = mysize[2];\r
170         else \r
171                 proj.media_width = 250;\r
172 \r
173         proj.duration = getFormattedTime2(dur);\r
174         clips = proj.clip_collection.clips;     \r
175                 \r
176         $("#m_timeline").slider({ \r
177         min: 0, \r
178         max: dur,\r
179     \r
180         stop: function(e, ui) { \r
181                 $("#m_timeline").slider("value", ui.value);\r
182         }, \r
183 \r
184         slide: function(e, ui) { \r
185             $("#c_timeline").slider("value", ui.value); \r
186                         moveMovieAll(ui.value);\r
187         } \r
188     });    \r
189 \r
190         //$("#show_hide_caps").html('<img src="images/application_get.png" style="margin-bottom:-3px;" alt="hide clips" title="hide clips" /> Clips');\r
191 \r
192         pace = dur / parseInt($("#m_timeline").css("width"));\r
193 \r
194         //isn't it always 0?\r
195         if (movieObj.GetTime() > 0) {\r
196                 curTime = calcTime(movieObj.GetTime());\r
197         } else {\r
198                 curTime = getFormattedTime2(0);\r
199         }\r
200         \r
201         $("#current-time").text(curTime);       \r
202         $("#clip-time").text(curTime);  \r
203         \r
204         curTime = getMilliseconds(curTime);\r
205         $("#makeclip").attr("disabled","disabled");\r
206 \r
207         saveJson();\r
208 }\r
209 \r
210 function moveMovie(time) { //time in milliseconds\r
211         movieObj.SetTime(time*movieObj.GetTimeScale()/1000);\r
212         setCurClip(time);  \r
213             \r
214         $("#current-time").text(getFormattedTime2(time));       \r
215         \r
216         clipTime = parseInt(time - this_location.inTimeMilli);\r
217         $("#clip-time").text(getFormattedTime2(clipTime));      \r
218 \r
219         curTime = time;\r
220 }\r
221 \r
222 function moveMovieAll(time) { //time in milliseconds\r
223         movieObj.SetTime(time*movieObj.GetTimeScale()/1000);\r
224         setCurClip(time);  \r
225         \r
226         $("#c_timeline").slider("value", time);\r
227     $("#m_timeline").slider("value", time); \r
228         $("#current-time").text(getFormattedTime2(time));       \r
229         \r
230         clipTime = parseInt(time - this_location.inTimeMilli);\r
231         $("#clip-time").text(getFormattedTime2(clipTime));      \r
232         curTime = time;\r
233 }\r
234 \r
235 function startTimeline() {\r
236         /*if (getMilliseconds(calcTime(movieObj.GetTime())) == curTime-1) {\r
237                 movieObj.SetTime((curTime*movieObj.GetTimeScale()/1000)+50);\r
238         }*/\r
239         runTimer();     \r
240         \r
241         this_location_dur = getMilliseconds($("#out-time").text())-getMilliseconds($("#in-time").text());\r
242         clip_pace = this_location_dur / parseInt($("#c_timeline").css("width"));\r
243         \r
244         updateMovieMarker(curTime);     \r
245         updateClipMarker(curTime);              \r
246 }\r
247 \r
248 function pauseTimeline() {\r
249         clearTimeout(clocktimer);\r
250         clearTimeout(marker);\r
251         clearTimeout(clip_marker);\r
252 }\r
253 \r
254 function updateMovieMarker(time) {      \r
255         $("#m_timeline").slider("value", time);\r
256         marker = setTimeout("updateMovieMarker(curTime)", pace);\r
257 }\r
258 \r
259 function updateClipMarker(time) {       \r
260         $("#c_timeline").slider("value", time);\r
261         clip_marker = setTimeout("updateClipMarker(curTime)", clip_pace);\r
262 }\r
263 \r
264 function runTimer() {\r
265         curTime = calcTime(movieObj.GetTime());\r
266 \r
267         $("#current-time").text(curTime);       \r
268         curTime = getMilliseconds(curTime);\r
269                 \r
270         clipTime = parseInt(curTime - getMilliseconds($("#in-time").text()));\r
271 \r
272         if ( curTime==dur || curTime>getMilliseconds($("#out-time").text()) || curTime<getMilliseconds($("#in-time").text()) ) {        \r
273                 if (clip_playing || curTime >= dur) {\r
274                         clip.pressStop();\r
275                         moveMovieAll(getMilliseconds($("#out-time").text()));\r
276                         return;\r
277                 } else {\r
278                         setCurClip(curTime);\r
279                 }\r
280         }\r
281         $("#clip-time").text(getFormattedTime2(clipTime));      \r
282         clocktimer = setTimeout("runTimer()",1);        \r
283 }\r
284 \r
285 function setClipTimeline(cdur, cin, cout) { \r
286         //console.log('setClipTimeline', cin, cout);\r
287         \r
288         //destroy the old slider set up and create the new one\r
289     $("#c_timeline").slider("destroy");\r
290 \r
291         $("#c_timeline").slider({ \r
292         min: cin, \r
293         max: cout,\r
294                   \r
295         stop: function(e, ui) { \r
296                         $("#c_timeline").slider("value", ui.value);\r
297         },\r
298         slide: function(e, ui) { \r
299             $("#m_timeline").slider("value", ui.value); \r
300                         moveMovieAll(ui.value);\r
301         } \r
302     });    \r
303 }\r
304         \r
305 function loadClips() {\r
306         $('#numclips').text(num_clips);\r
307         clips_html = '';\r
308                 \r
309         if (num_clips > 0) {\r
310                 for (var i in clips) {\r
311                                                 \r
312                         //previous space\r
313                         if (clips[parseInt(i)-1] == undefined && clips[i].inTimeMilli>0) {\r
314                                 space_dur = getFormattedTime2(clips[i].inTimeMilli-1);\r
315                                 clips_html += '<div class="space"><span style="font-weight:bold;float:left;"><a href="#" onclick="javascript:resetClipWork();moveMovieAll(0);">Space before Clip 1</a></span><span style="float:right">'+ space_dur +'</span><span id="space'+i+'"></span><br style="clear:both;" /></div>';\r
316                         } else if ( clips[parseInt(i)-1] != undefined && (clips[i].inTimeMilli != parseInt(clips[parseInt(i)-1].outTimeMilli)+1)) { \r
317                                 space_dur = getFormattedTime2(clips[i].inTimeMilli - clips[parseInt(i)-1].outTimeMilli -2);\r
318                                 clips_html += '<div class="space"><span style="font-weight:bold;float:left;"><a href="#" onclick="javascript:resetClipWork();moveMovieAll('+(clips[parseInt(i)-1].outTimeMilli+1)+');">Space after Clip '+i+'</a></span><span style="float:right">'+ space_dur +'</span><span id="space'+i+'"></span><br style="clear:both;" /></div>';\r
319                         } \r
320                         \r
321                         //clip\r
322                         html_caption = clips[i].caption_text.replace(/\n/g, "<br />");                  \r
323                         clips[i].name = 'Clip '+(parseInt(i)+1);\r
324                         clips_html += '<div style="float:right; padding-top:5px;margin-right:5px;"><a href="#" onclick="javascript:confirmDelete('+(parseInt(i)+1)+');">X</a></div><div class="clip"><span class="clip-title"><a name="clip'+i+'" href="#" onclick="javascript:resetClipWork();moveMovieAll('+clips[i].inTimeMilli+');">'+clips[i].name+'</a></span><span id="clip'+(parseInt(i)+1)+'"></span><br />' + html_caption + '<br /><div style="float:right"> '+ clips[i].duration + '</div><span style="font-size:smaller">in: ' + clips[i].inTime + ' <br />out: '+ clips[i].outTime +'</span></div>';\r
325                                 \r
326                         //last space\r
327                         if (clips[parseInt(i)+1] == undefined && clips[i].outTimeMilli<dur) {\r
328                                 space_dur = getFormattedTime2(dur - clips[i].outTimeMilli-1);\r
329                                 clips_html += '<div class="space"><span style="font-weight:bold;float:left;"><a href="#" onclick="javascript:resetClipWork();moveMovieAll('+parseInt(clips[i].outTimeMilli+1)+');">Space after Clip '+(parseInt(i)+1)+'</a></span><span style="float:right">'+ space_dur +'</span><span id="space'+(parseInt(i)+1)+'"></span><br style="clear:both;" /></div>';\r
330                         }\r
331                         i++;\r
332                 }       \r
333                 \r
334                 $("#info-tab").html(clips_html);                \r
335         } else {\r
336                 //no clips\r
337                 clips_html = '<div class="space" style="border-bottom:0px"><span style="font-weight:bold;float:left;"><a href="#" onclick="javascript:resetClipWork();moveMovieAll(0);">Space</a></span><span style="float:right">'+ $("#duration").text() +'</span><br style="clear:both;" /></div>';\r
338                 $("#info-tab").html(clips_html);\r
339                 \r
340                 new_flag = true;\r
341         }\r
342         setCurClip(curTime);\r
343 }\r
344 \r
345 /*\r
346  * As the movie plays (or the playhead is moved), figure out what clip it's on \r
347  */ \r
348 function setCurClip(time) {\r
349         \r
350         this_location = {};\r
351         inClip = false;\r
352         var asterisk = '';\r
353                         \r
354         if (temp_in) {\r
355                 this_location.inTime = temp_in;\r
356                 this_location.inTimeMilli = getMilliseconds(temp_in);\r
357         } else {\r
358                 this_location.inTime = $("#in-time").text();\r
359                 this_location.inTimeMilli = getMilliseconds(this_location.inTime);\r
360         }\r
361         if (temp_out) {\r
362                 this_location.outTime = temp_out;\r
363                 this_location.outTimeMilli = getMilliseconds(temp_out);\r
364         } else {\r
365                 this_location.outTime = $("#out-time").text();\r
366                 this_location.outTimeMilli = getMilliseconds(this_location.outTime);\r
367         }\r
368         \r
369         if (extend == true) {           \r
370                 if( (temp_in && time < getMilliseconds(temp_in)) || (temp_out && time > getMilliseconds(temp_out) )) {\r
371                         resetClipWork();\r
372                         extend = false;\r
373                 } else {\r
374                         return;\r
375                 }\r
376         } else {\r
377                 lastLoc = curClip;\r
378         }       \r
379         \r
380         if (num_clips == 0) {\r
381                 //no clips\r
382                 this_location.name = "Space";\r
383                 \r
384                 asterisk = "#space0";\r
385                 if (!temp_in) {\r
386                         this_location.inTimeMilli = 0;\r
387                         this_location.inTime = getFormattedTime2(this_location.inTimeMilli);\r
388                 }\r
389                 if (!temp_out) {\r
390                         this_location.outTimeMilli = dur;\r
391                         this_location.outTime = getFormattedTime2(dur);\r
392                 }\r
393                 \r
394                 this_location.caption_text = "";\r
395                 curClip = 0;\r
396                 $("#makeclip").val("Make Clip");\r
397                 \r
398         } else {        \r
399                 for (var i in clips) {\r
400                         if (time < clips[i].inTimeMilli && clips[parseInt(i)-1] == undefined) { \r
401                                 //first space\r
402                                 this_location.name = "Space before Clip 1";\r
403                                 \r
404                                 asterisk = "#space0";\r
405                                                                 \r
406                                 if (!temp_in) {\r
407                                         this_location.inTimeMilli = 0;\r
408                                         this_location.inTime = getFormattedTime2(this_location.inTimeMilli);\r
409                                 }\r
410                                 if (!temp_out) {\r
411                                         this_location.outTimeMilli = parseInt(clips[i].inTimeMilli)-1;\r
412                                         this_location.outTime = getFormattedTime2(this_location.outTimeMilli);\r
413                                 }\r
414                                 \r
415                                 this_location.caption_text = "";\r
416                                 curClip = 0;\r
417                                 $("#makeclip").val("Make Clip");\r
418 \r
419                                 break;\r
420                         } else if ( (clips[parseInt(i)+1] == undefined || time < clips[parseInt(i)+1].inTimeMilli) && time > clips[i].outTimeMilli) {\r
421                                 \r
422                                 //space\r
423                                 this_location.name = "Space after Clip "+ parseInt(parseInt(i)+1);\r
424                                 \r
425                                 if (!temp_in) { \r
426                                         this_location.inTimeMilli = clips[i].outTimeMilli+1;\r
427                                         this_location.inTime = getFormattedTime2(this_location.inTimeMilli);\r
428                                 }\r
429 \r
430                                 if (!temp_out) {\r
431                                         if (clips[parseInt(i)+1] == undefined)\r
432                                                 this_location.outTimeMilli = dur;\r
433                                         else\r
434                                                 this_location.outTimeMilli = clips[parseInt(i)+1].inTimeMilli-1;\r
435                                         \r
436                                         this_location.outTime = getFormattedTime2(this_location.outTimeMilli);\r
437                                 }\r
438                                 \r
439                                 this_location.caption_text = "";\r
440                                 curClip = parseInt(i)+1;\r
441                                 asterisk = "#space"+curClip;\r
442 \r
443                                 $("#makeclip").val("Make Clip");\r
444                                 \r
445                                 break;\r
446                         } else if (time >= clips[i].inTimeMilli && time <= clips[i].outTimeMilli) {\r
447                                 //clip\r
448                                 curClip = parseInt(i)+1;\r
449                                 this_location = clips[i];\r
450                                 inClip = true;\r
451                                 $("#makeclip").val("Update Clip");\r
452                                 \r
453                                 asterisk = "#clip"+curClip;\r
454                                 break;\r
455                         } else {                                \r
456                                 //console.log("skipping this one", i, clips[i].inTimeMilli, clips[i].outTimeMilli);\r
457                         }\r
458                 }       \r
459         }       \r
460         \r
461         // 'you are here' asterisk      \r
462         $("#space"+lastLoc).text("");                           \r
463         $("#clip"+lastLoc).text("");\r
464                 \r
465         $(asterisk).html("&nbsp;<img src='images/asterisk_yellow.png' alt='current space' />");\r
466         \r
467         // in and out times\r
468         if (!temp_in) \r
469                 $("#in-time").text(this_location.inTime);\r
470         if (!temp_out)                          \r
471                 $("#out-time").text(this_location.outTime);\r
472                         \r
473         //duration\r
474         this_location.durationMilli = this_location.outTimeMilli - this_location.inTimeMilli;\r
475         this_location.duration = getFormattedTime2(this_location.durationMilli);                \r
476         $("#clip-duration").text(this_location.duration);\r
477 \r
478         \r
479         // moved into a different clip or space\r
480         if ($("#clip-name").text() != this_location.name || (new_flag && !temp_in && !temp_out && !temp_caps)) {\r
481                 \r
482                 //caption text\r
483                 $("#caption-text").val(this_location.caption_text);                     \r
484                 \r
485                 // user was working on a new clip but it gets reset when moving out of current clip\r
486                 if (temp_in || temp_out || temp_caps) {  \r
487                         resetClipWork();\r
488                 }\r
489                 \r
490                 //move scroll bar to clip\r
491                 if (curClip>2)\r
492                         $("#info-tab").scrollTop(curClip*70);\r
493                 else \r
494                         $("#info-tab").scrollTop(0);\r
495                 \r
496                 // update the clip timeline and move the playhead\r
497                 setClipTimeline(this_location.durationMilli, this_location.inTimeMilli, this_location.outTimeMilli);\r
498         }\r
499         \r
500         // name\r
501         $("#clip-name").text(this_location.name);\r
502 }\r
503 /*************************************** movie controller buttons */\r
504 \r
505 movie.normPlay = function() {\r
506         if ($("#playButton").attr("src") == "images/play.png") {\r
507                 movieObj.Play();\r
508                 $("#playButton").attr("src", 'images/pause.png');\r
509                 $("#clip-playButton").attr("src", 'images/pause.png');\r
510 \r
511         } else {\r
512                 movie.pressStop();      \r
513         }\r
514 }\r
515 \r
516 movie.pressPlay = function() {\r
517         movieObj.Play();\r
518         $("#pressButton").attr("src", 'images/pause.png');\r
519 }\r
520 movie.pressStop = function() {\r
521         movieObj.Stop();\r
522         $("#playButton").attr("src", 'images/play.png');\r
523         $("#clip-playButton").attr("src", 'images/play.png');\r
524 \r
525         $("#pressButton").attr("src", 'images/pressplay.png');\r
526 }\r
527 \r
528 \r
529 /*************************************** clip controller buttons */\r
530 \r
531 clip.normPlay = function() {            \r
532         if ($("#clip-playButton").attr("src") == "images/play.png") {\r
533                 lastplay = curTime;\r
534                 movieObj.Play();\r
535                 $("#clip-playButton").attr("src", 'images/pause.png');\r
536                 $("#playButton").attr("src", 'images/pause.png');\r
537                 clip_playing = true;\r
538         } else {\r
539                 clip.pressStop();       \r
540         }\r
541 }\r
542 \r
543 clip.pressPlay = function() {\r
544         lastplay = curTime;\r
545         moveMovie(curTime);\r
546         movieObj.Play();\r
547         $("#clip-pressButton").attr("src", 'images/pause.png');\r
548         clip_playing = true;\r
549 }\r
550 clip.pressStop = function() {\r
551         movieObj.Stop();\r
552         var max = $("#c_timeline").slider("option", "max");\r
553         if (curTime > max)\r
554                 moveMovie(max-1000);\r
555                 \r
556         $("#clip-playButton").attr("src", 'images/play.png');\r
557         $("#playButton").attr("src", 'images/play.png');\r
558         $("#clip-pressButton").attr("src", 'images/pressplay.png');\r
559         clip_playing = false;   \r
560 }\r
561 \r
562 function getIndex( myarray, item ) {\r
563         for (var i=0; i<myarray.length; i++) {\r
564                 if (myarray[i] == item) {\r
565                         return i;\r
566                 }\r
567         }\r
568 }\r
569 \r
570 clip.previous = function() {    \r
571         //if in a clip\r
572         if (inClip && curClip > 1) {\r
573                 //go to prev space (prev clip's out time +1)\r
574                 if (clips[curClip-2].outTimeMilli+1 != clips[curClip-1].inTimeMilli) {\r
575                         moveMovieAll(clips[curClip-2].outTimeMilli+1);\r
576                         \r
577                 //if no space, go to prev clip\r
578                 } else {\r
579                         moveMovieAll(clips[curClip-2].inTimeMilli);             \r
580                 }\r
581                 \r
582         //if in a space, go to prev clip        \r
583         } else if (!inClip && curClip>0) {\r
584                 moveMovieAll(clips[curClip-1].inTimeMilli);\r
585         //if in first space or clip, go to start        \r
586         } else {        \r
587                 moveMovieAll(0);\r
588         }\r
589 }\r
590 clip.next = function() {        \r
591         //if in a clip\r
592         if (inClip && clips[curClip] != undefined) {\r
593                 \r
594                 //go to next space (next clip's out time +1)\r
595                 if (clips[curClip].inTimeMilli != clips[curClip-1].outTimeMilli+1) {\r
596                         moveMovieAll(clips[curClip-1].outTimeMilli+1);\r
597                         \r
598                 //if no space, go to next clip\r
599                 } else  {\r
600                         moveMovieAll(clips[curClip].inTimeMilli);               \r
601                 }\r
602                 \r
603         //if in a space, go to next clip        \r
604         } else if (!inClip && clips[curClip] != undefined) {\r
605                 moveMovieAll(clips[curClip].inTimeMilli);\r
606                 \r
607         //if at the end \r
608         } else if (clips[clips.length-1] != undefined) {\r
609                 if (clips[clips.length-1].outTimeMilli == dur)\r
610                         moveMovieAll(clips[clips.length-1].inTimeMilli);\r
611                 else\r
612                         moveMovieAll(clips[clips.length-1].outTimeMilli+1);\r
613         }\r
614 \r
615 }\r
616 \r
617 clip.goToStart = function() {\r
618         moveMovieAll(getMilliseconds($("#in-time").text()));\r
619 }\r
620 clip.goToEnd = function() {\r
621         moveMovieAll(getMilliseconds($("#out-time").text()));\r
622 }\r
623 clip.stepBack = function(step) {\r
624         if (curTime >= step && (curTime-step >= getMilliseconds($("#in-time").text())) )\r
625                 moveMovieAll(curTime - step);   \r
626 }\r
627 clip.stepForward = function(step) {             \r
628         if (  curTime+step <= getMilliseconds($("#out-time").text()) ) \r
629                 moveMovieAll(curTime + step);   \r
630 }\r
631 \r
632 clip.lastPlay = function() {            \r
633         moveMovieAll(lastplay); \r
634 }\r
635 \r
636 /*************** making a clip */\r
637 \r
638 clip.newInTime = function() {\r
639         var clip_dur = 0;\r
640         clip_dur = this_location.outTimeMilli-curTime;  \r
641         if (clip_dur <= MIN_CLIP_DUR) {\r
642                 alert("Too few frames to make a clip!");\r
643         } else {\r
644                 $("#in").css("color","red");    \r
645                 $("#in-time").css("color","red");\r
646                 $("#clip-duration").css("color","red"); \r
647                 $("#makeclip").removeAttr("disabled");\r
648                 $("#clip-duration").text(getFormattedTime2(clip_dur));\r
649 \r
650                 //old_in = getMilliseconds($("#in-time").text());\r
651                 \r
652                 temp_in = getFormattedTime2(curTime);\r
653                 $("#in-time").text(temp_in);\r
654                                 \r
655                 setClipTimeline(clip_dur, curTime, this_location.outTimeMilli);\r
656                 moveMovieAll(curTime);\r
657                                 \r
658                 /*if (new_flag)\r
659                         $("#in-undo").html("<a href='#' onclick='javascript:clip.undoIn(0)'><img src='images/bullet_delete.png' alt='cancel in-time' title='cancel in-time' /></a>");\r
660                 else if (inAClip())\r
661                         $("#in-undo").html("<a href='#' onclick='javascript:clip.undoIn("+milli_ins[curClip-1]+")'><img src='images/bullet_delete.png' alt='cancel in-time' title='cancel in-time' /></a>");\r
662                 else    \r
663                         $("#in-undo").html("<a href='#' onclick='javascript:clip.undoIn("+milli_spaceins[curClip]+")'><img src='images/bullet_delete.png' alt='cancel in-time' title='cancel in-time' /></a>");\r
664                 */\r
665         }       \r
666 }\r
667 \r
668 \r
669 clip.newOutTime = function() {\r
670         if (curTime != getMilliseconds($("#out-time").text())) {\r
671                 var clip_dur = 0;\r
672 \r
673                 if (temp_in) {\r
674                         clip_dur = curTime-getMilliseconds(temp_in);\r
675                 } else {\r
676                         clip_dur = curTime-getMilliseconds($("#in-time").text());\r
677                 }               \r
678                 \r
679                 if (clip_dur <= MIN_CLIP_DUR) {\r
680                         alert("Too few frames to make a clip!");\r
681                 } else {\r
682 \r
683                         $("#out").css("color","red");\r
684                         $("#out-time").css("color","red");\r
685                         $("#clip-duration").css("color","red");\r
686                         $("#makeclip").removeAttr("disabled");          \r
687                         $("#clip-duration").text(getFormattedTime2(clip_dur));                  \r
688                         \r
689                         temp_out = getFormattedTime2(curTime);\r
690                         $("#out-time").text(temp_out);\r
691                         \r
692                         setClipTimeline(curTime - getMilliseconds($("#in-time").text()), getMilliseconds($("#in-time").text()), curTime);\r
693                         moveMovieAll(curTime);\r
694 \r
695                         /*if (new_flag)\r
696                                 $("#out-undo").html("<a href='#' onclick='javascript:clip.undoOut("+dur+")'><img src='images/bullet_delete.png' alt='cancel out-time' title='cancel out-time' /></a>");\r
697                         else if (inAClip())\r
698                                 $("#out-undo").html("<a href='#' onclick='javascript:clip.undoOut("+milli_outs[curClip-1]+")'><img src='images/bullet_delete.png' alt='cancel out-time' title='cancel out-time' /></a>");\r
699                         else    \r
700                                 $("#out-undo").html("<a href='#' onclick='javascript:clip.undoOut("+milli_spaceouts[curClip]+")'><img src='images/bullet_delete.png' alt='cancel out-time' title='cancel out-time' /></a>");\r
701                         */                                      \r
702                 }\r
703         }\r
704 }\r
705 \r
706 clip.addPrevSpace = function() {                \r
707                 \r
708         //if the current clip's inTime is > 0 and also not equal to the prev clip's outTime\r
709         if (inClip && clips[curClip-1].inTimeMilli > 0 && ( clips[curClip-2]==undefined || clips[curClip-1].inTimeMilli != clips[curClip-2].outTimeMilli) ) {\r
710                                 \r
711                 var newin = 0;\r
712                 \r
713                 //make clip start = last clip's end     \r
714                 if (clips[curClip-2] != undefined) {\r
715                         newin = clips[curClip-2].outTimeMilli + 1;\r
716                 } else {\r
717                         newin = 0;\r
718                 }\r
719                 temp_in = getFormattedTime2(newin);\r
720                 var oldout = getMilliseconds($("#out-time").text())\r
721                 var caption_text = $("#caption-text").val();\r
722                                 \r
723                 //set new temp values\r
724                 $("#in-time").css("color","red");\r
725                 $("#in-time").text(temp_in);\r
726                 \r
727                 $("#clip-duration").css("color","red"); \r
728                 $("#makeclip").removeAttr("disabled");\r
729                 $("#makeclip").val("Update Clip");\r
730                 \r
731                 //$("#caption-text").val(caption_text);                         \r
732                 $("#clip-duration").text(getFormattedTime2(oldout - newin));            \r
733                 \r
734                 extend = true;          \r
735                 setClipTimeline(oldout - newin, newin, oldout);\r
736                 moveMovieAll(curTime);\r
737                 //$("#in-undo").html("<a href='#' onclick='javascript:clip.undoIn("+milli_ins[curClip-1]+")'><img src='images/bullet_delete.png' alt='cancel in-time' title='cancel in-time' /></a>");\r
738         }\r
739 }\r
740 \r
741 clip.addNextSpace = function() {                \r
742         \r
743         if (inClip && clips[curClip-1].outTimeMilli < dur && (clips[curClip]==undefined || clips[curClip-1].outTimeMilli != clips[curClip].inTimeMilli)) {\r
744                 var newout = 0;\r
745                 //make clip start = last clip's end     \r
746                 if (clips[curClip] != undefined) {\r
747                         newout = clips[curClip].inTimeMilli - 1;\r
748                 } else {\r
749                         newout = dur;\r
750                 }\r
751                 temp_out = getFormattedTime2(newout);\r
752 \r
753                 var oldin = getMilliseconds($("#in-time").text())\r
754                 var caption_text = $("#caption-text").val();\r
755                 \r
756                 //set new temp values\r
757                 $("#out-time").css("color","red");\r
758                 $("#out-time").text(temp_out);\r
759                 \r
760                 $("#clip-duration").css("color","red"); \r
761                 $("#makeclip").removeAttr("disabled");\r
762                 $("#makeclip").val("Update Clip");\r
763                 \r
764                 //$("#caption-text").val(caption_text);                         \r
765                 $("#clip-duration").text(getFormattedTime2(newout - oldin));            \r
766                                 \r
767                 extend = true;          \r
768                 setClipTimeline(newout - oldin, oldin, newout);\r
769                 moveMovieAll(curTime);  \r
770                 //$("#out-undo").html("<a href='#' onclick='javascript:clip.undoOut("+milli_outs[curClip-1]+")'><img src='images/bullet_delete.png' alt='cancel out-time' title='cancel out-time' /></a>");\r
771         }\r
772 }\r
773 \r
774 /****** making/updating and saving clips **/\r
775 \r
776 movie.saveClip = function() {\r
777         var caption_text = $("#caption-text").val();\r
778         var clipnum = 0;\r
779                 \r
780         // button should be disabled but double check that at least one time has changed, or caption text has changed\r
781         //if (temp_in || temp_out) {   \r
782                 resetClipWork();\r
783                 \r
784                 if (!temp_in) {\r
785                         temp_in = $("#in-time").text();\r
786                 }\r
787                 if (!temp_out) {\r
788                         temp_out = $("#out-time").text();\r
789                 }               \r
790                 \r
791                 this_location.inTime = temp_in;\r
792                 this_location.outTime = temp_out;\r
793                 this_location.inTimeMilli = getMilliseconds(temp_in);\r
794                 this_location.outTimeMilli = getMilliseconds(temp_out);\r
795                 \r
796                 this_location.durationMilli = this_location.outTimeMilli - this_location.inTimeMilli;\r
797                 this_location.duration = getFormattedTime2(this_location.durationMilli);\r
798                 this_location.caption_text = caption_text;\r
799                 \r
800                 if($("#makeclip").val() == "Make Clip") { \r
801                         num_clips++;\r
802                         \r
803                         if (num_clips > 0) {\r
804                                 //add to clips list\r
805                                 clips[num_clips-1] = this_location;\r
806                                 \r
807                                 //sort clips by inTimeMilli\r
808                                 clips.sort(function (a,b) { return a.inTimeMilli-b.inTimeMilli});\r
809                                 \r
810                         } else {\r
811                                 clips = new Array(); //clips\r
812                                 clips[0] = this_location;\r
813                                 \r
814                                 new_flag = 0;\r
815                         }\r
816                 } else {\r
817                         clips[curClip-1] = this_location;\r
818                 }\r
819                                                                                         \r
820                 //loadClips();\r
821                 \r
822                 var move_to = getMilliseconds(temp_out) + 1;\r
823                  if (move_to < (dur - MIN_CLIP_DUR) ) {\r
824                          setTimeout("moveMovieAll("+move_to+")", 500);  \r
825                  } else {\r
826                          setTimeout("moveMovie(curTime)", 500);                                          \r
827                  }                              \r
828 \r
829                 \r
830                 temp_in = '';\r
831                 temp_out = '';\r
832                 \r
833                 saveJson();\r
834         //}\r
835 }\r
836 \r
837 function deleteClip(clipnum) {\r
838         num_clips--;\r
839         clips.splice(clipnum-1, 1);\r
840         saveJson();     \r
841 }\r
842 \r
843 function saveJson() {\r
844         //save file\r
845         json = JSON.stringify(proj);\r
846         \r
847         $.post("include/workflow.php", { task: 'save_json', json:json, pid:proj.id }, function(data) {\r
848                 if (!data) { \r
849                         loadClips();\r
850                 } else {\r
851                         alert(data);\r
852                 }\r
853                 \r
854         } );\r
855         \r
856         var d = new Date();\r
857 \r
858         var curr_hour = d.getHours();\r
859         var curr_min = d.getMinutes();\r
860         \r
861         $("#last-saved").text('Last saved at '+curr_hour + ":" + ((curr_min < 10) ? "0" : "") + curr_min);\r
862 }\r
863 \r
864 /****************reset UI */\r
865 \r
866 function resetClipWork() {\r
867         $("#in").css("color","black");  \r
868         $("#out").css("color","black"); \r
869         $("#in-time").css("color","black");\r
870         $("#out-time").css("color","black");                    \r
871         $("#clip-duration").css("color","black");       \r
872         temp_in = 0;\r
873         temp_out = 0;\r
874         temp_caps = ''; \r
875         \r
876         extend = false;\r
877         $("#makeclip").attr("disabled","disabled");\r
878         $("#in-undo").html("");\r
879         $("#out-undo").html("");\r
880 \r
881 }\r
882 \r
883 \r