diff -r 12978893bbf0 -r 8a8b6097d382 integration/js/model.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/integration/js/model.js Wed Oct 24 15:58:27 2012 +0200 @@ -0,0 +1,987 @@ +/* TODO: Separate Project-specific data from Source */ + +/* model.js is where data is stored in a standard form, whatever the serializer */ + +(function (ns) { + +var Model = { + _SOURCE_STATUS_EMPTY : 0, + _SOURCE_STATUS_WAITING : 1, + _SOURCE_STATUS_READY : 2, + _ID_AUTO_INCREMENT : 0, + _ID_BASE : (function(_d) { + function pad(n){return n<10 ? '0'+n : n} + function fillrand(n) { + var _res = '' + for (var i=0; i _time) && _a.playing + }).forEach(function(_a) { + _a.playing = false; + _a.trigger("leave"); + }); + _this.getAnnotations().filter(function(_a) { + return _a.begin <= _time && _a.end > _time && !_a.playing + }).forEach(function(_a) { + _a.playing = true; + _a.trigger("enter"); + }); + }); +} + +Model.Media.prototype = new Model.Playable(); + +/* Default functions to be overriden by players */ + +Model.Media.prototype.setDuration = function(_durationMs) { + this.duration.setMilliseconds(_durationMs); +} + +Model.Media.prototype.getAnnotations = function() { + return this.getRelated("annotation"); +} + +Model.Media.prototype.getAnnotationsByTypeTitle = function(_title) { + var _annTypes = this.source.getAnnotationTypes().searchByTitle(_title).pluck("id"); + if (_annTypes.length) { + return this.getAnnotations().filter(function(_annotation) { + return ns._(_annTypes).indexOf(_annotation.getAnnotationType().id) !== -1; + }); + } else { + return new Model.List(this.source.directory) + } +} + +/* */ + +Model.Tag = function(_id, _source) { + Model.Element.call(this, _id, _source); + this.elementType = 'tag'; +} + +Model.Tag.prototype = new Model.Element(); + +Model.Tag.prototype.getAnnotations = function() { + return this.getRelated("annotation"); +} + +/* */ +Model.AnnotationType = function(_id, _source) { + Model.Element.call(this, _id, _source); + this.elementType = 'annotationType'; +} + +Model.AnnotationType.prototype = new Model.Element(); + +Model.AnnotationType.prototype.getAnnotations = function() { + return this.getRelated("annotation"); +} + +/* Annotation + * */ + +Model.Annotation = function(_id, _source) { + Model.Element.call(this, _id, _source); + this.elementType = 'annotation'; + this.begin = new Model.Time(); + this.end = new Model.Time(); + this.tag = new Model.Reference(_source, []); + this.playing = false; + var _this = this; + this.on("click", function() { + _this.getMedia().setCurrentTime(_this.begin); + }); +} + +Model.Annotation.prototype = new Model.Element(); + +Model.Annotation.prototype.setBegin = function(_beginMs) { + this.begin.setMilliseconds(_beginMs); +} + +Model.Annotation.prototype.setEnd = function(_beginMs) { + this.end.setMilliseconds(_beginMs); +} + +Model.Annotation.prototype.setMedia = function(_idRef) { + this.setReference("media", _idRef); +} + +Model.Annotation.prototype.getMedia = function() { + return this.getReference("media"); +} + +Model.Annotation.prototype.setAnnotationType = function(_idRef) { + this.setReference("annotationType", _idRef); +} + +Model.Annotation.prototype.getAnnotationType = function() { + return this.getReference("annotationType"); +} + +Model.Annotation.prototype.setTags = function(_idRefs) { + this.setReference("tag", _idRefs); +} + +Model.Annotation.prototype.getTags = function() { + return this.getReference("tag"); +} + +Model.Annotation.prototype.getTagTexts = function() { + return this.getTags().getTitles(); +} + +Model.Annotation.prototype.getDuration = function() { + return new Model.Time(this.end.milliseconds - this.begin.milliseconds) +} + +/* */ + +Model.MashedAnnotation = function(_mashup, _annotation) { + Model.Element.call(this, _mashup.id + "_" + _annotation.id, _annotation.source); + this.elementType = 'mashedAnnotation'; + this.annotation = _annotation; + this.begin = new Model.Time(_mashup.duration); + this.end = new Model.Time(_mashup.duration + _annotation.getDuration()); + this.title = this.annotation.title; + this.description = this.annotation.description; + this.color = this.annotation.color; + var _this = this; + this.on("click", function() { + _mashup.setCurrentTime(_this.begin); + }); +} + +Model.MashedAnnotation.prototype = new Model.Element(null); + +Model.MashedAnnotation.prototype.getMedia = function() { + return this.annotation.getReference("media"); +} + +Model.MashedAnnotation.prototype.getAnnotationType = function() { + return this.annotation.getReference("annotationType"); +} + +Model.MashedAnnotation.prototype.getTags = function() { + return this.annotation.getReference("tag"); +} + +Model.MashedAnnotation.prototype.getTagTexts = function() { + return this.annotation.getTags().getTitles(); +} + +Model.MashedAnnotation.prototype.getDuration = function() { + return this.annotation.getDuration(); +} + +/* */ + +Model.Mashup = function(_id, _source) { + Model.Playable.call(this, _id, _source); + this.elementType = 'mashup'; + this.duration = new Model.Time(); + this.segments = new Model.List(_source.directory); + this.medias = new Model.List(_source.directory); + var _currentMedia = null; + var _this = this; + this.on("timeupdate", function(_time) { + _this.getAnnotations().filter(function(_a) { + return (_a.end <= _time || _a.begin > _time) && _a.playing + }).forEach(function(_a) { + _a.playing = false; + _a.trigger("leave"); + }); + _this.getAnnotations().filter(function(_a) { + return _a.begin <= _time && _a.end > _time && !_a.playing + }).forEach(function(_a) { + _a.playing = true; + _a.trigger("enter"); + var _m = _a.getMedia(); + if (_m !== _currentMedia) { + if (_currentMedia) { + _currentMedia.trigger("leave"); + } + _m.trigger("enter"); + _currentMedia = _m; + } + }); + }); +} + +Model.Mashup.prototype = new Model.Playable(); + +Model.Mashup.prototype.addSegment = function(_annotation) { + var _mashedAnnotation = new Model.MashedAnnotation(this, _annotation); + this.duration.setMilliseconds(_mashedAnnotation.end); + this.segments.push(_mashedAnnotation); + this.medias.push(_annotation.getMedia()); +} + +Model.Mashup.prototype.addSegmentById = function(_elId) { + var _annotation = this.source.getElement(_elId); + if (typeof _annotation !== "undefined") { + this.addSegment(_annotation); + } +} + +Model.Mashup.prototype.getAnnotations = function() { + return this.segments; +} + +Model.Mashup.prototype.getMedias = function() { + return this.medias; +} + +Model.Mashup.prototype.getAnnotationsByTypeTitle = function(_title) { + var _annTypes = this.source.getAnnotationTypes().searchByTitle(_title).pluck("id"); + if (_annTypes.length) { + return this.getAnnotations().filter(function(_annotation) { + return ns._(_annTypes).indexOf(_annotation.getAnnotationType().id) !== -1; + }); + } else { + return new Model.List(this.source.directory) + } +} + +Model.Mashup.prototype.getAnnotationAtTime = function(_time) { + var _list = this.segments.filter(function(_annotation) { + return _annotation.begin <= _time && _annotation.end > _time; + }); + if (_list.length) { + return _list[0]; + } else { + return undefined; + } +} + +Model.Mashup.prototype.getMediaAtTime = function(_time) { + var _annotation = this.getAnnotationAtTime(_time); + if (typeof _annotation !== "undefined") { + return _annotation.getMedia(); + } else { + return undefined; + } +} + +/* */ + +Model.Source = function(_config) { + this.status = Model._SOURCE_STATUS_EMPTY; + this.elementType = "source"; + if (typeof _config !== "undefined") { + var _this = this; + ns._(_config).forEach(function(_v, _k) { + _this[_k] = _v; + }) + this.callbackQueue = []; + this.contents = {}; + this.get(); + } +} + +Model.Source.prototype = new Model.Element(); + +Model.Source.prototype.addList = function(_listId, _contents) { + if (typeof this.contents[_listId] === "undefined") { + this.contents[_listId] = new Model.List(this.directory); + } + this.contents[_listId].addElements(_contents); +} + +Model.Source.prototype.getList = function(_listId, _global) { + _global = (typeof _global !== "undefined" && _global); + if (_global || typeof this.contents[_listId] === "undefined") { + return this.directory.getGlobalList().filter(function(_e) { + return (_e.elementType === _listId); + }); + } else { + return this.contents[_listId]; + } +} + +Model.Source.prototype.forEach = function(_callback) { + var _this = this; + ns._(this.contents).forEach(function(_value, _key) { + _callback.call(_this, _value, _key); + }) +} + +Model.Source.prototype.getElement = function(_elId) { + return this.directory.getElement(_elId); +} + +Model.Source.prototype.get = function() { + this.status = Model._SOURCE_STATUS_WAITING; + this.handleCallbacks(); +} + +/* We defer the callbacks calls so they execute after the queue is cleared */ +Model.Source.prototype.deferCallback = function(_callback) { + var _this = this; + ns._.defer(function() { + _callback.call(_this); + }); +} + +Model.Source.prototype.handleCallbacks = function() { + this.status = Model._SOURCE_STATUS_READY; + while (this.callbackQueue.length) { + this.deferCallback(this.callbackQueue.splice(0,1)[0]); + } +} +Model.Source.prototype.onLoad = function(_callback) { + if (this.status === Model._SOURCE_STATUS_READY) { + this.deferCallback(_callback); + } else { + this.callbackQueue.push(_callback); + } +} + +Model.Source.prototype.serialize = function() { + return this.serializer.serialize(this); +} + +Model.Source.prototype.deSerialize = function(_data) { + this.serializer.deSerialize(_data, this); +} + +Model.Source.prototype.getAnnotations = function(_global) { + _global = (typeof _global !== "undefined" && _global); + return this.getList("annotation", _global); +} + +Model.Source.prototype.getMedias = function(_global) { + _global = (typeof _global !== "undefined" && _global); + return this.getList("media", _global); +} + +Model.Source.prototype.getTags = function(_global) { + _global = (typeof _global !== "undefined" && _global); + return this.getList("tag", _global); +} + +Model.Source.prototype.getMashups = function(_global) { + _global = (typeof _global !== "undefined" && _global); + return this.getList("mashup", _global); +} + +Model.Source.prototype.getAnnotationTypes = function(_global) { + _global = (typeof _global !== "undefined" && _global); + return this.getList("annotationType", _global); +} + +Model.Source.prototype.getAnnotationsByTypeTitle = function(_title, _global) { + _global = (typeof _global !== "undefined" && _global); + var _res = new Model.List(this.directory), + _annTypes = this.getAnnotationTypes(_global).searchByTitle(_title); + _annTypes.forEach(function(_annType) { + _res.addElements(_annType.getAnnotations(_global)); + }) + return _res; +} + +Model.Source.prototype.getDuration = function() { + var _m = this.currentMedia; + if (typeof _m !== "undefined") { + return this.currentMedia.duration; + } +} + +Model.Source.prototype.getCurrentMedia = function(_opts) { + if (typeof this.currentMedia === "undefined") { + if (_opts.is_mashup) { + var _mashups = this.getMashups(); + if (_mashups.length) { + this.currentMedia = _mashups[0]; + } + } else { + var _medias = this.getMedias(); + if (_medias.length) { + this.currentMedia = _medias[0]; + } + } + } + return this.currentMedia; +} + +Model.Source.prototype.merge = function(_source) { + var _this = this; + _source.forEach(function(_value, _key) { + _this.getList(_key).addElements(_value); + }); +} + +/* */ + +Model.RemoteSource = function(_config) { + Model.Source.call(this, _config); +} + +Model.RemoteSource.prototype = new Model.Source(); + +Model.RemoteSource.prototype.get = function() { + this.status = Model._SOURCE_STATUS_WAITING; + var _this = this; + this.serializer.loadData(this.url, function(_result) { + _this.deSerialize(_result); + _this.handleCallbacks(); + }); +} + +/* */ + +Model.Directory = function() { + this.remoteSources = {}; + this.elements = {}; +} + +Model.Directory.prototype.remoteSource = function(_properties) { + if (typeof _properties !== "object" || typeof _properties.url === "undefined") { + throw "Error : Model.Directory.remoteSource(configuration): configuration.url is undefined"; + } + var _config = ns._({ directory: this }).extend(_properties); + if (typeof this.remoteSources[_properties.url] === "undefined") { + this.remoteSources[_properties.url] = new Model.RemoteSource(_config); + } + return this.remoteSources[_properties.url]; +} + +Model.Directory.prototype.newLocalSource = function(_properties) { + var _config = ns._({ directory: this }).extend(_properties), + _res = new Model.Source(_config); + return _res; +} + +Model.Directory.prototype.getElement = function(_id) { + return this.elements[_id]; +} + +Model.Directory.prototype.addElement = function(_element) { + this.elements[_element.id] = _element; +} + +Model.Directory.prototype.getGlobalList = function() { + var _res = new Model.List(this); + _res.addIds(ns._(this.elements).keys()); + return _res; +} + +ns.Model = Model; + +})(IriSP);