1 /** The minplayer namespace. */
  2 var minplayer = minplayer || {};
  3 
  4 /**
  5  * @constructor
  6  * @extends minplayer.display
  7  * @class The play loader base class, which is used to control the busy
  8  * cursor, big play button, and the opaque background which shows when the
  9  * player is paused.
 10  *
 11  * @param {object} context The jQuery context.
 12  * @param {object} options This components options.
 13  */
 14 minplayer.playLoader = function(context, options) {
 15 
 16   // Clear the variables.
 17   this.clear();
 18 
 19   // Derive from display
 20   minplayer.display.call(this, 'playLoader', context, options);
 21 };
 22 
 23 /** Derive from minplayer.display. */
 24 minplayer.playLoader.prototype = new minplayer.display();
 25 
 26 /** Reset the constructor. */
 27 minplayer.playLoader.prototype.constructor = minplayer.playLoader;
 28 
 29 /**
 30  * The constructor.
 31  */
 32 minplayer.playLoader.prototype.construct = function() {
 33 
 34   // Call the media display constructor.
 35   minplayer.display.prototype.construct.call(this);
 36 
 37   // Set the plugin name within the options.
 38   this.options.pluginName = 'playLoader';
 39 
 40   // Get the media plugin.
 41   this.initializePlayLoader();
 42 
 43   // We are now ready.
 44   this.ready();
 45 };
 46 
 47 /**
 48  * Initialize the playLoader.
 49  */
 50 minplayer.playLoader.prototype.initializePlayLoader = function() {
 51 
 52   // Get the media plugin.
 53   this.get('media', function(media) {
 54 
 55     // Only bind if this player does not have its own play loader.
 56     if (!media.hasPlayLoader(this.options.preview)) {
 57 
 58       // Enable the playLoader.
 59       this.enabled = true;
 60 
 61       // Get the poster image.
 62       if (!this.options.preview) {
 63         this.options.preview = media.poster;
 64       }
 65 
 66       // Determine if we should load the image.
 67       var shouldLoad = true;
 68       if (this.preview && this.preview.loader) {
 69         shouldLoad = (this.preview.loader.src !== this.options.preview);
 70       }
 71 
 72       // Only load the image if it is different.
 73       if (shouldLoad) {
 74         // Reset the media's poster image.
 75         media.elements.media.attr('poster', '');
 76 
 77         // Load the preview image.
 78         this.loadPreview();
 79       }
 80 
 81       // Trigger a play event when someone clicks on the controller.
 82       if (this.elements.bigPlay) {
 83         minplayer.click(this.elements.bigPlay.unbind(), function(event) {
 84           event.preventDefault();
 85           jQuery(this).hide();
 86           media.play();
 87         });
 88       }
 89 
 90       // Bind to the player events to control the play loader.
 91       media.ubind(this.uuid + ':loadstart', (function(playLoader) {
 92         return function(event, data, reset) {
 93           playLoader.busy.setFlag('media', true);
 94           playLoader.bigPlay.setFlag('media', true);
 95           playLoader.previewFlag.setFlag('media', true);
 96           playLoader.checkVisibility();
 97         };
 98       })(this));
 99       media.ubind(this.uuid + ':waiting', (function(playLoader) {
100         return function(event, data, reset) {
101           if (!reset) {
102             playLoader.busy.setFlag('media', true);
103             playLoader.checkVisibility();
104           }
105         };
106       })(this));
107       media.ubind(this.uuid + ':loadeddata', (function(playLoader) {
108         return function(event, data, reset) {
109           if (!reset) {
110             playLoader.busy.setFlag('media', false);
111             playLoader.checkVisibility();
112           }
113         };
114       })(this));
115       media.ubind(this.uuid + ':playing', (function(playLoader) {
116         return function(event, data, reset) {
117           if (!reset) {
118             playLoader.busy.setFlag('media', false);
119             playLoader.bigPlay.setFlag('media', false);
120             if (media.mediaFile.type !== 'audio') {
121               playLoader.previewFlag.setFlag('media', false);
122             }
123             playLoader.checkVisibility();
124           }
125         };
126       })(this));
127       media.ubind(this.uuid + ':pause', (function(playLoader) {
128         return function(event, data, reset) {
129           if (!reset) {
130             playLoader.busy.setFlag('media', false);
131             playLoader.bigPlay.setFlag('media', true);
132             playLoader.checkVisibility();
133           }
134         };
135       })(this));
136     }
137     else {
138 
139       // Hide the display.
140       this.enabled = false;
141       this.hide(this.elements.busy);
142       this.hide(this.elements.bigPlay);
143       this.hide(this.elements.preview);
144       this.hide();
145     }
146   });
147 };
148 
149 /**
150  * Clears the playloader.
151  *
152  * @param {function} callback Called when the playloader is finished clearing.
153  */
154 minplayer.playLoader.prototype.clear = function(callback) {
155 
156   // Define the flags that control the busy cursor.
157   this.busy = new minplayer.flags();
158 
159   // Define the flags that control the big play button.
160   this.bigPlay = new minplayer.flags();
161 
162   // Define the flags the control the preview.
163   this.previewFlag = new minplayer.flags();
164 
165   /** If the playLoader is enabled. */
166   this.enabled = true;
167 
168   // If the preview is defined, then clear the image.
169   if (this.preview) {
170 
171     this.preview.clear((function(playLoader) {
172       return function() {
173 
174         // Reset the preview.
175         playLoader.preview = null;
176 
177         // If they wish to be called back after it is cleared.
178         if (callback) {
179           callback();
180         }
181       };
182     })(this));
183   }
184   else {
185 
186     /** The preview image. */
187     this.preview = null;
188 
189     // Return the callback.
190     if (callback) {
191       callback();
192     }
193   }
194 };
195 
196 /**
197  * Loads the preview image.
198  *
199  * @param {string} image The image you would like to load.
200  * @return {boolean} Returns true if an image was loaded, false otherwise.
201  */
202 minplayer.playLoader.prototype.loadPreview = function(image) {
203 
204   // Get the image to load.
205   image = image || this.options.preview;
206   this.options.preview = image;
207 
208   // Ignore if disabled.
209   if (!this.enabled || (this.display.length === 0)) {
210     return;
211   }
212 
213   // If the preview element exists.
214   if (this.elements.preview) {
215 
216     // If there is a preview to show...
217     if (this.options.preview) {
218 
219       // Say that this has a preview.
220       this.elements.preview.addClass('has-preview').show();
221 
222       // Create a new preview image.
223       this.preview = new minplayer.image(this.elements.preview, this.options);
224 
225       // Create the image.
226       this.preview.load(this.options.preview);
227       return true;
228     }
229     else {
230 
231       // Hide the preview.
232       this.elements.preview.hide();
233     }
234   }
235 
236   return false;
237 };
238 
239 /**
240  * Hide or show certain elements based on the state of the busy and big play
241  * button.
242  */
243 minplayer.playLoader.prototype.checkVisibility = function() {
244 
245   // Ignore if disabled.
246   if (!this.enabled) {
247     return;
248   }
249 
250   // Hide or show the busy cursor based on the flags.
251   if (this.busy.flag) {
252     this.elements.busy.show();
253   }
254   else {
255     this.elements.busy.hide();
256   }
257 
258   // Hide or show the big play button based on the flags.
259   if (this.bigPlay.flag) {
260     this.elements.bigPlay.show();
261   }
262   else {
263     this.elements.bigPlay.hide();
264   }
265 
266   if (this.previewFlag.flag) {
267     this.elements.preview.show();
268   }
269   else {
270     this.elements.preview.hide();
271   }
272 
273   // Show the control either flag is set.
274   if (this.bigPlay.flag || this.busy.flag || this.previewFlag.flag) {
275     this.display.show();
276   }
277 
278   // Hide the whole control if both flags are 0.
279   if (!this.bigPlay.flag && !this.busy.flag && !this.previewFlag.flag) {
280     this.display.hide();
281   }
282 };
283