4fa1ededb321ffcdf8dd4c8fb0ef2ec7f0ceba97
[platform/framework/web/web-ui-fw.git] / src / widgets / multimediaview / js / jquery.mobile.tizen.multimediaview.js
1 /* ***************************************************************************
2  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  * ***************************************************************************
22  *
23  * Authors: Yonghwi Park <yonghwi0324.park@samsung.com>
24  *               Wonseop Kim <wonseop.kim@samsung.com>
25 */
26
27 /**
28  *
29  * MultiMediaView is a widget that lets the user view and handle multimedia contents.
30  * Video and audio elements are coded as standard HTML elements and enhanced by the 
31  * MultiMediaview to make them attractive and usable on a mobile device.
32  *
33  * HTML Attributes:
34  *                      data-theme : Set a theme of widget.
35  *                              If this value is not defined, widget will use parent`s theme. (optional)
36  *                      data-controls : If this value is 'true', widget will use belonging controller.
37  *                              If this value is 'false', widget will use browser`s controller.
38  *                              Default value is 'true'.
39  *                      data-full-screen : Set a status that full-screen when inital start.
40  *                              Default value is 'false'.
41  *
42  * APIs:
43  *                      width( [number] )
44  *                                      : Get or set the width of widget.
45  *                                      The first argument is the width of widget.
46  *                                      If no first argument is specified, will act as a getter.
47  *                      height( [number] )
48  *                                      : Get or set the height of widget.
49  *                                      The first argument is the height of widget.
50  *                                      If no first argument is specified, will act as a getter.
51  *                      fullScreen( [boolean] )
52  *                                      : Get or Set the status of full-screen.
53  *                                      If no first argument is specified, will act as a getter.
54  *
55  * Events:
56  *
57  *                      create :  triggered when a multimediaview is created.
58  *
59  * Examples:
60  *
61  *                      VIDEO :
62  *                              <video data-controls="true" style="width:100%;">
63  *                                      <source src="media/oceans-clip.mp4" type="video/mp4" />
64  *                                      Your browser does not support the video tag.
65  *                              </video>
66  *
67  *                      AUDIO :
68  *                              <audio data-controls="true" style="width:100%;">
69  *                                      <source src="media/Over the horizon.mp3" type="audio/mp3" />
70  *                                      Your browser does not support the audio tag.
71  *                              </audio>
72  *
73  */
74 /**
75         @class MutimediaView
76         The multimedia view widget shows a player control that you can use to view and handle multimedia content. This widget uses the standard HTML video and audio elements, which have been enhanced for use on a mobile device.
77
78         To add a multimedia view widget to the application, use the following code:
79         
80                 // Video player control
81                 <video data-controls="true" style="width:100%;">
82                 <source src="<VIDEO_FILE_URL>" type="video/mp4" /> Your browser does not support the video tag. </video>
83                 // Audio player control
84                 <audio data-controls="true" style="width:100%;"> <source src="<AUDIO_FILE_URL>" type="audio/mp3" /> Your browser does not support the audio tag.
85                 </audio>
86
87         The multimedia view can define a callback for the create event, which is fired when the widget is created.
88                 $('.selector').multimediaview({
89                         create:function(event, u){...}
90                 });
91                 $(".selector").bind("create", function(event, ui)
92                 {
93                         // Respond to the multimedia view widget creation
94                 });
95 */
96 /**
97         @property {Boolean} data-control
98         Sets the controls for the widget.
99         The default value is true. If the value is set to true, the widget uses its own player controls. If the value is set to false, the widget uses the browser's player controls.
100 */
101 /**
102         @property {Boolean} data-full-screen
103         Defines whether the widget opens in the fullscreen view mode.
104         The default value is false.
105 */
106 /**
107         @property {String} data-theme
108         Sets the widget theme.
109         If the value is not set, the parent control's theme is used
110 */
111 /**
112         @method width
113         The width method is used to get (if no value is defined) or set the multimedia view widget width:
114                 <video>
115                          <source src="test.mp4" type="video/mp4" />
116                 </video>
117                 $(".selector").multimediaview("width", [value]);
118 */
119 /**
120         @method height
121         The height method is used to get (if no value is defined) or set the multimedia view widget height:
122                 <video>
123                         <source src="test.mp4" type="video/mp4" />
124                 </video>
125                 $(".selector").multimediaview("height", [value]);
126 */
127 /**
128         @method fullScreen
129         The fullScreen method is used to get (if no value is defined) or set the full-screen mode of the multimedia view widget. If the value is true, the full-screen mode is used; otherwise the multimedia view widget runs in the normal mode.
130
131                 <video>
132                         <source src="test.mp4" type="video/mp4" />
133                 </video>
134                 $(".selector").multimediaview("fullScreen", [value]);
135 */
136 ( function ( $, document, window, undefined ) {
137         $.widget( "tizen.multimediaview", $.mobile.widget, {
138                 options : {
139                         theme : null,
140                         controls : true,
141                         fullScreen : false,
142                         initSelector : "video, audio"
143                 },
144                 _create : function () {
145                         var self = this,
146                                 view = self.element,
147                                 viewElement = view[0],
148                                 option = self.options,
149                                 role = "multimediaview",
150                                 control = null;
151
152                         $.extend( this, {
153                                 role : null,
154                                 isControlHide : false,
155                                 controlTimer : null,
156                                 isVolumeHide : true,
157                                 isVertical : true,
158                                 backupView : null
159                         });
160
161                         self.role = role;
162                         view.addClass( "ui-multimediaview" );
163                         control = self._createControl();
164
165                         if ( view[0].nodeName === "VIDEO" ) {
166                                 control.addClass( "ui-multimediaview-video" );
167                         }
168
169                         control.hide();
170                         view.wrap( "<div class='ui-multimediaview-wrap'>" ).after( control );
171                         if ( option.controls ) {
172                                 if ( view.attr("controls") ) {
173                                         view.removeAttr( "controls" );
174                                 }
175                         }
176
177                         self._addEvent();
178
179                         $( document ).bind( "pagechange.multimediaview", function ( e ) {
180                                 var $page = $( e.target );
181                                 if ( $page.find( view ).length > 0 && viewElement.autoplay ) {
182                                         viewElement.play();
183                                 }
184
185                                 if ( option.controls ) {
186                                         control.show();
187                                         self._resize();
188                                 }
189                         }).bind( "pagebeforechange.multimediaview", function ( e ) {
190                                 if ( viewElement.played.length !== 0 ) {
191                                         viewElement.pause();
192                                         control.hide();
193                                 }
194                         });
195                         $( window ).bind( "resize.multimediaview orientationchange.multimediaview", function ( e ) {
196                                 if ( !option.controls ) {
197                                         return;
198                                 }
199                                 var $page = $( e.target ),
200                                         $scrollview = view.parents( ".ui-scrollview-clip" );
201
202                                 $scrollview.each( function ( i ) {
203                                         if ( $.data( this, "scrollview" ) ) {
204                                                 $( this ).scrollview( "scrollTo", 0, 0 );
205                                         }
206                                 });
207
208                                 // for maintaining page layout
209                                 if ( !option.fullScreen ) {
210                                         $( ".ui-footer:visible" ).show();
211                                 } else {
212                                         $( ".ui-footer" ).hide();
213                                         self._fitContentArea( $page );
214                                 }
215
216                                 self._resize();
217                         });
218                 },
219                 _resize : function () {
220                         var view = this.element,
221                                 parent = view.parent(),
222                                 control = parent.find( ".ui-multimediaview-control" ),
223                                 viewWidth = 0,
224                                 viewHeight = 0,
225                                 viewOffset = null;
226
227                         this._resizeFullscreen( this.options.fullScreen );
228                         viewWidth = ( ( view[0].nodeName === "VIDEO" ) ? view.width() : parent.width() );
229                         viewHeight = ( ( view[0].nodeName === "VIDEO" ) ? view.height() : control.height() );
230                         viewOffset = view.offset();
231
232                         this._resizeControl( viewOffset, viewWidth, viewHeight );
233
234                         this._updateSeekBar();
235                         this._updateVolumeState();
236                 },
237                 _resizeControl : function ( offset, width, height ) {
238                         var self = this,
239                                 view = self.element,
240                                 viewElement = view[0],
241                                 control = view.parent().find( ".ui-multimediaview-control" ),
242                                 buttons = control.find( ".ui-button" ),
243                                 playpauseButton = control.find( ".ui-playpausebutton" ),
244                                 seekBar = control.find( ".ui-seekbar" ),
245                                 durationLabel = control.find( ".ui-durationlabel" ),
246                                 timestampLabel = control.find( ".ui-timestamplabel" ),
247                                 volumeControl = control.find( ".ui-volumecontrol" ),
248                                 volumeBar = volumeControl.find( ".ui-volumebar" ),
249                                 controlWidth = width,
250                                 controlHeight = control.outerHeight( true ),
251                                 availableWidth = 0,
252                                 controlOffset = null;
253
254                         if ( control ) {
255                                 if ( view[0].nodeName === "VIDEO" ) {
256                                         controlOffset = control.offset();
257                                         controlOffset.left = offset.left;
258                                         controlOffset.top = offset.top + height - controlHeight;
259                                         control.offset( controlOffset );
260                                 }
261
262                                 control.width( controlWidth );
263                         }
264
265                         if ( seekBar ) {
266                                 availableWidth = control.width() - ( buttons.outerWidth( true ) * buttons.length );
267                                 availableWidth -= ( parseInt( buttons.eq( 0 ).css( "margin-left" ), 10 ) + parseInt( buttons.eq( 0 ).css( "margin-right" ), 10 ) ) * buttons.length;
268                                 if ( !self.isVolumeHide ) {
269                                         availableWidth -= volumeControl.outerWidth( true );
270                                 }
271                                 seekBar.width( availableWidth );
272                         }
273
274                         if ( durationLabel && !isNaN( viewElement.duration ) ) {
275                                 durationLabel.find( "p" ).text( self._convertTimeFormat( viewElement.duration ) );
276                         }
277
278                         if ( viewElement.autoplay && viewElement.paused === false ) {
279                                 playpauseButton.removeClass( "ui-play-icon" ).addClass( "ui-pause-icon" );
280                         }
281
282                         if ( seekBar.width() < ( volumeBar.width() + timestampLabel.width() + durationLabel.width() ) ) {
283                                 durationLabel.hide();
284                         } else {
285                                 durationLabel.show();
286                         }
287                 },
288                 _resizeFullscreen : function ( isFullscreen ) {
289                         var self = this,
290                                 view = self.element,
291                                 parent = view.parent(),
292                                 control = view.parent().find( ".ui-multimediaview-control" ),
293                                 playpauseButton = control.find( ".ui-playpausebutton" ),
294                                 timestampLabel = control.find( ".ui-timestamplabel" ),
295                                 seekBar = control.find( ".ui-seekbar" ),
296                                 durationBar = seekBar.find( ".ui-duration" ),
297                                 currenttimeBar = seekBar.find( ".ui-currenttime" ),
298                                 docWidth = 0,
299                                 docHeight = 0;
300
301                         if ( isFullscreen ) {
302                                 if ( !self.backupView ) {
303                                         self.backupView = {
304                                                 width : view[0].style.getPropertyValue( "width" ) || "",
305                                                 height : view[0].style.getPropertyValue( "height" ) || "",
306                                                 position : view.css( "position" ),
307                                                 zindex : view.css( "z-index" )
308                                         };
309                                 }
310                                 docWidth = $( "body" )[0].clientWidth;
311                                 docHeight = $( "body" )[0].clientHeight;
312
313                                 view.width( docWidth ).height( docHeight - 1 );
314                                 view.addClass( "ui-" + self.role + "-fullscreen" );
315                                 view.offset( {
316                                         top : 0,
317                                         left : 0
318                                 });
319                         } else {
320                                 if ( !self.backupView ) {
321                                         return;
322                                 }
323
324                                 view.removeClass( "ui-" + self.role + "-fullscreen" );
325                                 view.css( {
326                                         "width" : self.backupView.width,
327                                         "height" : self.backupView.height,
328                                         "position": self.backupView.position,
329                                         "z-index": self.backupView.zindex
330                                 });
331                                 self.backupView = null;
332                         }
333                         parent.show();
334                 },
335                 _addEvent : function () {
336                         var self = this,
337                                 view = self.element,
338                                 viewElement = view[0],
339                                 control = view.parent().find( ".ui-multimediaview-control" ),
340                                 playpauseButton = control.find( ".ui-playpausebutton" ),
341                                 timestampLabel = control.find( ".ui-timestamplabel" ),
342                                 durationLabel = control.find( ".ui-durationlabel" ),
343                                 volumeButton = control.find( ".ui-volumebutton" ),
344                                 volumeControl = control.find( ".ui-volumecontrol" ),
345                                 volumeBar = volumeControl.find( ".ui-volumebar" ),
346                                 volumeGuide = volumeControl.find( ".ui-guide" ),
347                                 volumeHandle = volumeControl.find( ".ui-handler" ),
348                                 fullscreenButton = control.find( ".ui-fullscreenbutton" ),
349                                 seekBar = control.find( ".ui-seekbar" ),
350                                 durationBar = seekBar.find( ".ui-duration" ),
351                                 currenttimeBar = seekBar.find( ".ui-currenttime" );
352
353                         view.bind( "loadedmetadata.multimediaview", function ( e ) {
354                                 if ( !isNaN( viewElement.duration ) ) {
355                                         durationLabel.find( "p" ).text( self._convertTimeFormat( viewElement.duration ) );
356                                 }
357                                 self._resize();
358                         }).bind( "timeupdate.multimediaview", function ( e ) {
359                                 self._updateSeekBar();
360                         }).bind( "play.multimediaview", function ( e ) {
361                                 playpauseButton.removeClass( "ui-play-icon" ).addClass( "ui-pause-icon" );
362                         }).bind( "pause.multimediaview", function ( e ) {
363                                 playpauseButton.removeClass( "ui-pause-icon" ).addClass( "ui-play-icon" );
364                         }).bind( "ended.multimediaview", function ( e ) {
365                                 if ( typeof viewElement.loop == "undefined" || viewElement.loop === "" ) {
366                                         self.stop();
367                                 }
368                         }).bind( "volumechange.multimediaview", function ( e ) {
369                                 if ( viewElement.volume < 0.1 ) {
370                                         viewElement.muted = true;
371                                         volumeButton.removeClass( "ui-volume-icon" ).addClass( "ui-mute-icon" );
372                                 } else {
373                                         viewElement.muted = false;
374                                         volumeButton.removeClass( "ui-mute-icon" ).addClass( "ui-volume-icon" );
375                                 }
376
377                                 if ( !self.isVolumeHide ) {
378                                         self._updateVolumeState();
379                                 }
380                         }).bind( "durationchange.multimediaview", function ( e ) {
381                                 if ( !isNaN( viewElement.duration ) ) {
382                                         durationLabel.find( "p" ).text( self._convertTimeFormat( viewElement.duration ) );
383                                 }
384                                 self._resize();
385                         }).bind( "error.multimediaview", function ( e ) {
386                                 switch ( e.target.error.code ) {
387                                 case e.target.error.MEDIA_ERR_ABORTED :
388                                         window.alert( 'You aborted the video playback.' );
389                                         break;
390                                 case e.target.error.MEDIA_ERR_NETWORK :
391                                         window.alert( 'A network error caused the video download to fail part-way.' );
392                                         break;
393                                 case e.target.error.MEDIA_ERR_DECODE :
394                                         window.alert( 'The video playback was aborted due to a corruption problem or because the video used features your browser did not support.' );
395                                         break;
396                                 case e.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED :
397                                         window.alert( 'The video could not be loaded, either because the server or network failed or because the format is not supported.' );
398                                         break;
399                                 default :
400                                         window.alert( 'An unknown error occurred.' );
401                                         break;
402                                 }
403                         }).bind( "vclick.multimediaview", function ( e ) {
404                                 if ( !self.options.controls ) {
405                                         return;
406                                 }
407
408                                 control.fadeToggle( "fast", function () {
409                                         var offset = control.offset();
410                                         self.isControlHide = !self.isControlHide;
411                                         if ( self.options.mediatype == "video" ) {
412                                                 self._startTimer();
413                                         }
414                                 });
415                                 self._resize();
416                         });
417
418                         playpauseButton.bind( "vclick.multimediaview", function () {
419                                 self._endTimer();
420
421                                 if ( viewElement.paused ) {
422                                         viewElement.play();
423                                 } else {
424                                         viewElement.pause();
425                                 }
426
427                                 if ( self.options.mediatype == "video" ) {
428                                         self._startTimer();
429                                 }
430                         });
431
432                         fullscreenButton.bind( "vclick.multimediaview", function ( e ) {
433                                 self.fullScreen( !self.options.fullScreen );
434                                 control.fadeIn( "fast" );
435                                 self._endTimer();
436                                 e.preventDefault();
437                                 e.stopPropagation();
438                         });
439
440                         seekBar.bind( "vmousedown.multimediaview", function ( e ) {
441                                 var x = e.clientX,
442                                         duration = viewElement.duration,
443                                         durationOffset = durationBar.offset(),
444                                         durationWidth = durationBar.width(),
445                                         timerate = ( x - durationOffset.left ) / durationWidth,
446                                         time = duration * timerate;
447
448                                 viewElement.currentTime = time;
449
450                                 self._endTimer();
451
452                                 e.preventDefault();
453                                 e.stopPropagation();
454
455                                 $( document ).bind( "vmousemove.multimediaview", function ( e ) {
456                                         var x = e.clientX,
457                                                 timerate = ( x - durationOffset.left ) / durationWidth;
458
459                                         viewElement.currentTime = duration * timerate;
460
461                                         e.preventDefault();
462                                         e.stopPropagation();
463                                 }).bind( "vmouseup.multimediaview", function () {
464                                         $( document ).unbind( "vmousemove.multimediaview vmouseup.multimediaview" );
465                                         if ( viewElement.paused ) {
466                                                 viewElement.pause();
467                                         } else {
468                                                 viewElement.play();
469                                         }
470                                 });
471                         });
472
473                         volumeButton.bind( "vclick.multimediaview", function () {
474                                 if ( self.isVolumeHide ) {
475                                         var view = self.element,
476                                                 volume = viewElement.volume;
477
478                                         self.isVolumeHide = false;
479                                         self._resize();
480                                         volumeControl.fadeIn( "fast" );
481                                         self._updateVolumeState();
482                                         self._updateSeekBar();
483                                 } else {
484                                         self.isVolumeHide = true;
485                                         volumeControl.fadeOut( "fast", function () {
486                                                 self._resize();
487                                         });
488                                         self._updateSeekBar();
489                                 }
490                         });
491
492                         volumeBar.bind( "vmousedown.multimediaview", function ( e ) {
493                                 var baseX = e.clientX,
494                                         volumeGuideLeft = volumeGuide.offset().left,
495                                         volumeGuideWidth = volumeGuide.width(),
496                                         volumeBase = volumeGuideLeft + volumeGuideWidth,
497                                         handlerOffset = volumeHandle.offset(),
498                                         volumerate = ( baseX - volumeGuideLeft ) / volumeGuideWidth,
499                                         currentVolume = ( baseX - volumeGuideLeft ) / volumeGuideWidth;
500
501                                 self._endTimer();
502                                 self._setVolume( currentVolume.toFixed( 2 ) );
503
504                                 e.preventDefault();
505                                 e.stopPropagation();
506
507                                 $( document ).bind( "vmousemove.multimediaview", function ( e ) {
508                                         var currentX = e.clientX,
509                                                 currentVolume = ( currentX - volumeGuideLeft ) / volumeGuideWidth;
510
511                                         self._setVolume( currentVolume.toFixed( 2 ) );
512
513                                         e.preventDefault();
514                                         e.stopPropagation();
515                                 }).bind( "vmouseup.multimediaview", function () {
516                                         $( document ).unbind( "vmousemove.multimediaview vmouseup.multimediaview" );
517
518                                         if ( self.options.mediatype == "video" ) {
519                                                 self._startTimer();
520                                         }
521                                 });
522                         });
523                 },
524                 _removeEvent : function () {
525                         var self = this,
526                                 view = self.element,
527                                 control = view.parent().find( ".ui-multimediaview-control" ),
528                                 playpauseButton = control.find( ".ui-playpausebutton" ),
529                                 fullscreenButton = control.find( ".ui-fullscreenbutton" ),
530                                 seekBar = control.find( ".ui-seekbar" ),
531                                 volumeControl = control.find( ".ui-volumecontrol" ),
532                                 volumeBar = volumeControl.find( ".ui-volumebar" ),
533                                 volumeHandle = volumeControl.find( ".ui-handler" );
534
535                         view.unbind( ".multimediaview" );
536                         playpauseButton.unbind( ".multimediaview" );
537                         fullscreenButton.unbind( ".multimediaview" );
538                         seekBar.unbind( ".multimediaview" );
539                         volumeBar.unbind( ".multimediaview" );
540                         volumeHandle.unbind( ".multimediaview" );
541                 },
542                 _createControl : function () {
543                         var self = this,
544                                 view = self.element,
545                                 control = $( "<span></span>" ),
546                                 playpauseButton = $( "<span></span>" ),
547                                 seekBar = $( "<span></span>" ),
548                                 timestampLabel = $( "<span><p>00:00:00</p></span>" ),
549                                 durationLabel = $( "<span><p>00:00:00</p></span>" ),
550                                 volumeButton = $( "<span></span>" ),
551                                 volumeControl = $( "<span></span>" ),
552                                 volumeBar = $( "<div></div>" ),
553                                 volumeGuide = $( "<span></span>" ),
554                                 volumeValue = $( "<span></span>" ),
555                                 volumeHandle = $( "<span></span>" ),
556                                 fullscreenButton = $( "<span></span>" ),
557                                 durationBar = $( "<span></span>" ),
558                                 currenttimeBar = $( "<span></span>" );
559
560                         control.addClass( "ui-" + self.role + "-control" );
561                         playpauseButton.addClass( "ui-playpausebutton ui-button" );
562                         seekBar.addClass( "ui-seekbar" );
563                         timestampLabel.addClass( "ui-timestamplabel" );
564                         durationLabel.addClass( "ui-durationlabel" );
565                         volumeButton.addClass( "ui-volumebutton ui-button" );
566                         fullscreenButton.addClass( "ui-fullscreenbutton ui-button" );
567                         durationBar.addClass( "ui-duration" );
568                         currenttimeBar.addClass( "ui-currenttime" );
569                         volumeControl.addClass( "ui-volumecontrol" );
570                         volumeBar.addClass( "ui-volumebar" );
571                         volumeGuide.addClass( "ui-guide" );
572                         volumeValue.addClass( "ui-value" );
573                         volumeHandle.addClass( "ui-handler" );
574
575                         seekBar.append( durationBar ).append( currenttimeBar ).append( durationLabel ).append( timestampLabel );
576
577                         playpauseButton.addClass( "ui-play-icon" );
578                         if ( view[0].muted ) {
579                                 $( volumeButton ).addClass( "ui-mute-icon" );
580                         } else {
581                                 $( volumeButton ).addClass( "ui-volume-icon" );
582                         }
583
584                         volumeBar.append( volumeGuide ).append( volumeValue ).append( volumeHandle );
585                         volumeControl.append( volumeBar );
586
587                         control.append( playpauseButton ).append( seekBar ).append( volumeControl ).append( volumeButton );
588
589                         if ( self.element[0].nodeName === "VIDEO" ) {
590                                 $( fullscreenButton ).addClass( "ui-fullscreen-on" );
591                                 control.append( fullscreenButton );
592                         }
593                         volumeControl.hide();
594
595                         return control;
596                 },
597                 _startTimer : function ( duration ) {
598                         this._endTimer();
599
600                         if ( !duration ) {
601                                 duration = 3000;
602                         }
603
604                         var self = this,
605                                 view = self.element,
606                                 control = view.parent().find( ".ui-multimediaview-control" ),
607                                 volumeControl = control.find( ".ui-volumecontrol" );
608
609                         self.controlTimer = setTimeout( function () {
610                                 self.isVolumeHide = true;
611                                 self.isControlHide = true;
612                                 self.controlTimer = null;
613                                 volumeControl.hide();
614                                 control.fadeOut( "fast" );
615                         }, duration );
616                 },
617                 _endTimer : function () {
618                         if ( this.controlTimer ) {
619                                 clearTimeout( this.controlTimer );
620                                 this.controlTimer = null;
621                         }
622                 },
623                 _convertTimeFormat : function ( systime ) {
624                         var ss = parseInt( systime % 60, 10 ).toString(),
625                                 mm = parseInt( ( systime / 60 ) % 60, 10 ).toString(),
626                                 hh = parseInt( systime / 3600, 10 ).toString(),
627                                 time =  ( ( hh.length < 2  ) ? "0" + hh : hh ) + ":" +
628                                                 ( ( mm.length < 2  ) ? "0" + mm : mm ) + ":" +
629                                                 ( ( ss.length < 2  ) ? "0" + ss : ss );
630
631                         return time;
632                 },
633                 _updateSeekBar : function ( currenttime ) {
634                         var self = this,
635                                 view = self.element,
636                                 duration = view[0].duration,
637                                 control = view.parent().find( ".ui-multimediaview-control" ),
638                                 seekBar = control.find(  ".ui-seekbar"  ),
639                                 durationBar = seekBar.find( ".ui-duration" ),
640                                 currenttimeBar = seekBar.find( ".ui-currenttime" ),
641                                 timestampLabel = control.find( ".ui-timestamplabel" ),
642                                 durationOffset = durationBar.offset(),
643                                 durationWidth = durationBar.width(),
644                                 durationHeight = durationBar.height(),
645                                 timebarWidth = 0;
646
647                         if ( typeof currenttime == "undefined" ) {
648                                 currenttime = view[0].currentTime;
649                         }
650                         timebarWidth = parseInt( currenttime / duration * durationWidth, 10 );
651                         durationBar.offset( durationOffset );
652                         currenttimeBar.offset( durationOffset ).width( timebarWidth );
653                         timestampLabel.find( "p" ).text( self._convertTimeFormat( currenttime ) );
654                 },
655                 _updateVolumeState : function () {
656                         var self = this,
657                                 view = self.element,
658                                 control = view.parent().find( ".ui-multimediaview-control" ),
659                                 volumeControl = control.find( ".ui-volumecontrol" ),
660                                 volumeButton = control.find( ".ui-volumebutton" ),
661                                 volumeBar = volumeControl.find( ".ui-volumebar" ),
662                                 volumeGuide = volumeControl.find( ".ui-guide" ),
663                                 volumeValue = volumeControl.find( ".ui-value" ),
664                                 volumeHandle = volumeControl.find( ".ui-handler" ),
665                                 handlerWidth = volumeHandle.width(),
666                                 handlerHeight = volumeHandle.height(),
667                                 volumeGuideHeight = volumeGuide.height(),
668                                 volumeGuideWidth = volumeGuide.width(),
669                                 volumeGuideTop = 0,
670                                 volumeGuideLeft = 0,
671                                 volumeBase = 0,
672                                 handlerOffset = null,
673                                 volume = view[0].volume;
674
675                         volumeGuideTop = parseInt( volumeGuide.offset().top, 10 );
676                         volumeGuideLeft = parseInt( volumeGuide.offset().left, 10 );
677                         volumeBase = volumeGuideLeft;
678                         handlerOffset = volumeHandle.offset();
679                         handlerOffset.top = volumeGuideTop - parseInt( ( handlerHeight - volumeGuideHeight ) / 2, 10 );
680                         handlerOffset.left = volumeBase + parseInt( volumeGuideWidth * volume, 10 ) - parseInt( handlerWidth / 2, 10 );
681                         volumeHandle.offset( handlerOffset );
682                         volumeValue.width( parseInt( volumeGuideWidth * ( volume ), 10 ) );
683                 },
684                 _setVolume : function ( value ) {
685                         var viewElement = this.element[0];
686
687                         if ( value < 0.0 || value > 1.0 ) {
688                                 return;
689                         }
690
691                         viewElement.volume = value;
692                 },
693                 _fitContentArea: function ( page, parent ) {
694                         if ( typeof parent == "undefined" ) {
695                                 parent = window;
696                         }
697
698                         var $page = $( page ),
699                                 $content = $( ".ui-content:visible:first" ),
700                                 hh = $( ".ui-header:visible" ).outerHeight() || 0,
701                                 fh = $( ".ui-footer:visible" ).outerHeight() || 0,
702                                 pt = parseFloat( $content.css( "padding-top" ) ),
703                                 pb = parseFloat( $content.css( "padding-bottom" ) ),
704                                 wh = ( ( parent === window ) ? window.innerHeight : $( parent ).height() ),
705                                 height = wh - ( hh + fh ) - ( pt + pb );
706
707                         $content.offset( {
708                                 top : ( hh + pt )
709                         }).height( height );
710                 },
711                 width : function ( value ) {
712                         var self = this,
713                                 args = arguments,
714                                 view = self.element;
715
716                         if ( args.length === 0 ) {
717                                 return view.width();
718                         }
719                         if ( args.length === 1 ) {
720                                 view.width( value );
721                                 self._resize();
722                         }
723                 },
724                 height : function ( value ) {
725                         var self = this,
726                                 view = self.element,
727                                 args = arguments;
728
729                         if ( args.length === 0 ) {
730                                 return view.height();
731                         }
732                         if ( args.length === 1 ) {
733                                 view.height( value );
734                                 self._resize();
735                         }
736                 },
737                 fullScreen : function ( value ) {
738                         var self = this,
739                                 view = self.element,
740                                 control = view.parent().find( ".ui-multimediaview-control" ),
741                                 fullscreenButton = control.find( ".ui-fullscreenbutton" ),
742                                 args = arguments,
743                                 option = self.options,
744                                 currentPage = $( ".ui-page-active" );
745
746                         if ( args.length === 0 ) {
747                                 return option.fullScreen;
748                         }
749                         if ( args.length === 1 ) {
750                                 view.parents( ".ui-content" ).scrollview( "scrollTo", 0, 0 );
751
752                                 this.options.fullScreen = value;
753                                 if ( value ) {
754                                         currentPage.children( ".ui-header" ).hide();
755                                         currentPage.children( ".ui-footer" ).hide();
756                                         this._fitContentArea( currentPage );
757                                         fullscreenButton.removeClass( "ui-fullscreen-on" ).addClass( "ui-fullscreen-off" );
758                                 } else {
759                                         currentPage.children( ".ui-header" ).show();
760                                         currentPage.children( ".ui-footer" ).show();
761                                         this._fitContentArea( currentPage );
762                                         fullscreenButton.removeClass( "ui-fullscreen-off" ).addClass( "ui-fullscreen-on" );
763                                 }
764                                 self._resize();
765                         }
766                 },
767                 refresh : function () {
768                         this._resize();
769                 }
770         });
771
772         $( document ).bind( "pagecreate create", function ( e ) {
773                 $.tizen.multimediaview.prototype.enhanceWithin( e.target );
774         });
775 } ( jQuery, document, window ) );