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 /* */ |