1 // Add a way to instanciate using jQuery prototype.
  2 if (!jQuery.fn.osmplayer) {
  3 
  4   /**
  5    * @constructor
  6    *
  7    * Define a jQuery osmplayer prototype.
  8    *
  9    * @param {object} options The options for this jQuery prototype.
 10    * @return {Array} jQuery object.
 11    */
 12   jQuery.fn.osmplayer = function(options) {
 13     return jQuery(this).each(function() {
 14       options = options || {};
 15       options.id = options.id || jQuery(this).attr('id') || Math.random();
 16       if (!minplayer.plugins[options.id]) {
 17         options.template = options.template || 'default';
 18         if (osmplayer[options.template]) {
 19           new osmplayer[options.template](jQuery(this), options);
 20         }
 21         else {
 22           new osmplayer(jQuery(this), options);
 23         }
 24       }
 25     });
 26   };
 27 }
 28 
 29 /**
 30  * @constructor
 31  * @extends minplayer
 32  * @class The main osmplayer class.
 33  *
 34  * <p><strong>Usage:</strong>
 35  * <pre><code>
 36  *
 37  *   // Create a media player.
 38  *   var player = jQuery("#player").osmplayer({
 39  *
 40  *   });
 41  *
 42  * </code></pre>
 43  * </p>
 44  *
 45  * @param {object} context The jQuery context.
 46  * @param {object} options This components options.
 47  */
 48 osmplayer = function(context, options) {
 49 
 50   // Derive from minplayer
 51   minplayer.call(this, context, options);
 52 };
 53 
 54 /** Derive from minplayer. */
 55 osmplayer.prototype = new minplayer();
 56 
 57 /** Reset the constructor. */
 58 osmplayer.prototype.constructor = osmplayer;
 59 
 60 /**
 61  * Creates a new plugin within this context.
 62  *
 63  * @param {string} name The name of the plugin you wish to create.
 64  * @param {object} base The base object for this plugin.
 65  * @param {object} context The context which you would like to create.
 66  * @return {object} The new plugin object.
 67  */
 68 osmplayer.prototype.create = function(name, base, context) {
 69   return minplayer.prototype.create.call(this, name, 'osmplayer', context);
 70 };
 71 
 72 /**
 73  * @see minplayer.plugin.construct
 74  */
 75 osmplayer.prototype.construct = function() {
 76 
 77   // Make sure we provide default options...
 78   this.options = jQuery.extend({
 79     playlist: '',
 80     node: {},
 81     swfplayer: 'minplayer/flash/minplayer.swf',
 82     logo: 'logo.png',
 83     link: 'http://www.mediafront.org'
 84   }, this.options);
 85 
 86   // Call the minplayer display constructor.
 87   minplayer.prototype.construct.call(this);
 88 
 89   /** The play queue and index. */
 90   this.playQueue = [];
 91   this.playIndex = 0;
 92   this.hasPlaylist = false;
 93 
 94   /** The playlist for this media player. */
 95   this.create('playlist', 'osmplayer');
 96 
 97   /** Get the playlist or any other playlist that connects. */
 98   this.get('playlist', function(playlist) {
 99     this.hasPlaylist = true;
100     playlist.ubind(this.uuid + ':nodeLoad', (function(player) {
101       return function(event, data) {
102         player.loadNode(data);
103       };
104     })(this));
105   });
106 
107   // Play each media sequentially...
108   this.get('media', (function(player) {
109     return function(media) {
110       media.ubind(player.uuid + ':ended', function() {
111         player.options.autoplay = true;
112         player.playNext();
113       });
114     };
115   })(this));
116 
117   // Load the node if one is provided.
118   if (this.options.node) {
119     this.loadNode(this.options.node);
120   }
121 };
122 
123 /**
124  * Gets the full screen element.
125  *
126  * @return {object} The element that will go into fullscreen.
127  */
128 osmplayer.prototype.fullScreenElement = function() {
129   return this.elements.minplayer;
130 };
131 
132 /**
133  * The load node function.
134  *
135  * @param {object} node A media node object.
136  */
137 osmplayer.prototype.loadNode = function(node) {
138   if (node && node.mediafiles) {
139 
140     // Load the media files.
141     var media = node.mediafiles.media;
142     if (media) {
143       this.playQueue.length = 0;
144       this.playQueue = [];
145       this.playIndex = 0;
146       var file = null;
147       var types = [];
148 
149       // For mobile devices, we should only show the main media.
150       if (minplayer.isAndroid || minplayer.isIDevice) {
151         types = ['media'];
152       }
153       else {
154         types = ['intro', 'commercial', 'prereel', 'media', 'postreel'];
155       }
156 
157       // Iterate through the types.
158       jQuery.each(types, (function(player) {
159         return function(key, type) {
160           if (file = player.addToQueue(media[type])) {
161             file.queueType = type;
162           }
163         };
164       })(this));
165     }
166 
167     // Load the preview image.
168     osmplayer.getImage(node.mediafiles, 'preview', (function(player) {
169       return function(image) {
170         player.options.preview = image.path;
171         if (player.playLoader) {
172           player.playLoader.initialize();
173         }
174       };
175     })(this));
176 
177     // Play the next media
178     this.playNext();
179   }
180 };
181 
182 /**
183  * Adds a file to the play queue.
184  *
185  * @param {object} file The file to add to the queue.
186  * @return {object} The file that was added to the queue.
187  */
188 osmplayer.prototype.addToQueue = function(file) {
189   if (file = minplayer.getMediaFile(file)) {
190     this.playQueue.push(file);
191   }
192   return file;
193 };
194 
195 /**
196  * Plays the next media file in the queue.
197  */
198 osmplayer.prototype.playNext = function() {
199   if (this.playQueue.length > this.playIndex) {
200     this.load(this.playQueue[this.playIndex]);
201     this.playIndex++;
202   }
203   else if (this.options.repeat) {
204     this.playIndex = 0;
205     this.playNext();
206   }
207   else if (this.playQueue.length > 0) {
208 
209     // If we have a playlist, let them handle what to do next.
210     if (this.hasPlaylist) {
211       this.trigger('player_ended');
212     }
213     else {
214       // If there is no playlist, and no repeat, we will
215       // just seek to the beginning and pause.
216       this.options.autoplay = false;
217       this.playIndex = 0;
218       this.playNext();
219     }
220   }
221   else if (this.media) {
222     // Stop the player and unload.
223     this.media.stop();
224   }
225 };
226 
227 /**
228  * Returns an image provided image array.
229  *
230  * @param {object} mediafiles The mediafiles to search within.
231  * @param {string} type The type of image to look for.
232  * @param {function} callback Called when the image is retrieved.
233  */
234 osmplayer.getImage = function(mediafiles, type, callback) {
235 
236   var image = '';
237   var images = mediafiles.image;
238   if (images) {
239 
240     // If the image type exists, then just use that one...
241     if (images[type]) {
242       image = images[type];
243     }
244     // Or try the original image...
245     else if (images['image']) {
246       image = images['image'];
247     }
248     // Otherwise, just try ANY image...
249     else {
250 
251       // Or, just pick the first one available.
252       for (type in images) {
253         if (images.hasOwnProperty(type)) {
254           image = images[type];
255           break;
256         }
257       }
258     }
259   }
260 
261   // If the image exists, then callback with that image.
262   if (image) {
263     callback(new minplayer.file(image));
264   }
265   else {
266     // Get the image from the media player...
267     var mediaFile = minplayer.getMediaFile(mediafiles.media.media);
268     if (mediaFile) {
269       var player = minplayer.players[mediaFile.player];
270       if (player && (typeof player.getImage === 'function')) {
271         player.getImage(mediaFile, type, function(src) {
272           callback(new minplayer.file(src));
273         });
274       }
275     }
276   }
277 };
278