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