src/js/model.js
branchnew-model
changeset 856 41c574c807d1
parent 854 29f28a9f236f
child 858 ad1ffe0c0955
equal deleted inserted replaced
854:29f28a9f236f 856:41c574c807d1
     1 /* model.js is where data is stored in a standard form, whatever the serializer */
     1 /* model.js is where data is stored in a standard form, whatever the serializer */
     2 
     2 
     3 IriSP.Cinelab = {
     3 IriSP.Model = {
     4     STATUS_WAITING : 1,
     4     SOURCE_STATUS_EMPTY : 0,
     5     STATUS_READY : 2
     5     SOURCE_STATUS_WAITING : 1,
     6 }
     6     SOURCE_STATUS_READY : 2,
     7 
     7     IDS_AUTO_INCREMENT : 0,
     8 IriSP.Cinelab.Source = function(_directory, _url, _serializer) {
     8     IDS_PREFIX : 'autoid-'
     9     this.status = IriSP.Cinelab.STATUS_EMPTY;
     9 }
       
    10 
       
    11 /* */
       
    12 
       
    13 IriSP.Model.List = function() {
       
    14     this.contents = {};
       
    15 }
       
    16 
       
    17 IriSP.Model.List.prototype.toString = function() {
       
    18     return 'List of Elements, length=' + this.length();
       
    19 }
       
    20 
       
    21 IriSP.Model.List.prototype.keys = function() {
       
    22     return IriSP._(this.contents).keys();
       
    23 }
       
    24 
       
    25 IriSP.Model.List.prototype.length = function() {
       
    26     return this.keys().length;
       
    27 }
       
    28 
       
    29 IriSP.Model.List.prototype.getElement = function(_id) {
       
    30     return this.contents[_id];
       
    31 }
       
    32 
       
    33 IriSP.Model.List.prototype.getFirst = function() {
       
    34     return this.contents(this.keys()[0]);
       
    35 }
       
    36 
       
    37 IriSP.Model.List.prototype.each = function(_callback) {
       
    38     var _this = this;
       
    39     IriSP._(this.contents).each(function(_element, _id) {
       
    40         _callback.call(_this, _element, _id);
       
    41     });
       
    42 }
       
    43 
       
    44 IriSP.Model.List.prototype.map = function(_callback) {
       
    45     var _this = this;
       
    46     return IriSP._(this.contents).map(function(_element, _id) {
       
    47         return _callback.call(_this, _element, _id);
       
    48     });
       
    49 }
       
    50 
       
    51 IriSP.Model.List.prototype.addElement = function(_element) {
       
    52     if ( typeof _element.id === "undefined" ) {
       
    53         IriSP.Model.AUTO_INCREMENT++;
       
    54         _element.id = IriSP.Model.IDS_PREFIX + IriSP.Model.IDS_AUTO_INCREMENT;
       
    55     }
       
    56     this.contents[_element.id] = _element;
       
    57     if ( this.hasParent ) {
       
    58         this.parent.addElement(_element);
       
    59     }
       
    60 }
       
    61 
       
    62 IriSP.Model.List.prototype.addElements = function(_list) {
       
    63     var _this = this;
       
    64     _list.each(function(_element) {
       
    65         _this.addElement(_element);
       
    66     });
       
    67 }
       
    68 /* */
       
    69 
       
    70 IriSP.Model.Time = function(_milliseconds) {
       
    71     this.milliseconds = parseInt(typeof _milliseconds !== "undefined" ? _milliseconds : 0);
       
    72 }
       
    73 
       
    74 IriSP.Model.Time.prototype.setSeconds = function(_seconds) {
       
    75     this.milliseconds = 1000 * _seconds;
       
    76 }
       
    77 
       
    78 IriSP.Model.Time.prototype.getSeconds = function() {
       
    79     return Math.floor(this.milliseconds / 1000);
       
    80 }
       
    81 
       
    82 IriSP.Model.Time.prototype.getHMS = function() {
       
    83     var _totalSeconds = Math.abs(this.getSeconds());
       
    84     return {
       
    85         hours : Math.floor(_totalSeconds / 3600),
       
    86         minutes : (Math.floor(_totalSeconds / 60) % 60),
       
    87         seconds : _totalSeconds % 60
       
    88     } 
       
    89 }
       
    90 
       
    91 IriSP.Model.Time.prototype.toString = function() {
       
    92     function pad(_n) {
       
    93         var _res = _n.toString();
       
    94         while (_res.length < 2) {
       
    95             _res = '0' + _res;
       
    96         }
       
    97         return _res;
       
    98     }
       
    99     var _hms = this.getHMS(),
       
   100         _res = '';
       
   101     if (_hms.hours) {
       
   102         _res += pad(_hms.hours) + ':'
       
   103     }
       
   104     _res += pad(_hms.minutes) + ':' + pad(_hms.seconds);
       
   105     return _res;
       
   106 }
       
   107 
       
   108 IriSP.Model.BrokenReference = function(_elementType, _idRef) {
       
   109     this.id = _idRef;
       
   110     this.elementType = 'brokenReference';
       
   111     this.originalElementType = _elementType;
       
   112     this.isSolved = false;
       
   113 }
       
   114 
       
   115 IriSP.Model.BrokenReference.prototype.toString = function() {
       
   116     return 'Broken reference to ' + IriSP.Model.ELEMENT_TYPES[_elementType].element_str + ', id=' + this.id;
       
   117 }
       
   118 
       
   119 IriSP.Model.BrokenReference.prototype.tryToSolve = function(_container) {
       
   120     if (this.isSolved) {
       
   121         return this.solution;
       
   122     }
       
   123     var _obj = _container.getElement(this.originalElementType, this.id);
       
   124     if (typeof _obj !== "undefined") {
       
   125         this.isSolved = true;
       
   126         this.solution = _obj;
       
   127         return this.solution;
       
   128     } else {
       
   129         return undefined;
       
   130     }
       
   131 }
       
   132 
       
   133 /* */
       
   134 
       
   135 IriSP.Model.Element = function(_id, _source) {
       
   136     this.elementType = 'element';
       
   137     if (typeof _id === "undefined") {
       
   138         IriSP.Model.IDS_AUTO_INCREMENT++;
       
   139         this.id = IriSP.Model.IDS_PREFIX + IriSP.Model.AUTO_INCREMENT;
       
   140     } else {
       
   141         this.id = _id;
       
   142     }
       
   143     this.source = _source;
       
   144     this.title = "";
       
   145     this.description = "";
       
   146 }
       
   147 
       
   148 IriSP.Model.Element.prototype.toString = function() {
       
   149     return this.elementType + ', id=' + this.id + ', title="' + this.title + '"';
       
   150 }
       
   151 
       
   152 IriSP.Model.Element.prototype.getReference = function(_container, _elementType, _idRef) {
       
   153     var _obj = _container.getElement(_elementType, _idRef);
       
   154     if (typeof _obj === "undefined") {
       
   155         _obj = new IriSP.Model.BrokenReference(_elementType, _idRef);
       
   156     }
       
   157     _obj.backReference(this);
       
   158     return _obj;
       
   159 }
       
   160 
       
   161 IriSP.Model.Element.prototype.backReference = function(_object) {
       
   162     if (typeof this.referencedBy === "undefined") {
       
   163         this.referencedBy = {}
       
   164     }
       
   165     if (typeof this.referencedBy[_object.elementType] === "undefined") {
       
   166         this.referencedBy[_object.elementType] = new IriSP.Model.List();
       
   167     }
       
   168     this.referencedBy[_object.elementType].addElement(_object);
       
   169 }
       
   170 
       
   171 IriSP.Model.Element.prototype.otmCrossReference = function(_container, _elementType, _idRef) {
       
   172     if (typeof this.referencing === "undefined") {
       
   173         this.referencing = {};
       
   174     }
       
   175     this.referencing[_elementType] = this.getReference(_container, _elementType, _idRef);
       
   176 }
       
   177 
       
   178 IriSP.Model.Element.prototype.mtmCrossReference = function(_container, _elementType, _idRefList) {
       
   179     if (typeof this.referencing === "undefined") {
       
   180         this.referencing = {};
       
   181     }
       
   182     this.referencing[_elementType] = new IriSP.Model.List;
       
   183     for (var _i = 0; _i < _idRefList.length; _i++) {
       
   184         this.referencing[_elementType].addElement(this.getReference(_container, _elementType, _idRefList[_i]));
       
   185     }
       
   186 }
       
   187 /* */
       
   188 
       
   189 IriSP.Model.Media = function(_id, _source) {
       
   190     IriSP.Model.Element.call(this, _id, _source);
       
   191     this.elementType = 'media';
       
   192     this.duration = new IriSP.Model.Time();
       
   193     this.url = '';
       
   194 }
       
   195 
       
   196 IriSP.Model.Media.prototype = new IriSP.Model.Element(null);
       
   197 
       
   198 IriSP.Model.Media.prototype.setDuration = function(_durationMs) {
       
   199     this.duration.milliseconds = _durationMs;
       
   200 }
       
   201 
       
   202 /* */
       
   203 
       
   204 IriSP.Model.AnnotationType = function(_id, _source) {
       
   205     IriSP.Model.Element.call(this, _id, _source);
       
   206     this.elementType = 'annotationType';
       
   207 }
       
   208 
       
   209 IriSP.Model.AnnotationType.prototype = new IriSP.Model.Element(null);
       
   210 
       
   211 /* Annotation
       
   212  * */
       
   213 
       
   214 IriSP.Model.Annotation = function(_id, _source) {
       
   215     IriSP.Model.Element.call(this, _id, _source);
       
   216     this.elementType = 'annotation';
       
   217     this.begin = new IriSP.Model.Time();
       
   218     this.end = new IriSP.Model.Time();
       
   219 }
       
   220 
       
   221 IriSP.Model.Annotation.prototype = new IriSP.Model.Element(null);
       
   222 
       
   223 IriSP.Model.Annotation.prototype.setBegin = function(_beginMs) {
       
   224     this.begin.milliseconds = _beginMs;
       
   225 }
       
   226 
       
   227 IriSP.Model.Annotation.prototype.setEnd = function(_beginMs) {
       
   228     this.end.milliseconds = _beginMs;
       
   229 }
       
   230 
       
   231 IriSP.Model.Annotation.prototype.setMedia = function(_idRef, _container) {
       
   232     this.otmCrossReference(_container, "media" , _idRef);
       
   233 }
       
   234 
       
   235 IriSP.Model.Annotation.prototype.getMedia = function() {
       
   236     return this.referencing.media;
       
   237 }
       
   238 
       
   239 IriSP.Model.Annotation.prototype.setAnnotationType = function(_idRef, _container) {
       
   240     this.otmCrossReference(_container, "annotationType" , _idRef);
       
   241 }
       
   242 
       
   243 IriSP.Model.Annotation.prototype.getAnnotationType = function() {
       
   244     return this.referencing.annotation_type;
       
   245 }
       
   246 
       
   247 /* A Container contains lists of elements. It corresponds to the root of Cinelab
       
   248  * */
       
   249 
       
   250 IriSP.Model.Container = function(_parent) {
       
   251     this.hasParent = (typeof _parent !== "undefined");
       
   252     if (this.hasParent) {
       
   253         this.parent = _parent;
       
   254     }
       
   255     this.contents = {}
       
   256 }
       
   257 
       
   258 IriSP.Model.Container.prototype.each = function(_callback) {
       
   259     var _this = this;
       
   260     IriSP._(this.contents).each(function(_element, _id) {
       
   261         _callback.call(_this, _element, _id);
       
   262     });
       
   263 }
       
   264 
       
   265 IriSP.Model.Container.prototype.map = function(_callback) {
       
   266     var _this = this;
       
   267     return IriSP._(this.contents).map(function(_element, _id) {
       
   268         return _callback.call(_this, _element, _id);
       
   269     });
       
   270 }
       
   271 
       
   272 IriSP.Model.Container.prototype.addList = function(_listId, _contents) {
       
   273     if (this.hasParent) {
       
   274         this.parent.addList(_listId, _contents);
       
   275     }
       
   276     if (typeof this.contents[_listId] === "undefined") {
       
   277         this.contents[_listId] = _contents;
       
   278     } else {
       
   279         this.contents[_listId].addElements(_contents);
       
   280     }
       
   281 }
       
   282 
       
   283 IriSP.Model.Container.prototype.getList = function(_listId) {
       
   284     if (typeof this.contents[_listId] === "undefined") {
       
   285         if (this.hasParent) {
       
   286             return this.parent.getList(_listId);
       
   287         } else {
       
   288             return undefined;
       
   289         }
       
   290     } else {
       
   291         return this.contents[_listId];
       
   292     }
       
   293 }
       
   294 
       
   295 IriSP.Model.Container.prototype.getElement = function(_listId, _elId) {
       
   296     var _list = this.getList(_listId);
       
   297     return (typeof _list !== "undefined" ? _list.getElement(_elId) : undefined);
       
   298 }
       
   299 
       
   300 IriSP.Model.Container.prototype.getMedias = function(_contents) {
       
   301     return this.getList("media");
       
   302 }
       
   303 
       
   304 IriSP.Model.Container.prototype.getAnnotations = function(_contents) {
       
   305     return this.getList("annotation");
       
   306 }
       
   307 
       
   308 IriSP.Model.Container.prototype.setCurrentMediaById = function(_idRef) {
       
   309     if (typeof _idRef !== "undefined") {
       
   310         this.currentMedia = this.getElement("media", _idRef);
       
   311     }
       
   312 }
       
   313 
       
   314 IriSP.Model.Container.prototype.setDefaultCurrentMedia = function() {
       
   315     if (typeof this.currentMedia === "undefined") {
       
   316         this.currentMedia = this.getMedias().getFirst();
       
   317     }
       
   318 }
       
   319 
       
   320 /* */
       
   321 
       
   322 IriSP.Model.Source = function(_directory, _url, _serializer) {
       
   323     this.status = IriSP.Model.SOURCE_STATUS_EMPTY;
    10     if (typeof _directory === "undefined") {
   324     if (typeof _directory === "undefined") {
    11         throw "Error : Cinelab.Source called with no parent directory";
   325         throw "Error : Model.Source called with no parent directory";
    12     }
   326     }
    13     if (typeof _url === "undefined") {
   327     if (typeof _url === "undefined") {
    14         throw "Error : Cinelab.Source called with no URL";
   328         throw "Error : Model.Source called with no URL";
    15     }
   329     }
    16     if (typeof _serializer === "undefined") {
   330     if (typeof _serializer === "undefined") {
    17         throw "Error : Cinelab.Source called with no serializer";
   331         throw "Error : Model.Source called with no serializer";
    18     }
   332     }
    19     this.directory = _directory;
   333     this.directory = _directory;
    20     this.serializer = _serializer;
   334     this.serializer = _serializer;
    21     this.url = _url;
   335     this.url = _url;
    22     this.callbackQueue = [];
   336     this.callbackQueue = [];
    23     this.contents = null;
   337     this.container = new IriSP.Model.Container(_directory.consolidated);
    24 }
   338     this.get();
    25 
   339 }
    26 IriSP.Cinelab.Source.prototype.get = function() {
   340 
    27     IriSP.jQuery.getJSON(_url, function(_result) {
   341 IriSP.Model.Source.prototype.get = function() {
    28         this.contents = this.serializer.deSerialize(_result);
   342     this.status = IriSP.Model.SOURCE_STATUS_WAITING;
    29         if (this.callbackQueue.length) {
   343     var _this = this;
    30             var _this = this;
   344     IriSP.jQuery.getJSON(this.url, function(_result) {
    31             IriSP._.each(this.callbackQueue, function(_callback) {
   345         _this.serializer.deSerialize(_result, _this.container);
    32                 _callback.call(_this, this.contents);
   346         if (_this.callbackQueue.length) {
       
   347             IriSP._.each(_this.callbackQueue, function(_callback) {
       
   348                 _callback.call(_this);
    33             });
   349             });
    34         }
   350         }
    35         this.callbackQueue = [];
   351         _this.callbackQueue = [];
    36     });
   352         _this.status = IriSP.Model.SOURCE_STATUS_READY;
    37 }
   353     });
    38 
   354 }
    39 IriSP.Cinelab.Source.prototype.addCallback = function(_callback) {
   355 
    40     if (this.status === IriSP.Cinelab.STATUS_READY) {
   356 IriSP.Model.Source.prototype.addCallback = function(_callback) {
    41         callback.call(this, this.contents);
   357     if (this.status === IriSP.Model.SOURCE_STATUS_READY) {
       
   358         callback.call(this);
    42     } else {
   359     } else {
    43         this.callbackQueue.push(_callback);
   360         this.callbackQueue.push(_callback);
    44     }
   361     }
    45 }
   362 }
    46 
   363 
    47 IriSP.Cinelab.Directory = function() {
   364 IriSP.Model.Source.prototype.getAnnotations = function() {
       
   365     return this.container.getAnnotations();
       
   366 }
       
   367 
       
   368 IriSP.Model.Source.prototype.getMedias = function() {
       
   369     return this.container.getMedias();
       
   370 }
       
   371 
       
   372 IriSP.Model.Source.prototype.getCurrentMedia = function() {
       
   373     return this.container.currentMedia;
       
   374 }
       
   375 
       
   376 IriSP.Model.Source.prototype.getDuration = function() {
       
   377     return this.getCurrentMedia().duration;
       
   378 }
       
   379 
       
   380 /* */
       
   381 
       
   382 IriSP.Model.Directory = function() {
    48     this.sources = {};
   383     this.sources = {};
    49     this.consolidated = [];
       
    50     this.imports = {};
   384     this.imports = {};
    51 }
   385     this.consolidated = new IriSP.Model.Container();
    52 
   386 }
    53 IriSP.Cinelab.Directory.prototype.addSource = function(_source, _serializer) {
   387 
    54     this.source[_source] = new IriSP.Cinelab.Source(this, _source, _serializer);
   388 IriSP.Model.Directory.prototype.addSource = function(_source, _serializer) {
    55 }
   389     this.sources[_source] = new IriSP.Model.Source(this, _source, _serializer);
    56 
   390 }
    57 IriSP.Cinelab.Directory.prototype.getSource = function(_source) {
   391 
    58     return (typeof this.sources[_source] !== "undefined" ? this.sources[_source] : false);
   392 IriSP.Model.Directory.prototype.source = function(_source, _serializer) {
    59 }
   393     if (typeof this.sources[_source] === "undefined") {
    60 
       
    61 IriSP.Cinelab.Directory.prototype.source = function(_source, _serializer) {
       
    62     if (typeof this.sources[_source] !== "undefined") {
       
    63         this.addSource(_source, _serializer);
   394         this.addSource(_source, _serializer);
    64     }
   395     }
    65     return this.getSource(_source);
   396     return this.sources[_source];
    66 }
   397 }
       
   398 
       
   399 /* */