1 /** The minplayer namespace. */
  2 minplayer = minplayer || {};
  3 
  4 /**
  5  * @constructor
  6  * @extends minplayer.plugin
  7  * @class Base class used to provide the display and options for any component
  8  * deriving from this class.  Components who derive are expected to provide
  9  * the elements that they define by implementing the getElements method.
 10  *
 11  * @param {string} name The name of this plugin.
 12  * @param {object} context The jQuery context this component resides.
 13  * @param {object} options The options for this component.
 14  * @param {object} queue The event queue to pass events around.
 15  */
 16 minplayer.display = function(name, context, options, queue) {
 17 
 18   // Derive from plugin
 19   minplayer.plugin.call(this, name, context, options, queue);
 20 };
 21 
 22 /** Derive from minplayer.plugin. */
 23 minplayer.display.prototype = new minplayer.plugin();
 24 
 25 /** Reset the constructor. */
 26 minplayer.display.prototype.constructor = minplayer.display;
 27 
 28 /**
 29  * Returns the display for this component.
 30  *
 31  * @param {object} context The context which this display is within.
 32  * @param {object} options The options to get the display.
 33  *
 34  * @return {object} The jQuery context for this display.
 35  */
 36 minplayer.display.prototype.getDisplay = function(context, options) {
 37 
 38   // Return the context.
 39   return context;
 40 };
 41 
 42 /**
 43  * @see minplayer.plugin.initialize
 44  */
 45 minplayer.display.prototype.initialize = function() {
 46 
 47   // Only set the display if it hasn't already been set.
 48   if (!this.display) {
 49 
 50     // Set the display.
 51     this.display = this.getDisplay(this.context, this.options);
 52   }
 53 
 54   // Only continue loading this plugin if there is a display.
 55   if (this.display) {
 56 
 57     // Set the plugin name within the options.
 58     this.options.pluginName = 'display';
 59 
 60     // Get the display elements.
 61     this.elements = this.getElements();
 62 
 63     // Call the plugin initialize method.
 64     minplayer.plugin.prototype.initialize.call(this);
 65   }
 66 };
 67 
 68 /**
 69  * @see minplayer.plugin.construct
 70  */
 71 minplayer.display.prototype.construct = function() {
 72 
 73   // Call the plugin constructor.
 74   minplayer.plugin.prototype.construct.call(this);
 75 
 76   // Set if this display is in autohide.
 77   this.autoHide = false;
 78 
 79   // Only do this if they allow resize for this display.
 80   if (this.onResize) {
 81 
 82     // Set the resize timeout and this pointer.
 83     var resizeTimeout = 0;
 84 
 85     // Add a handler to trigger a resize event.
 86     jQuery(window).resize((function(display) {
 87       return function() {
 88         clearTimeout(resizeTimeout);
 89         resizeTimeout = setTimeout(function() {
 90           display.onResize();
 91         }, 200);
 92       };
 93     })(this));
 94   }
 95 };
 96 
 97 /**
 98  * Called when the window resizes.
 99  */
