1 /* TODO: Separate Project-specific data from Source */ |
1 /* TODO: Separate Project-specific data from Source */ |
2 |
2 |
3 /* model.js is where data is stored in a standard form, whatever the serializer */ |
3 /* model.js is where data is stored in a standard form, whatever the serializer */ |
4 IriSP.Model = (function (ns) { |
4 IriSP.Model = (function (ns) { |
|
5 |
|
6 function pad(n, x, b) { |
|
7 b = b || 10; |
|
8 var s = (x).toString(b); |
|
9 while (s.length < n) { |
|
10 s = "0" + s; |
|
11 } |
|
12 return s; |
|
13 } |
|
14 |
|
15 function rand16(n) { |
|
16 return pad(n, Math.floor(Math.random()*Math.pow(16,n)), 16); |
|
17 } |
|
18 |
|
19 var uidbase = rand16(8) + "-" + rand16(4) + "-", uidincrement = Math.floor(Math.random()*0x10000); |
5 |
20 |
6 var Model = { |
21 var Model = { |
7 _SOURCE_STATUS_EMPTY : 0, |
22 _SOURCE_STATUS_EMPTY : 0, |
8 _SOURCE_STATUS_WAITING : 1, |
23 _SOURCE_STATUS_WAITING : 1, |
9 _SOURCE_STATUS_READY : 2, |
24 _SOURCE_STATUS_READY : 2, |
10 _ID_AUTO_INCREMENT : 0, |
|
11 _ID_BASE : (function(_d) { |
|
12 function pad(n){return n<10 ? '0'+n : n} |
|
13 function fillrand(n) { |
|
14 var _res = '' |
|
15 for (var i=0; i<n; i++) { |
|
16 _res += Math.floor(16*Math.random()).toString(16); |
|
17 } |
|
18 return _res; |
|
19 } |
|
20 return _d.getUTCFullYear() + '-' |
|
21 + pad(_d.getUTCMonth()+1) + '-' |
|
22 + pad(_d.getUTCDate()) + '-' |
|
23 + fillrand(16); |
|
24 })(new Date()), |
|
25 getUID : function() { |
25 getUID : function() { |
26 var _n = (++this._ID_AUTO_INCREMENT).toString(); |
26 return uidbase + pad(4, (++uidincrement % 0x10000), 16) + "-" + rand16(4) + "-" + rand16(6) + rand16(6); |
27 while (_n.length < 4) { |
|
28 _n = '0' + _n |
|
29 } |
|
30 return "autoid-" + this._ID_BASE + '-' + _n; |
|
31 }, |
27 }, |
32 regexpFromTextOrArray : function(_textOrArray, _testOnly, _iexact) { |
28 regexpFromTextOrArray : function(_textOrArray, _testOnly, _iexact) { |
33 var _testOnly = _testOnly || false, |
29 var _testOnly = _testOnly || false, |
34 _iexact = _iexact || false; |
30 _iexact = _iexact || false; |
35 function escapeText(_text) { |
31 function escapeText(_text) { |
73 var _res = new Date(); |
69 var _res = new Date(); |
74 _res.setTime(Number(time)); |
70 _res.setTime(Number(time)); |
75 return _res; |
71 return _res; |
76 }, |
72 }, |
77 dateToIso : function(d) { |
73 dateToIso : function(d) { |
78 function pad(n){return n<10 ? '0'+n : n} |
|
79 return d.getUTCFullYear()+'-' |
74 return d.getUTCFullYear()+'-' |
80 + pad(d.getUTCMonth()+1)+'-' |
75 + pad(2, d.getUTCMonth()+1)+'-' |
81 + pad(d.getUTCDate())+'T' |
76 + pad(2, d.getUTCDate())+'T' |
82 + pad(d.getUTCHours())+':' |
77 + pad(2, d.getUTCHours())+':' |
83 + pad(d.getUTCMinutes())+':' |
78 + pad(2, d.getUTCMinutes())+':' |
84 + pad(d.getUTCSeconds())+'Z' |
79 + pad(2, d.getUTCSeconds())+'Z' |
85 } |
80 } |
86 } |
81 } |
87 |
82 |
88 /* |
83 /* |
89 * Model.List is a class for a list of elements (e.g. annotations, medias, etc. that each have a distinct ID) |
84 * Model.List is a class for a list of elements (e.g. annotations, medias, etc. that each have a distinct ID) |
345 Model.Time.prototype.valueOf = function() { |
340 Model.Time.prototype.valueOf = function() { |
346 return this.milliseconds; |
341 return this.milliseconds; |
347 } |
342 } |
348 |
343 |
349 Model.Time.prototype.toString = function(showCs) { |
344 Model.Time.prototype.toString = function(showCs) { |
350 function pad(_n) { |
|
351 var _res = _n.toString(); |
|
352 while (_res.length < 2) { |
|
353 _res = '0' + _res; |
|
354 } |
|
355 return _res; |
|
356 } |
|
357 var _hms = this.getHMS(), |
345 var _hms = this.getHMS(), |
358 _res = ''; |
346 _res = ''; |
359 if (_hms.hours) { |
347 if (_hms.hours) { |
360 _res += _hms.hours + ':' |
348 _res += _hms.hours + ':' |
361 } |
349 } |
362 _res += pad(_hms.minutes) + ':' + pad(_hms.seconds); |
350 _res += pad(2, _hms.minutes) + ':' + pad(2, _hms.seconds); |
363 if (showCs) { |
351 if (showCs) { |
364 _res += "." + Math.round(_hms.milliseconds / 100) |
352 _res += "." + Math.round(_hms.milliseconds / 100) |
365 } |
353 } |
366 return _res; |
354 return _res; |
367 } |
355 } |
407 |
395 |
408 /* */ |
396 /* */ |
409 |
397 |
410 Model.Element = function(_id, _source) { |
398 Model.Element = function(_id, _source) { |
411 this.elementType = 'element'; |
399 this.elementType = 'element'; |
412 if (typeof _source === "undefined") { |
|
413 return; |
|
414 } |
|
415 if (typeof _id === "undefined" || !_id) { |
|
416 _id = Model.getUID(); |
|
417 } |
|
418 this.source = _source; |
|
419 this.id = _id; |
|
420 this.title = ""; |
400 this.title = ""; |
421 this.description = ""; |
401 this.description = ""; |
422 this.__events = {} |
402 this.__events = {} |
|
403 if (typeof _source === "undefined") { |
|
404 return; |
|
405 } |
|
406 if (typeof _id === "undefined" || !_id) { |
|
407 _id = Model.getUID(); |
|
408 } |
|
409 this.source = _source; |
|
410 this.id = _id; |
423 this.source.directory.addElement(this); |
411 this.source.directory.addElement(this); |
424 } |
412 } |
425 |
413 |
426 Model.Element.prototype.toString = function() { |
414 Model.Element.prototype.toString = function() { |
427 return this.elementType + (this.elementType !== 'element' ? ', id=' + this.id + ', title="' + this.title + '"' : ''); |
415 return this.elementType + (this.elementType !== 'element' ? ', id=' + this.id + ', title="' + this.title + '"' : ''); |
487 this.on("pause", function() { |
475 this.on("pause", function() { |
488 _this.paused = true; |
476 _this.paused = true; |
489 }); |
477 }); |
490 this.on("timeupdate", function(_time) { |
478 this.on("timeupdate", function(_time) { |
491 _this.currentTime = _time; |
479 _this.currentTime = _time; |
492 }); |
|
493 } |
|
494 |
|
495 Model.Playable.prototype = new Model.Element(); |
|
496 |
|
497 Model.Playable.prototype.getCurrentTime = function() { |
|
498 return this.currentTime; |
|
499 } |
|
500 |
|
501 Model.Playable.prototype.getVolume = function() { |
|
502 return this.volume; |
|
503 } |
|
504 |
|
505 Model.Playable.prototype.getPaused = function() { |
|
506 return this.paused; |
|
507 } |
|
508 |
|
509 Model.Playable.prototype.getMuted = function() { |
|
510 return this.muted; |
|
511 } |
|
512 |
|
513 Model.Playable.prototype.setCurrentTime = function(_time) { |
|
514 this.trigger("setcurrenttime",_time); |
|
515 } |
|
516 |
|
517 Model.Playable.prototype.setVolume = function(_vol) { |
|
518 this.trigger("setvolume",_vol); |
|
519 } |
|
520 |
|
521 Model.Playable.prototype.setMuted = function(_muted) { |
|
522 this.trigger("setmuted",_muted); |
|
523 } |
|
524 |
|
525 Model.Playable.prototype.play = function() { |
|
526 this.trigger("setplay"); |
|
527 } |
|
528 |
|
529 Model.Playable.prototype.pause = function() { |
|
530 this.trigger("setpause"); |
|
531 } |
|
532 |
|
533 Model.Playable.prototype.show = function() {} |
|
534 |
|
535 Model.Playable.prototype.hide = function() {} |
|
536 |
|
537 /* */ |
|
538 |
|
539 Model.Media = function(_id, _source) { |
|
540 Model.Playable.call(this, _id, _source); |
|
541 this.elementType = 'media'; |
|
542 this.duration = new Model.Time(); |
|
543 this.video = ''; |
|
544 |
|
545 var _this = this; |
|
546 this.on("timeupdate", function(_time) { |
|
547 _this.getAnnotations().filter(function(_a) { |
480 _this.getAnnotations().filter(function(_a) { |
548 return (_a.end <= _time || _a.begin > _time) && _a.playing |
481 return (_a.end <= _time || _a.begin > _time) && _a.playing |
549 }).forEach(function(_a) { |
482 }).forEach(function(_a) { |
550 _a.playing = false; |
483 _a.playing = false; |
551 _a.trigger("leave"); |
484 _a.trigger("leave"); |
|
485 _this.trigger("leave-annotation",_a); |
552 }); |
486 }); |
553 _this.getAnnotations().filter(function(_a) { |
487 _this.getAnnotations().filter(function(_a) { |
554 return _a.begin <= _time && _a.end > _time && !_a.playing |
488 return _a.begin <= _time && _a.end > _time && !_a.playing |
555 }).forEach(function(_a) { |
489 }).forEach(function(_a) { |
556 _a.playing = true; |
490 _a.playing = true; |
557 _a.trigger("enter"); |
491 _a.trigger("enter"); |
|
492 _this.trigger("enter-annotation",_a); |
558 }); |
493 }); |
559 }); |
494 }); |
|
495 } |
|
496 |
|
497 Model.Playable.prototype = new Model.Element(); |
|
498 |
|
499 Model.Playable.prototype.getCurrentTime = function() { |
|
500 return this.currentTime; |
|
501 } |
|
502 |
|
503 Model.Playable.prototype.getVolume = function() { |
|
504 return this.volume; |
|
505 } |
|
506 |
|
507 Model.Playable.prototype.getPaused = function() { |
|
508 return this.paused; |
|
509 } |
|
510 |
|
511 Model.Playable.prototype.getMuted = function() { |
|
512 return this.muted; |
|
513 } |
|
514 |
|
515 Model.Playable.prototype.setCurrentTime = function(_time) { |
|
516 this.trigger("setcurrenttime",_time); |
|
517 } |
|
518 |
|
519 Model.Playable.prototype.setVolume = function(_vol) { |
|
520 this.trigger("setvolume",_vol); |
|
521 } |
|
522 |
|
523 Model.Playable.prototype.setMuted = function(_muted) { |
|
524 this.trigger("setmuted",_muted); |
|
525 } |
|
526 |
|
527 Model.Playable.prototype.play = function() { |
|
528 this.trigger("setplay"); |
|
529 } |
|
530 |
|
531 Model.Playable.prototype.pause = function() { |
|
532 this.trigger("setpause"); |
|
533 } |
|
534 |
|
535 Model.Playable.prototype.show = function() {} |
|
536 |
|
537 Model.Playable.prototype.hide = function() {} |
|
538 |
|
539 /* */ |
|
540 |
|
541 Model.Media = function(_id, _source) { |
|
542 Model.Playable.call(this, _id, _source); |
|
543 this.elementType = 'media'; |
|
544 this.duration = new Model.Time(); |
|
545 this.video = ''; |
|
546 var _this = this; |
560 } |
547 } |
561 |
548 |
562 Model.Media.prototype = new Model.Playable(); |
549 Model.Media.prototype = new Model.Playable(); |
563 |
550 |
564 /* Default functions to be overriden by players */ |
551 /* Default functions to be overriden by players */ |
735 Model.Playable.call(this, _id, _source); |
722 Model.Playable.call(this, _id, _source); |
736 this.elementType = 'mashup'; |
723 this.elementType = 'mashup'; |
737 this.duration = new Model.Time(); |
724 this.duration = new Model.Time(); |
738 this.segments = new Model.List(_source.directory); |
725 this.segments = new Model.List(_source.directory); |
739 this.loaded = false; |
726 this.loaded = false; |
740 var _currentMedia = null; |
727 var _this = this; |
741 var _this = this; |
|
742 this.on("timeupdate", function(_time) { |
|
743 _this.getSegments().filter(function(_a) { |
|
744 return (_a.end <= _time || _a.begin > _time) && _a.playing |
|
745 }).forEach(function(_a) { |
|
746 _a.playing = false; |
|
747 _a.trigger("leave"); |
|
748 }); |
|
749 _this.getSegments().filter(function(_a) { |
|
750 return _a.begin <= _time && _a.end > _time && !_a.playing |
|
751 }).forEach(function(_a) { |
|
752 _a.playing = true; |
|
753 _a.trigger("enter"); |
|
754 var _m = _a.getMedia(); |
|
755 if (_m !== _currentMedia) { |
|
756 if (_currentMedia) { |
|
757 _currentMedia.trigger("leave"); |
|
758 } |
|
759 _m.trigger("enter"); |
|
760 _currentMedia = _m; |
|
761 } |
|
762 }); |
|
763 }); |
|
764 this._updateTimes = function() { |
728 this._updateTimes = function() { |
765 _this.updateTimes(); |
729 _this.updateTimes(); |
766 _this.trigger("change"); |
730 _this.trigger("change"); |
767 } |
731 } |
768 this.on("add", this._updateTimes); |
732 this.on("add", this._updateTimes); |