src/js/model.js
changeset 970 b1c3bf6eca78
parent 969 353b0881a0b9
child 971 1a9e57b033fa
equal deleted inserted replaced
969:353b0881a0b9 970:b1c3bf6eca78
     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 
     4 
     5 IriSP.Model = {
     5 if (typeof IriSP == "undefined") {
       
     6     IriSP = {};
       
     7 }
       
     8 
       
     9 (function (ns) {
       
    10 
       
    11 var Model = {
     6     _SOURCE_STATUS_EMPTY : 0,
    12     _SOURCE_STATUS_EMPTY : 0,
     7     _SOURCE_STATUS_WAITING : 1,
    13     _SOURCE_STATUS_WAITING : 1,
     8     _SOURCE_STATUS_READY : 2,
    14     _SOURCE_STATUS_READY : 2,
     9     _ID_AUTO_INCREMENT : 0,
    15     _ID_AUTO_INCREMENT : 0,
    10     _ID_BASE : (function(_d) {
    16     _ID_BASE : (function(_d) {
    34             return _text.replace(/([\\\*\+\?\|\{\[\}\]\(\)\^\$\.\#\/])/gm, '\\$1');
    40             return _text.replace(/([\\\*\+\?\|\{\[\}\]\(\)\^\$\.\#\/])/gm, '\\$1');
    35         }
    41         }
    36         var _source = 
    42         var _source = 
    37             typeof _textOrArray === "string"
    43             typeof _textOrArray === "string"
    38             ? escapeText(_textOrArray)
    44             ? escapeText(_textOrArray)
    39             : IriSP._(_textOrArray).map(escapeText).join("|");
    45             : ns._(_textOrArray).map(escapeText).join("|");
    40         if (_testOnly) {
    46         if (_testOnly) {
    41             return new RegExp( _source, 'im');
    47             return new RegExp( _source, 'im');
    42         } else {
    48         } else {
    43             return new RegExp( '(' + _source + ')', 'gim');
    49             return new RegExp( '(' + _source + ')', 'gim');
    44         }
    50         }
    78             + pad(d.getUTCSeconds())+'Z'  
    84             + pad(d.getUTCSeconds())+'Z'  
    79     }
    85     }
    80 }
    86 }
    81 
    87 
    82 /*
    88 /*
    83  * IriSP.Model.List is a class for a list of elements (e.g. annotations, medias, etc. that each have a distinct ID)
    89  * Model.List is a class for a list of elements (e.g. annotations, medias, etc. that each have a distinct ID)
    84  */
    90  */
    85 IriSP.Model.List = function(_directory) {
    91 Model.List = function(_directory) {
    86     Array.call(this);
    92     Array.call(this);
    87     this.directory = _directory;
    93     this.directory = _directory;
    88     this.idIndex = [];
    94     this.idIndex = [];
    89     this.__events = {};
    95     this.__events = {};
    90     if (typeof _directory == "undefined") {
    96     if (typeof _directory == "undefined") {
    91         console.trace();
    97         console.trace();
    92         throw "Error : new IriSP.Model.List(directory): directory is undefined";
    98         throw "Error : new Model.List(directory): directory is undefined";
    93     }
    99     }
    94 }
   100 }
    95 
   101 
    96 IriSP.Model.List.prototype = new Array();
   102 Model.List.prototype = new Array();
    97 
   103 
    98 IriSP.Model.List.prototype.hasId = function(_id) {
   104 Model.List.prototype.hasId = function(_id) {
    99     return IriSP._(this.idIndex).include(_id);
   105     return ns._(this.idIndex).include(_id);
   100 }
   106 }
   101 
   107 
   102 /* On recent browsers, forEach and map are defined and do what we want.
   108 /* On recent browsers, forEach and map are defined and do what we want.
   103  * Otherwise, we'll use the Underscore.js functions
   109  * Otherwise, we'll use the Underscore.js functions
   104  */
   110  */
   105 if (typeof Array.prototype.forEach === "undefined") {
   111 if (typeof Array.prototype.forEach === "undefined") {
   106     IriSP.Model.List.prototype.forEach = function(_callback) {
   112     Model.List.prototype.forEach = function(_callback) {
   107         var _this = this;
   113         var _this = this;
   108         IriSP._(this).forEach(function(_value, _key) {
   114         ns._(this).forEach(function(_value, _key) {
   109             _callback(_value, _key, _this);
   115             _callback(_value, _key, _this);
   110         });
   116         });
   111     }
   117     }
   112 }
   118 }
   113 
   119 
   114 if (typeof Array.prototype.map === "undefined") {
   120 if (typeof Array.prototype.map === "undefined") {
   115     IriSP.Model.List.prototype.map = function(_callback) {
   121     Model.List.prototype.map = function(_callback) {
   116         var _this = this;
   122         var _this = this;
   117         return IriSP._(this).map(function(_value, _key) {
   123         return ns._(this).map(function(_value, _key) {
   118             return _callback(_value, _key, _this);
   124             return _callback(_value, _key, _this);
   119         });
   125         });
   120     }
   126     }
   121 }
   127 }
   122 
   128 
   123 IriSP.Model.List.prototype.pluck = function(_key) {
   129 Model.List.prototype.pluck = function(_key) {
   124     return this.map(function(_value) {
   130     return this.map(function(_value) {
   125         return _value[_key];
   131         return _value[_key];
   126     });
   132     });
   127 }
   133 }
   128 
   134 
   129 /* We override Array's filter function because it doesn't return an IriSP.Model.List
   135 /* We override Array's filter function because it doesn't return an Model.List
   130  */
   136  */
   131 IriSP.Model.List.prototype.filter = function(_callback) {
   137 Model.List.prototype.filter = function(_callback) {
   132     var _this = this,
   138     var _this = this,
   133         _res = new IriSP.Model.List(this.directory);
   139         _res = new Model.List(this.directory);
   134     _res.addElements(IriSP._(this).filter(function(_value, _key) {
   140     _res.addElements(ns._(this).filter(function(_value, _key) {
   135         return _callback(_value, _key, _this);
   141         return _callback(_value, _key, _this);
   136     }));
   142     }));
   137     return _res;
   143     return _res;
   138 }
   144 }
   139 
   145 
   140 IriSP.Model.List.prototype.slice = function(_start, _end) {
   146 Model.List.prototype.slice = function(_start, _end) {
   141     var _res = new IriSP.Model.List(this.directory);
   147     var _res = new Model.List(this.directory);
   142     _res.addElements(Array.prototype.slice.call(this, _start, _end));
   148     _res.addElements(Array.prototype.slice.call(this, _start, _end));
   143     return _res;
   149     return _res;
   144 }
   150 }
   145 
   151 
   146 IriSP.Model.List.prototype.splice = function(_start, _end) {
   152 Model.List.prototype.splice = function(_start, _end) {
   147     var _res = new IriSP.Model.List(this.directory);
   153     var _res = new Model.List(this.directory);
   148     _res.addElements(Array.prototype.splice.call(this, _start, _end));
   154     _res.addElements(Array.prototype.splice.call(this, _start, _end));
   149     this.idIndex.splice(_start, _end);
   155     this.idIndex.splice(_start, _end);
   150     return _res;
   156     return _res;
   151 }
   157 }
   152 
   158 
   153 /* Array has a sort function, but it's not as interesting as Underscore.js's sortBy
   159 /* Array has a sort function, but it's not as interesting as Underscore.js's sortBy
   154  * and won't return a new IriSP.Model.List
   160  * and won't return a new Model.List
   155  */
   161  */
   156 IriSP.Model.List.prototype.sortBy = function(_callback) {
   162 Model.List.prototype.sortBy = function(_callback) {
   157     var _this = this,
   163     var _this = this,
   158         _res = new IriSP.Model.List(this.directory);
   164         _res = new Model.List(this.directory);
   159     _res.addElements(IriSP._(this).sortBy(function(_value, _key) {
   165     _res.addElements(ns._(this).sortBy(function(_value, _key) {
   160         return _callback(_value, _key, _this);
   166         return _callback(_value, _key, _this);
   161     }));
   167     }));
   162     return _res;
   168     return _res;
   163 }
   169 }
   164 
   170 
   165 /* Title and Description are basic information for (almost) all element types,
   171 /* Title and Description are basic information for (almost) all element types,
   166  * here we can search by these criteria
   172  * here we can search by these criteria
   167  */
   173  */
   168 IriSP.Model.List.prototype.searchByTitle = function(_text) {
   174 Model.List.prototype.searchByTitle = function(_text) {
   169     var _rgxp = IriSP.Model.regexpFromTextOrArray(_text, true);
   175     var _rgxp = Model.regexpFromTextOrArray(_text, true);
   170     return this.filter(function(_element) {
   176     return this.filter(function(_element) {
   171         return _rgxp.test(_element.title);
   177         return _rgxp.test(_element.title);
   172     });
   178     });
   173 }
   179 }
   174 
   180 
   175 IriSP.Model.List.prototype.searchByDescription = function(_text) {
   181 Model.List.prototype.searchByDescription = function(_text) {
   176     var _rgxp = IriSP.Model.regexpFromTextOrArray(_text, true);
   182     var _rgxp = Model.regexpFromTextOrArray(_text, true);
   177     return this.filter(function(_element) {
   183     return this.filter(function(_element) {
   178         return _rgxp.test(_element.description);
   184         return _rgxp.test(_element.description);
   179     });
   185     });
   180 }
   186 }
   181 
   187 
   182 IriSP.Model.List.prototype.searchByTextFields = function(_text) {
   188 Model.List.prototype.searchByTextFields = function(_text) {
   183     var _rgxp =  IriSP.Model.regexpFromTextOrArray(_text, true);
   189     var _rgxp =  Model.regexpFromTextOrArray(_text, true);
   184     return this.filter(function(_element) {
   190     return this.filter(function(_element) {
   185         return _rgxp.test(_element.description) || _rgxp.test(_element.title);
   191         return _rgxp.test(_element.description) || _rgxp.test(_element.title);
   186     });
   192     });
   187 }
   193 }
   188 
   194 
   189 IriSP.Model.List.prototype.getTitles = function() {
   195 Model.List.prototype.getTitles = function() {
   190     return this.map(function(_el) {
   196     return this.map(function(_el) {
   191         return _el.title;
   197         return _el.title;
   192     });
   198     });
   193 }
   199 }
   194 
   200 
   195 IriSP.Model.List.prototype.addId = function(_id) {
   201 Model.List.prototype.addId = function(_id) {
   196     var _el = this.directory.getElement(_id)
   202     var _el = this.directory.getElement(_id)
   197     if (!this.hasId(_id) && typeof _el !== "undefined") {
   203     if (!this.hasId(_id) && typeof _el !== "undefined") {
   198         this.idIndex.push(_id);
   204         this.idIndex.push(_id);
   199         Array.prototype.push.call(this, _el);
   205         Array.prototype.push.call(this, _el);
   200     }
   206     }
   201 }
   207 }
   202 
   208 
   203 IriSP.Model.List.prototype.push = function(_el) {
   209 Model.List.prototype.push = function(_el) {
   204     if (typeof _el === "undefined") {
   210     if (typeof _el === "undefined") {
   205         return;
   211         return;
   206     }
   212     }
   207     var _index = (IriSP._(this.idIndex).indexOf(_el.id));
   213     var _index = (ns._(this.idIndex).indexOf(_el.id));
   208     if (_index === -1) {
   214     if (_index === -1) {
   209         this.idIndex.push(_el.id);
   215         this.idIndex.push(_el.id);
   210         Array.prototype.push.call(this, _el);
   216         Array.prototype.push.call(this, _el);
   211     } else {
   217     } else {
   212         this[_index] = _el;
   218         this[_index] = _el;
   213     }
   219     }
   214 }
   220 }
   215 
   221 
   216 IriSP.Model.List.prototype.addIds = function(_array) {
   222 Model.List.prototype.addIds = function(_array) {
   217     var _l = _array.length,
   223     var _l = _array.length,
   218         _this = this;
   224         _this = this;
   219     IriSP._(_array).forEach(function(_id) {
   225     ns._(_array).forEach(function(_id) {
   220         _this.addId(_id);
   226         _this.addId(_id);
   221     });
   227     });
   222 }
   228 }
   223 
   229 
   224 IriSP.Model.List.prototype.addElements = function(_array) {
   230 Model.List.prototype.addElements = function(_array) {
   225     var _this = this;
   231     var _this = this;
   226     IriSP._(_array).forEach(function(_el) {
   232     ns._(_array).forEach(function(_el) {
   227         _this.push(_el);
   233         _this.push(_el);
   228     });
   234     });
   229 }
   235 }
   230 
   236 
   231 IriSP.Model.List.prototype.removeId = function(_id, _deleteFromDirectory) {
   237 Model.List.prototype.removeId = function(_id, _deleteFromDirectory) {
   232     var _deleteFromDirectory = _deleteFromDirectory || false,
   238     var _deleteFromDirectory = _deleteFromDirectory || false,
   233         _index = (IriSP._(this.idIndex).indexOf(_id));
   239         _index = (ns._(this.idIndex).indexOf(_id));
   234     if (_index !== -1) {
   240     if (_index !== -1) {
   235         this.splice(_index,1);
   241         this.splice(_index,1);
   236     }
   242     }
   237     if (_deleteFromDirectory) {
   243     if (_deleteFromDirectory) {
   238         delete this.directory.elements[_id];
   244         delete this.directory.elements[_id];
   239     }
   245     }
   240 }
   246 }
   241 
   247 
   242 IriSP.Model.List.prototype.removeElement = function(_el, _deleteFromDirectory) {
   248 Model.List.prototype.removeElement = function(_el, _deleteFromDirectory) {
   243     var _deleteFromDirectory = _deleteFromDirectory || false;
   249     var _deleteFromDirectory = _deleteFromDirectory || false;
   244     this.removeId(_el.id);
   250     this.removeId(_el.id);
   245 }
   251 }
   246 
   252 
   247 IriSP.Model.List.prototype.removeIds = function(_list, _deleteFromDirectory) {
   253 Model.List.prototype.removeIds = function(_list, _deleteFromDirectory) {
   248     var _deleteFromDirectory = _deleteFromDirectory || false,
   254     var _deleteFromDirectory = _deleteFromDirectory || false,
   249         _this = this;
   255         _this = this;
   250     IriSP._(_list).forEach(function(_id) {
   256     ns._(_list).forEach(function(_id) {
   251         _this.removeId(_id);
   257         _this.removeId(_id);
   252     });
   258     });
   253 }
   259 }
   254 
   260 
   255 IriSP.Model.List.prototype.removeElements = function(_list, _deleteFromDirectory) {
   261 Model.List.prototype.removeElements = function(_list, _deleteFromDirectory) {
   256     var _deleteFromDirectory = _deleteFromDirectory || false,
   262     var _deleteFromDirectory = _deleteFromDirectory || false,
   257         _this = this;
   263         _this = this;
   258     IriSP._(_list).forEach(function(_el) {
   264     ns._(_list).forEach(function(_el) {
   259         _this.removeElement(_el);
   265         _this.removeElement(_el);
   260     });
   266     });
   261 }
   267 }
   262 
   268 
   263 IriSP.Model.List.prototype.on = function(_event, _callback) {
   269 Model.List.prototype.on = function(_event, _callback) {
   264     if (typeof this.__events[_event] === "undefined") {
   270     if (typeof this.__events[_event] === "undefined") {
   265         this.__events[_event] = [];
   271         this.__events[_event] = [];
   266     }
   272     }
   267     this.__events[_event].push(_callback);
   273     this.__events[_event].push(_callback);
   268 }
   274 }
   269 
   275 
   270 IriSP.Model.List.prototype.off = function(_event, _callback) {
   276 Model.List.prototype.off = function(_event, _callback) {
   271     if (typeof this.__events[_event] !== "undefined") {
   277     if (typeof this.__events[_event] !== "undefined") {
   272         this.__events[_event] = IriSP._(this.__events[_event]).reject(function(_fn) {
   278         this.__events[_event] = ns._(this.__events[_event]).reject(function(_fn) {
   273             return _fn === _callback;
   279             return _fn === _callback;
   274         });
   280         });
   275     }
   281     }
   276 }
   282 }
   277 
   283 
   278 IriSP.Model.List.prototype.trigger = function(_event, _data) {
   284 Model.List.prototype.trigger = function(_event, _data) {
   279     var _list = this;
   285     var _list = this;
   280     IriSP._(this.__events[_event]).each(function(_callback) {
   286     ns._(this.__events[_event]).each(function(_callback) {
   281         _callback.call(_list, _data);
   287         _callback.call(_list, _data);
   282     });
   288     });
   283 }
   289 }
   284 
   290 
   285 /* A simple time management object, that helps converting millisecs to seconds and strings,
   291 /* A simple time management object, that helps converting millisecs to seconds and strings,
   286  * without the clumsiness of the original Date object.
   292  * without the clumsiness of the original Date object.
   287  */
   293  */
   288 
   294 
   289 IriSP.Model.Time = function(_milliseconds) {
   295 Model.Time = function(_milliseconds) {
   290     this.milliseconds = 0;
   296     this.milliseconds = 0;
   291     this.setMilliseconds(_milliseconds);
   297     this.setMilliseconds(_milliseconds);
   292 }
   298 }
   293 
   299 
   294 IriSP.Model.Time.prototype.setMilliseconds = function(_milliseconds) {
   300 Model.Time.prototype.setMilliseconds = function(_milliseconds) {
   295     var _ante = _milliseconds;
   301     var _ante = _milliseconds;
   296     switch(typeof _milliseconds) {
   302     switch(typeof _milliseconds) {
   297         case "string":
   303         case "string":
   298             this.milliseconds = parseFloat(_milliseconds);
   304             this.milliseconds = parseFloat(_milliseconds);
   299             break;
   305             break;
   309     if (this.milliseconds === NaN) {
   315     if (this.milliseconds === NaN) {
   310         this.milliseconds = _ante;
   316         this.milliseconds = _ante;
   311     }
   317     }
   312 }
   318 }
   313 
   319 
   314 IriSP.Model.Time.prototype.setSeconds = function(_seconds) {
   320 Model.Time.prototype.setSeconds = function(_seconds) {
   315     this.milliseconds = 1000 * _seconds;
   321     this.milliseconds = 1000 * _seconds;
   316 }
   322 }
   317 
   323 
   318 IriSP.Model.Time.prototype.getSeconds = function() {
   324 Model.Time.prototype.getSeconds = function() {
   319     return this.milliseconds / 1000;
   325     return this.milliseconds / 1000;
   320 }
   326 }
   321 
   327 
   322 IriSP.Model.Time.prototype.getHMS = function() {
   328 Model.Time.prototype.getHMS = function() {
   323     var _totalSeconds = Math.abs(Math.floor(this.getSeconds()));
   329     var _totalSeconds = Math.abs(Math.floor(this.getSeconds()));
   324     return {
   330     return {
   325         hours : Math.floor(_totalSeconds / 3600),
   331         hours : Math.floor(_totalSeconds / 3600),
   326         minutes : (Math.floor(_totalSeconds / 60) % 60),
   332         minutes : (Math.floor(_totalSeconds / 60) % 60),
   327         seconds : _totalSeconds % 60
   333         seconds : _totalSeconds % 60
   328     } 
   334     } 
   329 }
   335 }
   330 
   336 
   331 IriSP.Model.Time.prototype.add = function(_milliseconds) {
   337 Model.Time.prototype.add = function(_milliseconds) {
   332     this.milliseconds += new IriSP.Model.Time(_milliseconds).milliseconds;
   338     this.milliseconds += new Model.Time(_milliseconds).milliseconds;
   333 }
   339 }
   334 
   340 
   335 IriSP.Model.Time.prototype.valueOf = function() {
   341 Model.Time.prototype.valueOf = function() {
   336     return this.milliseconds;
   342     return this.milliseconds;
   337 }
   343 }
   338 
   344 
   339 IriSP.Model.Time.prototype.toString = function() {
   345 Model.Time.prototype.toString = function() {
   340     function pad(_n) {
   346     function pad(_n) {
   341         var _res = _n.toString();
   347         var _res = _n.toString();
   342         while (_res.length < 2) {
   348         while (_res.length < 2) {
   343             _res = '0' + _res;
   349             _res = '0' + _res;
   344         }
   350         }
   351     }
   357     }
   352     _res += pad(_hms.minutes) + ':' + pad(_hms.seconds);
   358     _res += pad(_hms.minutes) + ':' + pad(_hms.seconds);
   353     return _res;
   359     return _res;
   354 }
   360 }
   355 
   361 
   356 /* IriSP.Model.Reference handles references between elements
   362 /* Model.Reference handles references between elements
   357  */
   363  */
   358 
   364 
   359 IriSP.Model.Reference = function(_source, _idRef) {
   365 Model.Reference = function(_source, _idRef) {
   360     this.source = _source;
   366     this.source = _source;
   361     this.id = _idRef;
   367     this.id = _idRef;
   362     if (typeof _idRef === "object") {
   368     if (typeof _idRef === "object") {
   363         this.isList = true;
   369         this.isList = true;
   364     } else {
   370     } else {
   365         this.isList = false;
   371         this.isList = false;
   366     }
   372     }
   367     this.refresh();
   373     this.refresh();
   368 }
   374 }
   369 
   375 
   370 IriSP.Model.Reference.prototype.refresh = function() {
   376 Model.Reference.prototype.refresh = function() {
   371     if (this.isList) {
   377     if (this.isList) {
   372         this.contents = new IriSP.Model.List(this.source.directory);
   378         this.contents = new Model.List(this.source.directory);
   373         this.contents.addIds(this.id);
   379         this.contents.addIds(this.id);
   374     } else {
   380     } else {
   375         this.contents = this.source.getElement(this.id);
   381         this.contents = this.source.getElement(this.id);
   376     }
   382     }
   377     
   383     
   378 }
   384 }
   379 
   385 
   380 IriSP.Model.Reference.prototype.getContents = function() {
   386 Model.Reference.prototype.getContents = function() {
   381     if (typeof this.contents === "undefined" || (this.isList && this.contents.length != this.id.length)) {
   387     if (typeof this.contents === "undefined" || (this.isList && this.contents.length != this.id.length)) {
   382         this.refresh();
   388         this.refresh();
   383     }
   389     }
   384     return this.contents;
   390     return this.contents;
   385 }
   391 }
   386 
   392 
   387 IriSP.Model.Reference.prototype.isOrHasId = function(_idRef) {
   393 Model.Reference.prototype.isOrHasId = function(_idRef) {
   388     if (this.isList) {
   394     if (this.isList) {
   389         return (IriSP._(this.id).indexOf(_idRef) !== -1)
   395         return (ns._(this.id).indexOf(_idRef) !== -1)
   390     } else {
   396     } else {
   391         return (this.id == _idRef);
   397         return (this.id == _idRef);
   392     }
   398     }
   393 }
   399 }
   394 
   400 
   395 /* */
   401 /* */
   396 
   402 
   397 IriSP.Model.Element = function(_id, _source) {
   403 Model.Element = function(_id, _source) {
   398     this.elementType = 'element';
   404     this.elementType = 'element';
   399     if (typeof _source === "undefined") {
   405     if (typeof _source === "undefined") {
   400         return;
   406         return;
   401     }
   407     }
   402     if (typeof _id === "undefined" || !_id) {
   408     if (typeof _id === "undefined" || !_id) {
   403         _id = IriSP.Model.getUID();
   409         _id = Model.getUID();
   404     }
   410     }
   405     this.source = _source;
   411     this.source = _source;
   406     this.id = _id;
   412     this.id = _id;
   407     this.title = "";
   413     this.title = "";
   408     this.description = "";
   414     this.description = "";
   409     this.__events = {}
   415     this.__events = {}
   410     this.source.directory.addElement(this);
   416     this.source.directory.addElement(this);
   411 }
   417 }
   412 
   418 
   413 IriSP.Model.Element.prototype.toString = function() {
   419 Model.Element.prototype.toString = function() {
   414     return this.elementType + (this.elementType !== 'element' ? ', id=' + this.id + ', title="' + this.title + '"' : '');
   420     return this.elementType + (this.elementType !== 'element' ? ', id=' + this.id + ', title="' + this.title + '"' : '');
   415 }
   421 }
   416 
   422 
   417 IriSP.Model.Element.prototype.setReference = function(_elementType, _idRef) {
   423 Model.Element.prototype.setReference = function(_elementType, _idRef) {
   418     this[_elementType] = new IriSP.Model.Reference(this.source, _idRef);
   424     this[_elementType] = new Model.Reference(this.source, _idRef);
   419 }
   425 }
   420 
   426 
   421 IriSP.Model.Element.prototype.getReference = function(_elementType) {
   427 Model.Element.prototype.getReference = function(_elementType) {
   422     if (typeof this[_elementType] !== "undefined") {
   428     if (typeof this[_elementType] !== "undefined") {
   423         return this[_elementType].getContents();
   429         return this[_elementType].getContents();
   424     }
   430     }
   425 }
   431 }
   426 
   432 
   427 IriSP.Model.Element.prototype.getRelated = function(_elementType, _global) {
   433 Model.Element.prototype.getRelated = function(_elementType, _global) {
   428     _global = (typeof _global !== "undefined" && _global);
   434     _global = (typeof _global !== "undefined" && _global);
   429     var _this = this;
   435     var _this = this;
   430     return this.source.getList(_elementType, _global).filter(function(_el) {
   436     return this.source.getList(_elementType, _global).filter(function(_el) {
   431         var _ref = _el[_this.elementType];
   437         var _ref = _el[_this.elementType];
   432         return _ref && _ref.isOrHasId(_this.id);
   438         return _ref && _ref.isOrHasId(_this.id);
   433     });
   439     });
   434 }
   440 }
   435 
   441 
   436 IriSP.Model.Element.prototype.on = function(_event, _callback) {
   442 Model.Element.prototype.on = function(_event, _callback) {
   437     if (typeof this.__events[_event] === "undefined") {
   443     if (typeof this.__events[_event] === "undefined") {
   438         this.__events[_event] = [];
   444         this.__events[_event] = [];
   439     }
   445     }
   440     this.__events[_event].push(_callback);
   446     this.__events[_event].push(_callback);
   441 }
   447 }
   442 
   448 
   443 IriSP.Model.Element.prototype.off = function(_event, _callback) {
   449 Model.Element.prototype.off = function(_event, _callback) {
   444     if (typeof this.__events[_event] !== "undefined") {
   450     if (typeof this.__events[_event] !== "undefined") {
   445         this.__events[_event] = IriSP._(this.__events[_event]).reject(function(_fn) {
   451         this.__events[_event] = ns._(this.__events[_event]).reject(function(_fn) {
   446             return _fn === _callback;
   452             return _fn === _callback;
   447         });
   453         });
   448     }
   454     }
   449 }
   455 }
   450 
   456 
   451 IriSP.Model.Element.prototype.trigger = function(_event, _data) {
   457 Model.Element.prototype.trigger = function(_event, _data) {
   452     var _element = this;
   458     var _element = this;
   453     IriSP._(this.__events[_event]).each(function(_callback) {
   459     ns._(this.__events[_event]).each(function(_callback) {
   454         _callback.call(_element, _data);
   460         _callback.call(_element, _data);
   455     });
   461     });
   456 }
   462 }
   457 
   463 
   458 /* */
   464 /* */
   459 
   465 
   460 IriSP.Model.Media = function(_id, _source) {
   466 Model.Playable = function(_id, _source) {
   461     IriSP.Model.Element.call(this, _id, _source);
   467     Model.Element.call(this, _id, _source);
       
   468     if (typeof _source === "undefined") {
       
   469         return;
       
   470     }
       
   471     this.elementType = 'playable';
       
   472     this.currentTime = new Model.Time();
       
   473     this.volume = .5;
       
   474     this.paused = true;
       
   475     this.muted = false;
       
   476     var _this = this;
       
   477     this.on("play", function() {
       
   478         _this.paused = false;
       
   479     });
       
   480     this.on("pause", function() {
       
   481         _this.paused = true;
       
   482     });
       
   483     this.on("timeupdate", function(_time) {
       
   484         _this.currentTime = _time;
       
   485     });
       
   486 }
       
   487 
       
   488 Model.Playable.prototype = new Model.Element();
       
   489 
       
   490 Model.Playable.prototype.getCurrentTime = function() { 
       
   491     return this.currentTime;
       
   492 }
       
   493 
       
   494 Model.Playable.prototype.getVolume = function() {
       
   495     return this.volume;
       
   496 }
       
   497 
       
   498 Model.Playable.prototype.getPaused = function() {
       
   499     return this.paused;
       
   500 }
       
   501 
       
   502 Model.Playable.prototype.getMuted = function() {
       
   503     return this.muted;
       
   504 }
       
   505 
       
   506 Model.Playable.prototype.setCurrentTime = function(_time) {
       
   507     this.trigger("setcurrenttime",_time);
       
   508 }
       
   509 
       
   510 Model.Playable.prototype.setVolume = function(_vol) {
       
   511     this.trigger("setvolume",_vol);
       
   512 }
       
   513 
       
   514 Model.Playable.prototype.setMuted = function(_muted) {
       
   515     this.trigger("setmuted",_muted);
       
   516 }
       
   517 
       
   518 Model.Playable.prototype.play = function() {
       
   519     this.trigger("setplay");
       
   520 }
       
   521 
       
   522 Model.Playable.prototype.pause = function() {
       
   523     this.trigger("setpause");
       
   524 }
       
   525 
       
   526 
       
   527 /* */
       
   528 
       
   529 Model.Media = function(_id, _source) {
       
   530     Model.Playable.call(this, _id, _source);
   462     this.elementType = 'media';
   531     this.elementType = 'media';
   463     this.duration = new IriSP.Model.Time();
   532     this.duration = new Model.Time();
   464     this.video = '';
   533     this.video = '';
       
   534     
   465     var _this = this;
   535     var _this = this;
   466     this.on("timeupdate", function(_time) {
   536     this.on("timeupdate", function(_time) {
   467         _this.getAnnotations().filter(function(_a) {
   537         _this.getAnnotations().filter(function(_a) {
   468             return (_a.end <= _time || _a.begin > _time) && _a.playing
   538             return (_a.end <= _time || _a.begin > _time) && _a.playing
   469         }).forEach(function(_a) {
   539         }).forEach(function(_a) {
   477             _a.trigger("enter");
   547             _a.trigger("enter");
   478         });
   548         });
   479     });
   549     });
   480 }
   550 }
   481 
   551 
   482 IriSP.Model.Media.prototype = new IriSP.Model.Element();
   552 Model.Media.prototype = new Model.Playable();
   483 
   553 
   484 /* Default functions to be overriden by players */
   554 /* Default functions to be overriden by players */
   485 
       
   486 IriSP.Model.Media.prototype.getCurrentTime = function() {  return new IriSP.Model.Time(0); }
       
   487 
       
   488 IriSP.Model.Media.prototype.getVolume = function() { return .5; }
       
   489 
       
   490 IriSP.Model.Media.prototype.getPaused = function() { return true; }
       
   491 
       
   492 IriSP.Model.Media.prototype.getMuted = function() { return false; }
       
   493 
       
   494 IriSP.Model.Media.prototype.setCurrentTime
       
   495     = IriSP.Model.Media.prototype.setVolume
       
   496     = IriSP.Model.Media.prototype.setMuted
       
   497     = IriSP.Model.Media.prototype.play
       
   498     = IriSP.Model.Media.prototype.pause
       
   499     = function() {}
       
   500     
   555     
   501 IriSP.Model.Media.prototype.setDuration = function(_durationMs) {
   556 Model.Media.prototype.setDuration = function(_durationMs) {
   502     this.duration.setMilliseconds(_durationMs);
   557     this.duration.setMilliseconds(_durationMs);
   503 }
   558 }
   504 
   559 
   505 IriSP.Model.Media.prototype.getAnnotations = function() {
   560 Model.Media.prototype.getAnnotations = function() {
   506     return this.getRelated("annotation");
   561     return this.getRelated("annotation");
   507 }
   562 }
   508 
   563 
   509 IriSP.Model.Media.prototype.getAnnotationsByTypeTitle = function(_title) {
   564 Model.Media.prototype.getAnnotationsByTypeTitle = function(_title) {
   510     var _annTypes = this.source.getAnnotationTypes().searchByTitle(_title).pluck("id");
   565     var _annTypes = this.source.getAnnotationTypes().searchByTitle(_title).pluck("id");
   511     if (_annTypes.length) {
   566     if (_annTypes.length) {
   512         return this.getAnnotations().filter(function(_annotation) {
   567         return this.getAnnotations().filter(function(_annotation) {
   513             return IriSP._(_annTypes).indexOf(_annotation.getAnnotationType().id) !== -1;
   568             return ns._(_annTypes).indexOf(_annotation.getAnnotationType().id) !== -1;
   514         });
   569         });
   515     } else {
   570     } else {
   516         return new IriSP.Model.List(this.source.directory)
   571         return new Model.List(this.source.directory)
   517     }
   572     }
   518 }
   573 }
   519 
   574 
   520 /* */
   575 /* */
   521 
   576 
   522 IriSP.Model.Tag = function(_id, _source) {
   577 Model.Tag = function(_id, _source) {
   523     IriSP.Model.Element.call(this, _id, _source);
   578     Model.Element.call(this, _id, _source);
   524     this.elementType = 'tag';
   579     this.elementType = 'tag';
   525 }
   580 }
   526 
   581 
   527 IriSP.Model.Tag.prototype = new IriSP.Model.Element();
   582 Model.Tag.prototype = new Model.Element();
   528 
   583 
   529 IriSP.Model.Tag.prototype.getAnnotations = function() {
   584 Model.Tag.prototype.getAnnotations = function() {
   530     return this.getRelated("annotation");
   585     return this.getRelated("annotation");
   531 }
   586 }
   532 
   587 
   533 /* */
   588 /* */
   534 
   589 Model.AnnotationType = function(_id, _source) {
   535 IriSP.Model.AnnotationType = function(_id, _source) {
   590     Model.Element.call(this, _id, _source);
   536     IriSP.Model.Element.call(this, _id, _source);
       
   537     this.elementType = 'annotationType';
   591     this.elementType = 'annotationType';
   538 }
   592 }
   539 
   593 
   540 IriSP.Model.AnnotationType.prototype = new IriSP.Model.Element();
   594 Model.AnnotationType.prototype = new Model.Element();
   541 
   595 
   542 IriSP.Model.AnnotationType.prototype.getAnnotations = function() {
   596 Model.AnnotationType.prototype.getAnnotations = function() {
   543     return this.getRelated("annotation");
   597     return this.getRelated("annotation");
   544 }
   598 }
   545 
   599 
   546 /* Annotation
   600 /* Annotation
   547  * */
   601  * */
   548 
   602 
   549 IriSP.Model.Annotation = function(_id, _source) {
   603 Model.Annotation = function(_id, _source) {
   550     IriSP.Model.Element.call(this, _id, _source);
   604     Model.Element.call(this, _id, _source);
   551     this.elementType = 'annotation';
   605     this.elementType = 'annotation';
   552     this.begin = new IriSP.Model.Time();
   606     this.begin = new Model.Time();
   553     this.end = new IriSP.Model.Time();
   607     this.end = new Model.Time();
   554     this.tag = new IriSP.Model.Reference(_source, []);
   608     this.tag = new Model.Reference(_source, []);
   555     this.playing = false;
   609     this.playing = false;
   556     var _this = this;
   610     var _this = this;
   557     this.on("click", function() {
   611     this.on("click", function() {
   558         _this.getMedia().setCurrentTime(_this.begin);
   612         _this.getMedia().setCurrentTime(_this.begin);
   559     });
   613     });
   560 }
   614 }
   561 
   615 
   562 IriSP.Model.Annotation.prototype = new IriSP.Model.Element(null);
   616 Model.Annotation.prototype = new Model.Element();
   563 
   617 
   564 IriSP.Model.Annotation.prototype.setBegin = function(_beginMs) {
   618 Model.Annotation.prototype.setBegin = function(_beginMs) {
   565     this.begin.setMilliseconds(_beginMs);
   619     this.begin.setMilliseconds(_beginMs);
   566 }
   620 }
   567 
   621 
   568 IriSP.Model.Annotation.prototype.setEnd = function(_beginMs) {
   622 Model.Annotation.prototype.setEnd = function(_beginMs) {
   569     this.end.setMilliseconds(_beginMs);
   623     this.end.setMilliseconds(_beginMs);
   570 }
   624 }
   571 
   625 
   572 IriSP.Model.Annotation.prototype.setMedia = function(_idRef) {
   626 Model.Annotation.prototype.setMedia = function(_idRef) {
   573     this.setReference("media", _idRef);
   627     this.setReference("media", _idRef);
   574 }
   628 }
   575 
   629 
   576 IriSP.Model.Annotation.prototype.getMedia = function() {
   630 Model.Annotation.prototype.getMedia = function() {
   577     return this.getReference("media");
   631     return this.getReference("media");
   578 }
   632 }
   579 
   633 
   580 IriSP.Model.Annotation.prototype.setAnnotationType = function(_idRef) {
   634 Model.Annotation.prototype.setAnnotationType = function(_idRef) {
   581     this.setReference("annotationType", _idRef);
   635     this.setReference("annotationType", _idRef);
   582 }
   636 }
   583 
   637 
   584 IriSP.Model.Annotation.prototype.getAnnotationType = function() {
   638 Model.Annotation.prototype.getAnnotationType = function() {
   585     return this.getReference("annotationType");
   639     return this.getReference("annotationType");
   586 }
   640 }
   587 
   641 
   588 IriSP.Model.Annotation.prototype.setTags = function(_idRefs) {
   642 Model.Annotation.prototype.setTags = function(_idRefs) {
   589     this.setReference("tag", _idRefs);
   643     this.setReference("tag", _idRefs);
   590 }
   644 }
   591 
   645 
   592 IriSP.Model.Annotation.prototype.getTags = function() {
   646 Model.Annotation.prototype.getTags = function() {
   593     return this.getReference("tag");
   647     return this.getReference("tag");
   594 }
   648 }
   595 
   649 
   596 IriSP.Model.Annotation.prototype.getTagTexts = function() {
   650 Model.Annotation.prototype.getTagTexts = function() {
   597     return this.getTags().getTitles();
   651     return this.getTags().getTitles();
   598 }
   652 }
   599 
   653 
   600 IriSP.Model.Annotation.prototype.getDuration = function() {
   654 Model.Annotation.prototype.getDuration = function() {
   601     return new IriSP.Model.Time(this.end.milliseconds - this.begin.milliseconds)
   655     return new Model.Time(this.end.milliseconds - this.begin.milliseconds)
   602 }
   656 }
   603 
   657 
   604 /* */
   658 /* */
   605 
   659 
   606 IriSP.Model.MashedAnnotation = function(_mashup, _annotation) {
   660 Model.MashedAnnotation = function(_mashup, _annotation) {
   607     IriSP.Model.Element.call(this, _mashup.id + "_" + _annotation.id, _annotation.source);
   661     Model.Element.call(this, _mashup.id + "_" + _annotation.id, _annotation.source);
   608     this.elementType = 'mashedAnnotation';
   662     this.elementType = 'mashedAnnotation';
   609     this.annotation = _annotation;
   663     this.annotation = _annotation;
   610     this.begin = new IriSP.Model.Time(_mashup.duration);
   664     this.begin = new Model.Time(_mashup.duration);
   611     this.end = new IriSP.Model.Time(_mashup.duration + _annotation.getDuration());
   665     this.end = new Model.Time(_mashup.duration + _annotation.getDuration());
   612     this.title = this.annotation.title;
   666     this.title = this.annotation.title;
   613     this.description = this.annotation.description;
   667     this.description = this.annotation.description;
   614     this.color = this.annotation.color;
   668     this.color = this.annotation.color;
   615     var _this = this;
   669     var _this = this;
   616     this.on("click", function() {
   670     this.on("click", function() {
   617         _mashup.setCurrentTime(_this.begin);
   671         _mashup.setCurrentTime(_this.begin);
   618     });
   672     });
   619 }
   673 }
   620 
   674 
   621 IriSP.Model.MashedAnnotation.prototype = new IriSP.Model.Element(null);
   675 Model.MashedAnnotation.prototype = new Model.Element(null);
   622 
   676 
   623 IriSP.Model.MashedAnnotation.prototype.getMedia = function() {
   677 Model.MashedAnnotation.prototype.getMedia = function() {
   624     return this.annotation.getReference("media");
   678     return this.annotation.getReference("media");
   625 }
   679 }
   626 
   680 
   627 IriSP.Model.MashedAnnotation.prototype.getAnnotationType = function() {
   681 Model.MashedAnnotation.prototype.getAnnotationType = function() {
   628     return this.annotation.getReference("annotationType");
   682     return this.annotation.getReference("annotationType");
   629 }
   683 }
   630 
   684 
   631 IriSP.Model.MashedAnnotation.prototype.getTags = function() {
   685 Model.MashedAnnotation.prototype.getTags = function() {
   632     return this.annotation.getReference("tag");
   686     return this.annotation.getReference("tag");
   633 }
   687 }
   634 
   688 
   635 IriSP.Model.MashedAnnotation.prototype.getTagTexts = function() {
   689 Model.MashedAnnotation.prototype.getTagTexts = function() {
   636     return this.annotation.getTags().getTitles();
   690     return this.annotation.getTags().getTitles();
   637 }
   691 }
   638 
   692 
   639 IriSP.Model.MashedAnnotation.prototype.getDuration = function() {
   693 Model.MashedAnnotation.prototype.getDuration = function() {
   640     return this.annotation.getDuration();
   694     return this.annotation.getDuration();
   641 }
   695 }
   642 
   696 
   643 /* */
   697 /* */
   644 
   698 
   645 IriSP.Model.Mashup = function(_id, _source) {
   699 Model.Mashup = function(_id, _source) {
   646     IriSP.Model.Element.call(this, _id, _source);
   700     Model.Playable.call(this, _id, _source);
   647     this.elementType = 'mashup';
   701     this.elementType = 'mashup';
   648     this.duration = new IriSP.Model.Time();
   702     this.duration = new Model.Time();
   649     this.segments = new IriSP.Model.List(_source.directory);
   703     this.segments = new Model.List(_source.directory);
   650     this.medias = new IriSP.Model.List(_source.directory);
   704     this.medias = new Model.List(_source.directory);
   651     var _currentMedia = null;
   705     var _currentMedia = null;
   652     var _this = this;
   706     var _this = this;
   653     this.on("timeupdate", function(_time) {
   707     this.on("timeupdate", function(_time) {
   654         _this.getAnnotations().filter(function(_a) {
   708         _this.getAnnotations().filter(function(_a) {
   655             return (_a.end <= _time || _a.begin > _time) && _a.playing
   709             return (_a.end <= _time || _a.begin > _time) && _a.playing
   672             }
   726             }
   673         });
   727         });
   674     });
   728     });
   675 }
   729 }
   676 
   730 
   677 IriSP.Model.Mashup.prototype = new IriSP.Model.Element();
   731 Model.Mashup.prototype = new Model.Playable();
   678 
   732 
   679 IriSP.Model.Mashup.prototype.addSegment = function(_annotation) {
   733 Model.Mashup.prototype.addSegment = function(_annotation) {
   680     var _mashedAnnotation = new IriSP.Model.MashedAnnotation(this, _annotation);
   734     var _mashedAnnotation = new Model.MashedAnnotation(this, _annotation);
   681     this.duration.setMilliseconds(_mashedAnnotation.end);
   735     this.duration.setMilliseconds(_mashedAnnotation.end);
   682     this.segments.push(_mashedAnnotation);
   736     this.segments.push(_mashedAnnotation);
   683     this.medias.push(_annotation.getMedia());
   737     this.medias.push(_annotation.getMedia());
   684 }
   738 }
   685 
   739 
   686 IriSP.Model.Mashup.prototype.addSegmentById = function(_elId) {
   740 Model.Mashup.prototype.addSegmentById = function(_elId) {
   687     var _annotation = this.source.getElement(_elId);
   741     var _annotation = this.source.getElement(_elId);
   688     if (typeof _annotation !== "undefined") {
   742     if (typeof _annotation !== "undefined") {
   689         this.addSegment(_annotation);
   743         this.addSegment(_annotation);
   690     }
   744     }
   691 }
   745 }
   692 
   746 
   693 IriSP.Model.Mashup.prototype.getAnnotations = function() {
   747 Model.Mashup.prototype.getAnnotations = function() {
   694     return this.segments;
   748     return this.segments;
   695 }
   749 }
   696 
   750 
   697 IriSP.Model.Mashup.prototype.getMedias = function() {
   751 Model.Mashup.prototype.getMedias = function() {
   698     return this.medias;
   752     return this.medias;
   699 }
   753 }
   700 
   754 
   701 IriSP.Model.Mashup.prototype.getAnnotationsByTypeTitle = function(_title) {
   755 Model.Mashup.prototype.getAnnotationsByTypeTitle = function(_title) {
   702     var _annTypes = this.source.getAnnotationTypes().searchByTitle(_title).pluck("id");
   756     var _annTypes = this.source.getAnnotationTypes().searchByTitle(_title).pluck("id");
   703     if (_annTypes.length) {
   757     if (_annTypes.length) {
   704         return this.getAnnotations().filter(function(_annotation) {
   758         return this.getAnnotations().filter(function(_annotation) {
   705             return IriSP._(_annTypes).indexOf(_annotation.getAnnotationType().id) !== -1;
   759             return ns._(_annTypes).indexOf(_annotation.getAnnotationType().id) !== -1;
   706         });
   760         });
   707     } else {
   761     } else {
   708         return new IriSP.Model.List(this.source.directory)
   762         return new Model.List(this.source.directory)
   709     }
   763     }
   710 }
   764 }
   711 
   765 
   712 IriSP.Model.Mashup.prototype.getAnnotationAtTime = function(_time) {
   766 Model.Mashup.prototype.getAnnotationAtTime = function(_time) {
   713     var _list = this.segments.filter(function(_annotation) {
   767     var _list = this.segments.filter(function(_annotation) {
   714         return _annotation.begin <= _time && _annotation.end > _time;
   768         return _annotation.begin <= _time && _annotation.end > _time;
   715     });
   769     });
   716     if (_list.length) {
   770     if (_list.length) {
   717         return _list[0];
   771         return _list[0];
   718     } else {
   772     } else {
   719         return undefined;
   773         return undefined;
   720     }
   774     }
   721 }
   775 }
   722 
   776 
   723 IriSP.Model.Mashup.prototype.getMediaAtTime = function(_time) {
   777 Model.Mashup.prototype.getMediaAtTime = function(_time) {
   724     var _annotation = this.getAnnotationAtTime(_time);
   778     var _annotation = this.getAnnotationAtTime(_time);
   725     if (typeof _annotation !== "undefined") {
   779     if (typeof _annotation !== "undefined") {
   726         return _annotation.getMedia();
   780         return _annotation.getMedia();
   727     } else {
   781     } else {
   728         return undefined;
   782         return undefined;
   729     }
   783     }
   730 }
   784 }
   731 
   785 
   732 /* Default functions to be overriden by players */
       
   733 
       
   734 IriSP.Model.Mashup.prototype.getCurrentTime = function() { return new IriSP.Model.Time(0); }
       
   735 
       
   736 IriSP.Model.Mashup.prototype.getVolume = function() { return .5; }
       
   737 
       
   738 IriSP.Model.Mashup.prototype.getPaused = function() { return true; }
       
   739 
       
   740 IriSP.Model.Mashup.prototype.getMuted = function() { return false; }
       
   741 
       
   742 IriSP.Model.Mashup.prototype.setCurrentTime
       
   743     = IriSP.Model.Mashup.prototype.setVolume
       
   744     = IriSP.Model.Mashup.prototype.setMuted
       
   745     = IriSP.Model.Mashup.prototype.play
       
   746     = IriSP.Model.Mashup.prototype.pause
       
   747     = function() {}
       
   748 
       
   749 /* */
   786 /* */
   750 
   787 
   751 IriSP.Model.Source = function(_config) {
   788 Model.Source = function(_config) {
   752     this.status = IriSP.Model._SOURCE_STATUS_EMPTY;
   789     this.status = Model._SOURCE_STATUS_EMPTY;
   753     this.elementType = "source";
   790     this.elementType = "source";
   754     if (typeof _config !== "undefined") {
   791     if (typeof _config !== "undefined") {
   755         var _this = this;
   792         var _this = this;
   756         IriSP._(_config).forEach(function(_v, _k) {
   793         ns._(_config).forEach(function(_v, _k) {
   757             _this[_k] = _v;
   794             _this[_k] = _v;
   758         })
   795         })
   759         this.callbackQueue = [];
   796         this.callbackQueue = [];
   760         this.contents = {};
   797         this.contents = {};
   761         this.get();
   798         this.get();
   762     }
   799     }
   763 }
   800 }
   764 
   801 
   765 IriSP.Model.Source.prototype = new IriSP.Model.Element();
   802 Model.Source.prototype = new Model.Element();
   766 
   803 
   767 IriSP.Model.Source.prototype.addList = function(_listId, _contents) {
   804 Model.Source.prototype.addList = function(_listId, _contents) {
   768     if (typeof this.contents[_listId] === "undefined") {
   805     if (typeof this.contents[_listId] === "undefined") {
   769         this.contents[_listId] = new IriSP.Model.List(this.directory);
   806         this.contents[_listId] = new Model.List(this.directory);
   770     }
   807     }
   771     this.contents[_listId].addElements(_contents);
   808     this.contents[_listId].addElements(_contents);
   772 }
   809 }
   773 
   810 
   774 IriSP.Model.Source.prototype.getList = function(_listId, _global) {
   811 Model.Source.prototype.getList = function(_listId, _global) {
   775     _global = (typeof _global !== "undefined" && _global);
   812     _global = (typeof _global !== "undefined" && _global);
   776     if (_global || typeof this.contents[_listId] === "undefined") {
   813     if (_global || typeof this.contents[_listId] === "undefined") {
   777         return this.directory.getGlobalList().filter(function(_e) {
   814         return this.directory.getGlobalList().filter(function(_e) {
   778             return (_e.elementType === _listId);
   815             return (_e.elementType === _listId);
   779         });
   816         });
   780     } else {
   817     } else {
   781         return this.contents[_listId];
   818         return this.contents[_listId];
   782     }
   819     }
   783 }
   820 }
   784 
   821 
   785 IriSP.Model.Source.prototype.forEach = function(_callback) {
   822 Model.Source.prototype.forEach = function(_callback) {
   786     var _this = this;
   823     var _this = this;
   787     IriSP._(this.contents).forEach(function(_value, _key) {
   824     ns._(this.contents).forEach(function(_value, _key) {
   788         _callback.call(_this, _value, _key);
   825         _callback.call(_this, _value, _key);
   789     })
   826     })
   790 }
   827 }
   791 
   828 
   792 IriSP.Model.Source.prototype.getElement = function(_elId) {
   829 Model.Source.prototype.getElement = function(_elId) {
   793     return this.directory.getElement(_elId);
   830     return this.directory.getElement(_elId);
   794 }
   831 }
   795 
   832 
   796 IriSP.Model.Source.prototype.get = function() {
   833 Model.Source.prototype.get = function() {
   797     this.status = IriSP.Model._SOURCE_STATUS_WAITING;
   834     this.status = Model._SOURCE_STATUS_WAITING;
   798     this.handleCallbacks();
   835     this.handleCallbacks();
   799 }
   836 }
   800 
   837 
   801 /* We defer the callbacks calls so they execute after the queue is cleared */
   838 /* We defer the callbacks calls so they execute after the queue is cleared */
   802 IriSP.Model.Source.prototype.deferCallback = function(_callback) {
   839 Model.Source.prototype.deferCallback = function(_callback) {
   803     var _this = this;
   840     var _this = this;
   804     IriSP._.defer(function() {
   841     ns._.defer(function() {
   805         _callback.call(_this);
   842         _callback.call(_this);
   806     });
   843     });
   807 }
   844 }
   808 
   845 
   809 IriSP.Model.Source.prototype.handleCallbacks = function() {
   846 Model.Source.prototype.handleCallbacks = function() {
   810     this.status = IriSP.Model._SOURCE_STATUS_READY;
   847     this.status = Model._SOURCE_STATUS_READY;
   811     while (this.callbackQueue.length) {
   848     while (this.callbackQueue.length) {
   812         this.deferCallback(this.callbackQueue.splice(0,1)[0]);
   849         this.deferCallback(this.callbackQueue.splice(0,1)[0]);
   813     }
   850     }
   814 }
   851 }
   815 IriSP.Model.Source.prototype.onLoad = function(_callback) {
   852 Model.Source.prototype.onLoad = function(_callback) {
   816     if (this.status === IriSP.Model._SOURCE_STATUS_READY) {
   853     if (this.status === Model._SOURCE_STATUS_READY) {
   817         this.deferCallback(_callback);
   854         this.deferCallback(_callback);
   818     } else {
   855     } else {
   819         this.callbackQueue.push(_callback);
   856         this.callbackQueue.push(_callback);
   820     }
   857     }
   821 }
   858 }
   822 
   859 
   823 IriSP.Model.Source.prototype.serialize = function() {
   860 Model.Source.prototype.serialize = function() {
   824     return this.serializer.serialize(this);
   861     return this.serializer.serialize(this);
   825 }
   862 }
   826 
   863 
   827 IriSP.Model.Source.prototype.deSerialize = function(_data) {
   864 Model.Source.prototype.deSerialize = function(_data) {
   828     this.serializer.deSerialize(_data, this);
   865     this.serializer.deSerialize(_data, this);
   829 }
   866 }
   830 
   867 
   831 IriSP.Model.Source.prototype.getAnnotations = function(_global) {
   868 Model.Source.prototype.getAnnotations = function(_global) {
   832     _global = (typeof _global !== "undefined" && _global);
   869     _global = (typeof _global !== "undefined" && _global);
   833     return this.getList("annotation", _global);
   870     return this.getList("annotation", _global);
   834 }
   871 }
   835 
   872 
   836 IriSP.Model.Source.prototype.getMedias = function(_global) {
   873 Model.Source.prototype.getMedias = function(_global) {
   837     _global = (typeof _global !== "undefined" && _global);
   874     _global = (typeof _global !== "undefined" && _global);
   838     return this.getList("media", _global);
   875     return this.getList("media", _global);
   839 }
   876 }
   840 
   877 
   841 IriSP.Model.Source.prototype.getTags = function(_global) {
   878 Model.Source.prototype.getTags = function(_global) {
   842     _global = (typeof _global !== "undefined" && _global);
   879     _global = (typeof _global !== "undefined" && _global);
   843     return this.getList("tag", _global);
   880     return this.getList("tag", _global);
   844 }
   881 }
   845 
   882 
   846 IriSP.Model.Source.prototype.getMashups = function(_global) {
   883 Model.Source.prototype.getMashups = function(_global) {
   847     _global = (typeof _global !== "undefined" && _global);
   884     _global = (typeof _global !== "undefined" && _global);
   848     return this.getList("mashup", _global);
   885     return this.getList("mashup", _global);
   849 }
   886 }
   850 
   887 
   851 IriSP.Model.Source.prototype.getAnnotationTypes = function(_global) {
   888 Model.Source.prototype.getAnnotationTypes = function(_global) {
   852     _global = (typeof _global !== "undefined" && _global);
   889     _global = (typeof _global !== "undefined" && _global);
   853     return this.getList("annotationType", _global);
   890     return this.getList("annotationType", _global);
   854 }
   891 }
   855 
   892 
   856 IriSP.Model.Source.prototype.getAnnotationsByTypeTitle = function(_title, _global) {
   893 Model.Source.prototype.getAnnotationsByTypeTitle = function(_title, _global) {
   857     _global = (typeof _global !== "undefined" && _global);
   894     _global = (typeof _global !== "undefined" && _global);
   858     var _res = new IriSP.Model.List(this.directory),
   895     var _res = new Model.List(this.directory),
   859         _annTypes = this.getAnnotationTypes(_global).searchByTitle(_title);
   896         _annTypes = this.getAnnotationTypes(_global).searchByTitle(_title);
   860     _annTypes.forEach(function(_annType) {
   897     _annTypes.forEach(function(_annType) {
   861         _res.addElements(_annType.getAnnotations(_global));
   898         _res.addElements(_annType.getAnnotations(_global));
   862     })
   899     })
   863     return _res;
   900     return _res;
   864 }
   901 }
   865 
   902 
   866 IriSP.Model.Source.prototype.getDuration = function() {
   903 Model.Source.prototype.getDuration = function() {
   867     var _m = this.currentMedia;
   904     var _m = this.currentMedia;
   868     if (typeof _m !== "undefined") {
   905     if (typeof _m !== "undefined") {
   869         return this.currentMedia.duration;
   906         return this.currentMedia.duration;
   870     }
   907     }
   871 }
   908 }
   872 
   909 
   873 IriSP.Model.Source.prototype.getCurrentMedia = function(_opts) {
   910 Model.Source.prototype.getCurrentMedia = function(_opts) {
   874     if (typeof this.currentMedia === "undefined") {
   911     if (typeof this.currentMedia === "undefined") {
   875         if (_opts.is_mashup) {
   912         if (_opts.is_mashup) {
   876             var _mashups = this.getMashups();
   913             var _mashups = this.getMashups();
   877             if (_mashups.length) {
   914             if (_mashups.length) {
   878                 this.currentMedia = _mashups[0];
   915                 this.currentMedia = _mashups[0];
   885         }
   922         }
   886     }
   923     }
   887     return this.currentMedia;
   924     return this.currentMedia;
   888 }
   925 }
   889 
   926 
   890 IriSP.Model.Source.prototype.merge = function(_source) {
   927 Model.Source.prototype.merge = function(_source) {
   891     var _this = this;
   928     var _this = this;
   892     _source.forEach(function(_value, _key) {
   929     _source.forEach(function(_value, _key) {
   893         _this.getList(_key).addElements(_value);
   930         _this.getList(_key).addElements(_value);
   894     });
   931     });
   895 }
   932 }
   896 
   933 
   897 /* */
   934 /* */
   898 
   935 
   899 IriSP.Model.RemoteSource = function(_config) {
   936 Model.RemoteSource = function(_config) {
   900     IriSP.Model.Source.call(this, _config);
   937     Model.Source.call(this, _config);
   901 }
   938 }
   902 
   939 
   903 IriSP.Model.RemoteSource.prototype = new IriSP.Model.Source();
   940 Model.RemoteSource.prototype = new Model.Source();
   904 
   941 
   905 IriSP.Model.RemoteSource.prototype.get = function() {
   942 Model.RemoteSource.prototype.get = function() {
   906     this.status = IriSP.Model._SOURCE_STATUS_WAITING;
   943     this.status = Model._SOURCE_STATUS_WAITING;
   907     var _this = this;
   944     var _this = this;
   908     this.serializer.loadData(this.url, function(_result) {
   945     this.serializer.loadData(this.url, function(_result) {
   909         _this.deSerialize(_result);
   946         _this.deSerialize(_result);
   910         _this.handleCallbacks();
   947         _this.handleCallbacks();
   911     });
   948     });
   912 }
   949 }
   913 
   950 
   914 /* */
   951 /* */
   915 
   952 
   916 IriSP.Model.Directory = function() {
   953 Model.Directory = function() {
   917     this.remoteSources = {};
   954     this.remoteSources = {};
   918     this.elements = {};
   955     this.elements = {};
   919 }
   956 }
   920 
   957 
   921 IriSP.Model.Directory.prototype.remoteSource = function(_properties) {
   958 Model.Directory.prototype.remoteSource = function(_properties) {
   922     if (typeof _properties !== "object" || typeof _properties.url === "undefined") {
   959     if (typeof _properties !== "object" || typeof _properties.url === "undefined") {
   923         throw "Error : IriSP.Model.Directory.remoteSource(configuration): configuration.url is undefined";
   960         throw "Error : Model.Directory.remoteSource(configuration): configuration.url is undefined";
   924     }
   961     }
   925     var _config = IriSP._({ directory: this }).extend(_properties);
   962     var _config = ns._({ directory: this }).extend(_properties);
   926     if (typeof this.remoteSources[_properties.url] === "undefined") {
   963     if (typeof this.remoteSources[_properties.url] === "undefined") {
   927         this.remoteSources[_properties.url] = new IriSP.Model.RemoteSource(_config);
   964         this.remoteSources[_properties.url] = new Model.RemoteSource(_config);
   928     }
   965     }
   929     return this.remoteSources[_properties.url];
   966     return this.remoteSources[_properties.url];
   930 }
   967 }
   931 
   968 
   932 IriSP.Model.Directory.prototype.newLocalSource = function(_properties) {
   969 Model.Directory.prototype.newLocalSource = function(_properties) {
   933     var _config = IriSP._({ directory: this }).extend(_properties),
   970     var _config = ns._({ directory: this }).extend(_properties),
   934         _res = new IriSP.Model.Source(_config);
   971         _res = new Model.Source(_config);
   935     return _res;
   972     return _res;
   936 }
   973 }
   937 
   974 
   938 IriSP.Model.Directory.prototype.getElement = function(_id) {
   975 Model.Directory.prototype.getElement = function(_id) {
   939     return this.elements[_id];
   976     return this.elements[_id];
   940 }
   977 }
   941 
   978 
   942 IriSP.Model.Directory.prototype.addElement = function(_element) {
   979 Model.Directory.prototype.addElement = function(_element) {
   943     this.elements[_element.id] = _element;
   980     this.elements[_element.id] = _element;
   944 }
   981 }
   945 
   982 
   946 IriSP.Model.Directory.prototype.getGlobalList = function() {
   983 Model.Directory.prototype.getGlobalList = function() {
   947     var _res = new IriSP.Model.List(this);
   984     var _res = new Model.List(this);
   948     _res.addIds(IriSP._(this.elements).keys());
   985     _res.addIds(ns._(this.elements).keys());
   949     return _res;
   986     return _res;
   950 }
   987 }
   951 
   988 
   952 /* */
   989 ns.Model = Model;
       
   990 
       
   991 })(IriSP);