100 minplayer.display.prototype.onResize = false;
101 
102 /**
103  * Wrapper around hide that will always not show.
104  *
105  * @param {object} element The element you wish to hide.
106  */
107 minplayer.display.prototype.hide = function(element) {
108   element = element || this.display;
109   if (element) {
110     element.forceHide = true;
111     element.unbind().hide();
112   }
113 };
114 
115 /**
116  * Gets the full screen element.
117  *
118  * @return {object} The display to be used for full screen support.
119  */
120 minplayer.display.prototype.fullScreenElement = function() {
121   return this.display;
122 };
123 
124 /**
125  * Fix for the click function in jQuery to be cross platform.
126  *
127  * @param {object} element The element that will be clicked.
128  * @param {function} fn Called when the element is clicked.
129  * @return {object} The element that is to be clicked.
130  */
131 minplayer.click = function(element, fn) {
132   var flag = false;
133   element = jQuery(element);
134   element.bind('touchstart click', function(event) {
135     if (!flag) {
136       flag = true;
137       setTimeout(function() {
138         flag = false;
139       }, 100);
140       fn.call(this, event);
141     }
142   });
143   return element;
144 };
145 
146 /**
147  * Determines if the player is in focus or not.
148  *
149  * @param {boolean} focus If the player is in focus.
150  */
151 minplayer.display.prototype.onFocus = function(focus) {
152   this.hasFocus = this.focus = focus;
153 
154   // If they have autoHide enabled, then show then hide this element.
155   if (this.autoHide) {
156     this.showThenHide(
157       this.autoHide.element,
158       this.autoHide.timeout,
159       this.autoHide.cb
160     );
161   }
162 };
163 
164 /**
165  * Called if you would like for your plugin to show then hide.
166  *
167  * @param {object} element The element you would like to hide or show.
168  * @param {number} timeout The timeout to hide and show.
169  * @param {function} cb Called when something happens.
170  */
171 minplayer.display.prototype.showThenHide = function(element, timeout, cb) {
172 
173   // Get the element type.
174   var elementType = (typeof element);
175 
176   // Set some interface defaults.
177   if (elementType === 'undefined') {
178     cb = null;
179     element = this.display;
180   }
181   else if (elementType === 'number') {
182     cb = timeout;
183     timeout = element;
184     element = this.display;
185   }
186   else if (elementType === 'function') {
187     cb = element;
188     element = this.display;
189   }
190 
191   if (!element) {
192     return;
193   }
194 
195   // Make sure we have a timeout.
196   timeout = timeout || 5000;
197 
198   // Set the autohide variable.
199   this.autoHide = {
200     element: element,
201     timeout: timeout,
202     cb: cb
203   };
204 
205   // Show the element.
206   if (!element.forceHide) {
207     if (typeof element.showMe !== 'undefined') {
208       if (element.showMe) {
209         element.showMe(cb);
210       }
211     }
212     else {
213       element.show();
214       if (cb) {
215         cb(true);
216       }
217     }
218   }
219 
220   // Define the hover state for this element.
221   if (!element.hoverState) {
222     jQuery(element).bind('mouseenter', function() {
223       element.hoverState = true;
224     });
225     jQuery(element).bind('mouseleave', function() {
226       element.hoverState = false;
227     });
228   }
229 
230   // Clear the timeout and start it over again.
231   clearTimeout(this.showTimer);
232   this.showTimer = setTimeout((function(self) {
233     return function tryAgain() {
234 
235       // Check the hover state.
236       if (!element.hoverState) {
237         if (typeof element.hideMe !== 'undefined') {
238           if (element.hideMe) {
239             element.hideMe(cb);
240           }
241         }
242         else {
243           // Hide the element.
244           element.hide('slow', function() {
245             if (cb) {
246               cb(false);
247             }
248           });
249         }
250       }
251       else {
252 
253         // Try again in the timeout time.
254         self.showTimer = setTimeout(tryAgain, timeout);
255       }
256     };
257   })(this), timeout);
258 };
259 
260 /**
261  * Make this display element go fullscreen.
262  *
263  * @param {boolean} full Tell the player to go into fullscreen or not.
264  */
265 minplayer.display.prototype.fullscreen = function(full) {
266   var isFull = this.isFullScreen();
267   var element = this.fullScreenElement();
268   if (isFull && !full) {
269     element.removeClass('fullscreen');
270     if (screenfull) {
271       screenfull.exit();
272     }
273     this.trigger('fullscreen', false);
274   }
275   else if (!isFull && full) {
276     element.addClass('fullscreen');
277     if (screenfull) {
278       screenfull.request(element[0]);
279       screenfull.onchange = (function(display) {
280         return function(e) {
281           if (!screenfull.isFullscreen) {
282             display.fullscreen(false);
283           }
284         };
285       })(this);
286     }
287     this.trigger('fullscreen', true);
288   }
289 };
290 
291 /**
292  * Toggle fullscreen.
293  */
294 minplayer.display.prototype.toggleFullScreen = function() {
295   this.fullscreen(!this.isFullScreen());
296 };
297 
298 /**
299  * Checks to see if we are in fullscreen mode.
300  *
301  * @return {boolean} TRUE - fullscreen, FALSE - otherwise.
302  */
303 minplayer.display.prototype.isFullScreen = function() {
304   return this.fullScreenElement().hasClass('fullscreen');
305 };
306 
307 /**
308  * Returns a scaled rectangle provided a ratio and the container rect.
309  *
310  * @param {number} ratio The width/height ratio of what is being scaled.
311  * @param {object} rect The bounding rectangle for scaling.
312  * @return {object} The Rectangle object of the scaled rectangle.
313  */
314 minplayer.display.prototype.getScaledRect = function(ratio, rect) {
315   var scaledRect = {};
316   scaledRect.x = rect.x ? rect.x : 0;
317   scaledRect.y = rect.y ? rect.y : 0;
318   scaledRect.width = rect.width ? rect.width : 0;
319   scaledRect.height = rect.height ? rect.height : 0;
320   if (ratio) {
321     if ((rect.width / rect.height) > ratio) {
322       scaledRect.height = rect.height;
323       scaledRect.width = Math.floor(rect.height * ratio);
324     }
325     else {
326       scaledRect.height = Math.floor(rect.width / ratio);
327       scaledRect.width = rect.width;
328     }
329     scaledRect.x = Math.floor((rect.width - scaledRect.width) / 2);
330     scaledRect.y = Math.floor((rect.height - scaledRect.height) / 2);
331   }
332   return scaledRect;
333 };
334 
335 /**
336  * Returns all the jQuery elements that this component uses.
337  *
338  * @return {object} An object which defines all the jQuery elements that
339  * this component uses.
340  */
341 minplayer.display.prototype.getElements = function() {
342   return {};
343 };
344