[TemporaryStorage] add files required for SDK build
[samples/web/TemporaryStorage.git] / tizen-web-ui-fw / latest / js / src / widgets / jquery.mobile.tizen.splitview.js
1
2 /* ***************************************************************************
3  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  * ***************************************************************************
23  *
24  *  Author: Sanghee Lee <sang-hee.lee@samsung.com>
25 */
26
27 /**
28  *  Splitview is a widget which can show different HTML contents at the same time on each divided pane.
29  *  A user can place Splitview controls on JQuery Mobile's Content area and arrange two panes on the widget.
30  *  And HTML fragments or another Splitview also can be placed on the pane.
31  *  The number of panes inside of Splitview is restricted as two.
32  *  If a user define only one pane in Splitview, a empty pane will be added automatically,
33  *  on the other hand, if 3 or more panes are defined in Splitview, the panes after two will be ignored and removed from the DOM tree.
34  *  The HTML fragments of a pane should be composed of elements describing a part of Web page (e.g. <div>...</div>).
35  *  Also widgets can be included in the HTML fragments.
36  *
37  *  HTML Attributes:
38  *
39  *      data-fixed : The resizing mode of panes - fixed and flexible mode.
40  *              If the value is true, the panes' sizes will be fixed, or if not, it will be flexible. (Default : false)
41  *      data-divider-vertical : The direction of dividers.
42  *              If the value is true, the panes will be placed in horizontal direction,
43  *              or if not, it will be placed in vertical direction. (Default : "true")
44  *      data-ratio : The ratio of two panes' widths or heights. (Default : [ 1/2, 1/2 ]
45  *
46  *  APIs:
47  *
48  *      pane ( id [ , element ] )
49  *          : This method replaces child contents of a pane indicated by id attribute with contents of inputted element.
50  *            If second argument is not specified, it will act as a getter method.
51  *            The string of id has to be started with "#" which means "id" of CSS selectors.
52  *      maximize ( id )
53  *          : This method maximizes a pane's size indicated by id.
54  *            The string of id has to be started with "#" which means "id" of CSS selectors.
55  *      restore ()
56  *          : This method restores all panes' sizes to the ratio prior to maximization.
57  *
58  *  Examples:
59  *
60  *      <div data-role="splitview" data-fixed="false" data-divider-vertical="true" data-ratio="0.5, 0.5">
61  *          <div class="ui-pane">pane0</div>
62  *          <div class="ui-pane">pane1</div>
63  *      </div>
64  *
65  */
66
67
68 /**
69         @class Splitview
70         Splitview widget enables a user to place and arrange several panes. Each divided pane can show repective HTML contents.
71
72         To add a Splitview widget to the application, use the following code:
73
74                 <div data-role="splitview" data-fixed="false" data-divider-vertical="true" data-ratio="0.5, 0.5">
75                         <div class="ui-pane">pane0</div>
76                         <div class="ui-pane">pane1</div>
77                 </div>
78 */
79
80 /**
81         @property {Boolean} data-fixed
82         The resizing mode of panes - fixed and flexible mode.
83 */
84
85 /**
86         @property {Boolean} data-divider-vertical
87         The direction of dividers - horizontal or vertical.
88  */
89
90 /**
91         @property {Array} data-ratio
92         The ratio of two panes' widths or heights.
93 */
94
95 /**
96         @method pane
97         This method replaces child contents of a pane indicated by id attribute with contents of inputted element.
98         If second argument is not specified, it will act as a getter method.
99
100                 <div data-role="splitview">
101                         <div class="ui-pane" id="pane0">pane0</div>
102                         <div class="ui-pane" id="pane1">pane1</div>
103                 </div>
104                 $(".selector").splitview("pane", id, element);
105 */
106
107 /**
108         @method maximize
109         This method maximizes a pane's size indicated by id.
110
111                 <div data-role="splitview">
112                         <div class="ui-pane" id="pane0">pane0</div>
113                         <div class="ui-pane" id="pane1">pane1</div>
114                 </div>
115                 $(".selector").splitview("maximize", id);
116 */
117
118 /**
119         @method restore
120         This method restores all panes' sizes to the ratio prior to maximization.
121
122                 <div data-role="splitview">
123                         <div class="ui-pane" id="pane0">pane0</div>
124                         <div class="ui-pane" id="pane1">pane1</div>
125                 </div>
126                 $(".selector").splitview("restore");
127 */
128
129 ( function ( $, window, document, undefined ) {
130         $.widget( "tizen.splitview", $.mobile.widget, {
131                 options : {
132                         fixed : false,
133                         dividerVertical : true,
134                         ratio : [],
135                         initSelector : ":jqmData(role='splitview')"
136                 },
137
138                 _create : function () {
139                         var self = this,
140                                 $el = self.element,
141                                 opt = self.options,
142                                 $panes = $el.children( ".ui-pane" ),
143                                 panesLength = $panes.length,
144                                 spliters = [],
145                                 spliterBars = [],
146                                 ratioAttr = this.element.attr( "data-ratio" ),
147                                 containerSize = [ 0, 0 ],
148                                 resizeTimer = null,
149                                 i = 0;
150
151                         if ( panesLength !== 2 ) {
152                                 if ( panesLength < 2 ) {
153                                         for ( i = panesLength ; i < 2 ; ++i ) {
154                                                 self._addEmptyPanes();
155                                         }
156                                 } else {
157                                         $panes.slice( 2 ).remove();
158                                 }
159
160                                 $panes = $el.children( ".ui-pane" );
161                                 panesLength = $panes.length;
162                         }
163
164                         spliters[ 0 ] = $( "<a href='#' class='ui-spliter' aria-label='Drag scroll, double tap and move to adjust split area'></a>" ).insertAfter( $panes[ 0 ] );
165                         spliterBars[ 0 ] = $( "<div class='ui-spliter-bar'></div>" ).appendTo( spliters[ 0 ] );
166                         $( "<div class='ui-spliter-handle'></div>" ).appendTo( spliterBars[ 0 ] );
167
168                         $.extend( this, {
169                                 moveTarget : null,
170                                 moveData : {},
171                                 spliters : spliters,
172                                 spliterBars : spliterBars,
173                                 panes : $panes,
174                                 containerSize : containerSize,
175                                 touchStatus : false,
176                                 minPaneWidth : 50,
177                                 savedRatio : []
178                         });
179
180                         self._bindTouchEvents();
181                         self._convertRatio( ratioAttr, $panes.length );
182
183                         $el.addClass( "ui-splitview ui-direction-" + self._direction( opt.dividerVertical ) );
184
185                         self._refresh();
186
187                         $( window ).unbind( ".splitview" )
188                                 .bind( "pagechange.splitview resize.splitview", function ( event ) {
189                                         $( ".ui-page-active .ui-splitview" ).each( function () {
190                                                 $( this ).data( "splitview" )._refresh();
191                                         });
192                                 });
193                 },
194
195                 _addEmptyPanes : function () {
196                         var self = this,
197                                 $el = self.element,
198                                 opt = self.options,
199                                 $panes = $el.children( ".ui-pane" ),
200                                 scrollAttribute = ( $.support.scrollview ) ? "data-scroll='y'" : "",
201                                 pane = $( "<div class='ui-pane' " + scrollAttribute + "></div>" );
202
203                         if ( scrollAttribute.length ) {
204                                 pane.scrollview( { direction: "y" } );
205                         }
206
207                         if ( !$panes.length ) {
208                                 $el.append( pane );
209                         } else {
210                                 $panes.last().after( pane );
211                         }
212                 },
213
214                 _direction : function ( isHorizontal ) {
215                         return isHorizontal ? "horizontal" : "vertical";
216                 },
217
218                 _isStyleSpecified : function ( cssString ) {
219                         return ( typeof cssString !== "undefined" && cssString.length );
220                 },
221
222                 _getContainerSize : function ( widthString, heightString ) {
223                         var self = this,
224                                 $el = self.element,
225                                 widthSpecified = self._isStyleSpecified( widthString ),
226                                 heightSpecified = self._isStyleSpecified( heightString );
227
228                         self.containerSize[ 0 ] = ( widthSpecified ) ? $el.outerWidth( true ) : self._parentWidth();
229                         self.containerSize[ 1 ] = ( heightSpecified ) ? $el.outerHeight( true ) : self._parentHeight();
230
231                         if ( !self.containerSize[ 0 ] || !self.containerSize[ 1 ] ) {
232                                 return false;
233                         }
234
235                         return true;
236                 },
237
238                 _parentWidth : function () {
239                         var $parent = this.element.parent();
240
241                         if ( !$parent && typeof $parent === "undefined" && !$parent.length ) {
242                                 return $( window ).width();
243                         }
244
245                         return $parent.width();
246                 },
247
248                 _parentHeight : function () {
249                         var $parent = this.element.parent(),
250                                 heightString = "",
251                                 heightSpecified = false,
252                                 parentHeight = 0;
253
254                         while ( $parent && typeof $parent !== "undefined" && $parent.length ) {
255                                 if ( typeof $parent[ 0 ].style !== "undefined" ) {
256                                         heightString = $parent[ 0 ].style.height;
257                                         heightSpecified = ( typeof heightString !== "undefined" && heightString.length );
258                                         if ( heightSpecified ) {
259                                                 parentHeight = $parent.height();
260                                                 break;
261                                         }
262                                 }
263
264                                 $parent = $parent.parent();
265                         }
266
267                         if ( !heightSpecified ) {
268                                 parentHeight = $(window).height();
269                         }
270
271                         return parentHeight;
272                 },
273
274                 _convertRatio : function ( ratioParam, panesLength ) {
275                         var self = this,
276                                 ratio = [],
277                                 loop = 0,
278                                 type = typeof ratioParam,
279                                 ratioArray = null,
280                                 i;
281
282                         for ( i = 0; i < panesLength; ++i ) {
283                                 ratio.push( 0 );
284                         }
285
286                         switch ( type ) {
287                         case "number":
288                                 if ( panesLength ) {
289                                         ratio[ 0 ] = ratioParam;
290                                 }
291                                 break;
292
293                         case "string":
294                                 ratioArray = ratioParam.split( "," );
295                                 loop = Math.min( ratioArray.length, panesLength );
296                                 for ( i = 0; i < loop; ++i ) {
297                                         ratio[ i ] = parseFloat( ratioArray[ i ] );
298                                 }
299                                 break;
300
301                         case "object":
302                                 if ( !$.isArray( ratioParam ) ) {
303                                         break;
304                                 }
305
306                                 loop = Math.min( ratioParam.length, panesLength );
307                                 for ( i = 0; i < loop; ++i ) {
308                                         type = typeof ratioParam[ i ];
309                                         ratio[ i ] = ( type === "string" ) ? parseFloat( ratioParam[ i ] ) :
310                                                                 ( type === "number" ) ? ratioParam[ i ] : 0;
311                                 }
312                                 break;
313                         }
314
315                         self.options.ratio = ratio;
316                         self._adjustRatio( panesLength );
317                 },
318
319                 _adjustRatio : function ( panesLength ) {
320                         var self = this,
321                                 ratio = self.options.ratio,
322                                 sum = 0,
323                                 remain = 0,
324                                 value = 0,
325                                 subValue = 0,
326                                 subRemain = 0,
327                                 i;
328
329                         if ( !panesLength ) {
330                                 self.options.ratio = [];
331                                 return;
332                         }
333
334                         for ( i in ratio ) {
335                                 sum += ratio[ i ];
336                         }
337
338                         if ( sum !== 1 ) {
339                                 remain = 1 - sum;
340                                 value = remain / panesLength;
341
342                                 for ( i in ratio ) {
343                                         if ( value >= 0 ) {
344                                                 ratio[ i ] += value;
345                                                 remain = Math.max( 0, remain - value );
346                                         } else {
347                                                 subRemain += value;
348                                                 subValue = Math.max( subRemain, ratio[ i ] * -1 );
349                                                 ratio[ i ] = Math.max( 0, ratio[ i ] + subValue );
350                                                 remain = Math.min( 0, remain - subValue );
351                                                 subRemain -= subValue;
352                                         }
353                                 }
354
355                                 if ( remain ) {
356                                         if ( remain > 0 ) {
357                                                 ratio[ ratio.length - 1 ] += remain;
358                                         } else {
359                                                 for ( i = ratio.length - 1; i >= 0; --i ) {
360                                                         subValue = Math.max( remain, ratio[ i ] * -1 );
361                                                         ratio[ i ] = Math.max( 0, ratio[ i ] + subValue );
362                                                         remain = Math.min( 0, remain - subValue );
363                                                         if ( !remain ) {
364                                                                 break;
365                                                         }
366                                                 }
367                                         }
368                                 }
369
370                                 self.options.ratio = ratio;
371                         }
372                 },
373
374                 _setOption : function ( key, value ) {
375                         var self = this,
376                                 orgValue = self.options[ key ];
377
378                         if ( orgValue === value ) {
379                                 return;
380                         }
381
382                         $.Widget.prototype._setOption.apply( this, arguments );
383
384                         switch ( key ) {
385                         case "fixed":
386                                 self._fixed( value );
387                                 break;
388
389                         case "dividerVertical":
390                                 self._dividerVertical( value );
391                                 break;
392
393                         case "ratio":
394                                 self._ratio( value );
395                                 break;
396                         }
397                 },
398
399                 _subtractDiffWidth : function ( width, diff ) {
400                         var self = this;
401
402                         if ( width <= self.minPaneWidth ) {
403                                 return {
404                                         width: width,
405                                         diff: diff
406                                 };
407                         }
408
409                         width += diff;
410                         if ( width >= self.minPaneWidth ) {
411                                 return {
412                                         width: width,
413                                         diff: 0
414                                 };
415                         }
416
417                         return {
418                                 width: self.minPaneWidth,
419                                 diff: width - self.minPaneWidth
420                         };
421                 },
422
423                 _initRatio : function ( fromFirstPane, panes, isHorizontal, availableWidth ) {
424                         var self = this,
425                                 sum = 0,
426                                 widths = [],
427                                 diff = 0,
428                                 panesLength = panes.length,
429                                 ret,
430                                 i;
431
432                         panes.each( function ( i ) {
433                                 var pane = $( this );
434                                 widths.push( isHorizontal ? pane.width() : pane.height() );
435                                 sum += widths[ i ];
436                         });
437
438                         diff = availableWidth - sum;
439                         if ( !diff ) {
440                                 return widths;
441                         }
442
443                         if ( diff > 0 ) {
444                                 widths[ fromFirstPane ? 0 : panesLength - 1 ] += diff;
445                         } else {
446                                 if ( fromFirstPane ) {
447                                         for ( i = 0; i < panesLength; ++i ) {
448                                                 ret = self._subtractDiffWidth( widths[ i ], diff );
449                                                 widths[ i ] = ret.width;
450                                                 diff = ret.diff;
451                                                 if ( !diff ) {
452                                                         break;
453                                                 }
454                                         }
455                                 } else {
456                                         for ( i = panesLength - 1; i >= 0; --i ) {
457                                                 diff = self._subtractDiffWidth( widths[ i ], diff );
458                                                 widths[ i ] = ret.width;
459                                                 diff = ret.diff;
460                                                 if ( !diff ) {
461                                                         break;
462                                                 }
463                                         }
464                                 }
465                         }
466
467                         sum = 0;
468                         for ( i in widths ) {
469                                 sum += widths[ i ];
470                         }
471
472                         for ( i in self.options.ratio ) {
473                                 self.options.ratio[ i ] = widths[ i ] / sum;
474                         }
475
476                         return widths;
477                 },
478
479                 _horizontalBoundary : function () {
480                         var self = this,
481                                 $el = self.element;
482
483                         return $el.outerWidth( true ) - $el.width();
484                 },
485
486                 _verticalBoundary : function () {
487                         var self = this,
488                                 $el = self.element;
489
490                         return $el.outerHeight( true ) - $el.height();
491                 },
492
493                 _boundary : function ( type ) {
494                         var self = this,
495                                 $el = self.element,
496                                 computedStyle = window.getComputedStyle( $el[ 0 ], null ),
497                                 margin = parseFloat( computedStyle[ "margin" + type ] ),
498                                 border = parseFloat( computedStyle[ "border" + type + "Width" ] ),
499                                 padding = parseFloat( computedStyle[ "padding" + type ] );
500
501                         return {
502                                 margin: margin,
503                                 border: border,
504                                 padding: padding
505                         };
506                 },
507
508                 _layout : function ( initRatio, fromFirstPane ) {
509                         var self = this,
510                                 $el = self.element,
511                                 opt = self.options,
512                                 isHorizontal = opt.dividerVertical,
513                                 $panes = self.panes,
514                                 spliters = self.spliters,
515                                 spliterBars = self.spliterBars,
516                                 spliterBar = self.spliterBars.length ? $( spliterBars[ 0 ] ) : null,
517                                 spliterWidth = !spliterBar ? 0 :
518                                                                 isHorizontal ? spliterBar.outerWidth() :
519                                                                                                 spliterBar.outerHeight(),
520                                 spliterBarMargin = !spliterBar ? 0 :
521                                                                         isHorizontal ?
522                                                                                 spliterBar.outerWidth( true ) - spliterBar.outerWidth() :
523                                                                                 spliterBar.outerHeight( true ) - spliterBar.outerHeight(),
524                                 panesLength = $panes.length,
525                                 currentAvailable = 0,
526                                 spliterSize = spliterWidth * ( panesLength - 1 ),
527                                 parentWidth = self.containerSize[ 0 ],
528                                 parentHeight = self.containerSize[ 1 ],
529                                 width = parentWidth - self._horizontalBoundary(),
530                                 height = parentHeight - self._verticalBoundary(),
531                                 innerSize = isHorizontal ? height : width,
532                                 availableWidth = isHorizontal ? width - spliterSize :
533                                                                                                 height - spliterSize,
534                                 initializedWidth = [],
535                                 widthSum = 0,
536                                 childSplitview = null;
537
538                         initRatio = !!initRatio;
539                         fromFirstPane = !!fromFirstPane;
540
541                         $el.css( {
542                                 "min-width" : width,
543                                 "min-height" : height
544                         });
545
546                         if ( initRatio ) {
547                                 initializedWidth = self._initRatio( fromFirstPane, $panes, isHorizontal, availableWidth );
548                         }
549
550                         currentAvailable = availableWidth;
551                         $panes.each( function ( i ) {
552                                 var $pane = $( this ),
553                                         paneWidth = initRatio ? initializedWidth[ i ] :
554                                                                                 Math.floor( availableWidth * self.options.ratio[i] ),
555                                         prevPane = ( ( i ) ? $panes.eq( i - 1 ) : null ),
556                                         posValue = 0,
557                                         widthValue = 0,
558                                         heightValue = 0,
559                                         boundary = 0;
560
561                                 currentAvailable -= paneWidth;
562                                 if ( i === ( panesLength - 1 ) ) {
563                                         paneWidth = Math.max( Math.min( paneWidth, self.minPaneWidth ), paneWidth + currentAvailable );
564                                 }
565
566                                 widthSum += paneWidth;
567
568                                 if ( !prevPane ) {
569                                         boundary = self._boundary( isHorizontal ? "Left" : "Top" );
570                                         posValue = boundary.padding;
571                                 } else {
572                                         posValue = parseInt( prevPane.css( isHorizontal ? "left" : "top" ), 10 );
573                                         posValue += isHorizontal ? prevPane.width() : prevPane.height();
574                                         posValue += spliterWidth;
575                                 }
576
577                                 widthValue = isHorizontal ? paneWidth : innerSize;
578                                 heightValue = isHorizontal ? innerSize : paneWidth;
579
580                                 $pane.css( {
581                                         "width" : widthValue ,
582                                         "height" : heightValue
583                                 } );
584
585                                 $pane.css( ( isHorizontal ? "left" : "top" ), posValue );
586                         });
587
588                         $panes.each( function ( i ) {
589                                 var $pane = $( this ),
590                                         paneWidth = isHorizontal ? $pane.width() : $pane.height();
591
592                                 self.options.ratio[ i ] = paneWidth / widthSum;
593                         });
594
595                         $.each( spliters, function ( i ) {
596                                 var spliter = $( this ),
597                                         prevPane = $panes.eq( i ),
598                                         bar = spliter.children( ".ui-spliter-bar" ),
599                                         handle = bar.children( ".ui-spliter-handle" ),
600                                         posValue = 0;
601
602                                 if ( isHorizontal ) {
603                                         posValue = parseInt( prevPane.css( "left" ), 10 ) + prevPane.width() - spliterBarMargin;
604                                         spliter.outerHeight( innerSize ).css( "left", posValue );
605                                 } else {
606                                         posValue = parseInt( prevPane.css( "top" ), 10 ) + prevPane.height() - spliterBarMargin;
607                                         spliter.outerWidth( innerSize ).css( "top", posValue );
608                                 }
609
610                                 if ( bar.length ) {
611                                         bar[ isHorizontal ? "outerHeight" : "outerWidth" ]( innerSize );
612                                 }
613                                 if ( handle.length ) {
614                                         handle.css( isHorizontal ? "top" : "left", ( innerSize - spliterWidth ) / 2 );
615                                 }
616                         });
617
618                         childSplitview = $el.find( ".ui-splitview:first" );
619                         if ( !childSplitview.length ) {
620                                 return;
621                         }
622
623                         childSplitview = childSplitview.data( "splitview" );
624                         if ( childSplitview ) {
625                                 childSplitview._refresh();
626                         }
627                 },
628
629                 _bindTouchEvents : function () {
630                         var self = this,
631                                 $el = self.element,
632                                 $panes = self.panes,
633                                 spliters = self.spliters;
634
635                         $.each( spliters, function ( i ) {
636                                 var spliter = $( this );
637                                 self._bindSpliterTouchEvents.call( self, spliter );
638                         });
639                 },
640
641                 _bindSpliterTouchEvents : function ( spliter ) {
642                         var self = this,
643                                 $el = self.element,
644                                 opt = self.options,
645                                 touchStartEvt = ( $.support.touch ? "touchstart" : "mousedown" ),
646                                 touchMoveEvt = ( $.support.touch ? "touchmove" : "mousemove" ) + ".splitview",
647                                 touchEndEvt = ( $.support.touch ? "touchend" : "mouseup" ) + ".splitview";
648
649                         spliter.bind( touchStartEvt, { e : spliter }, function ( event ) {
650                                 if ( self.options.fixed ) {
651                                         return;
652                                 }
653
654                                 var realEvent = $.support.touch ? event.originalEvent.changedTouches[0] : event,
655                                         targetSpliter = event.data.e,
656                                         prevPane = targetSpliter.prev(),
657                                         nextPane = targetSpliter.next(),
658                                         splitviewInPrev = prevPane.find( ".ui-splitview:first" ),
659                                         splitviewInNext = nextPane.find( ".ui-splitview:first" ),
660                                         isHorizontal = opt.dividerVertical,
661                                         spliterWidth = isHorizontal ?
662                                                                         $( self.spliterBars[0] ).outerWidth() :
663                                                                         $( self.spliterBars[0] ).outerHeight();
664
665                                 self.moveTarget = targetSpliter;
666                                 self.moveData = {
667                                         spliterWidth : spliterWidth || 0,
668                                         prevPane : prevPane,
669                                         nextPane : nextPane,
670                                         splitviewInPrev : splitviewInPrev,
671                                         splitviewInNext : splitviewInNext,
672                                         prevPanePos : parseInt( prevPane.css( isHorizontal ? "left" : "top" ), 10 ) || 0,
673                                         prevPaneWidth : parseInt( prevPane.css( isHorizontal ? "width" : "height" ), 10 ) || 0,
674                                         nextPanePos : parseInt( nextPane.css( isHorizontal ? "left" : "top" ), 10 ) || 0,
675                                         nextPaneWidth : parseInt( nextPane.css( isHorizontal ? "width" : "height" ), 10 ) || 0,
676                                         targetPos : parseInt( targetSpliter.css( isHorizontal ? "left" : "top" ), 10 ) || 0,
677                                         pagePos : isHorizontal ? realEvent.pageX : realEvent.pageY
678                                 };
679
680                                 targetSpliter.addClass( "ui-spliter-active" );
681
682                                 $el.bind( touchMoveEvt, function ( event ) {
683                                         if ( !self.touchStatus ) {
684                                                 return;
685                                         }
686                                         event.stopPropagation();
687                                         self._drag( $.support.touch ? event.originalEvent.changedTouches[0] : event );
688                                 }).bind( touchEndEvt, function ( event ) {
689                                         event.stopPropagation();
690                                         self._stop( $.support.touch ? event.originalEvent.changedTouches[0] : event );
691                                         self.touchStatus = false;
692                                         $el.unbind( ".splitview" );
693                                         $( document ).unbind( ".splitview" );
694                                 });
695
696                                 $( document ).bind( touchMoveEvt + " " + touchEndEvt, function() {
697                                         $el.trigger( touchEndEvt );
698                                 });
699
700                                 event.preventDefault();
701                                 self.touchStatus = true;
702                         });
703                 },
704
705                 _drag : function ( e ) {
706                         if ( !this.moveData || typeof this.moveData === "undefined" ) {
707                                 return;
708                         }
709
710                         var self = this,
711                                 $el = self.element,
712                                 opt = self.options,
713                                 isHorizontal = opt.dividerVertical,
714                                 moveData = self.moveData,
715                                 moveTarget = self.moveTarget,
716                                 prevPane = moveData.prevPane,
717                                 nextPane = moveData.nextPane,
718                                 splitviewInPrev = moveData.splitviewInPrev,
719                                 splitviewInNext = moveData.splitviewInNext,
720                                 spliterWidth = moveData.spliterWidth,
721                                 movement = null,
722                                 targetPos = null,
723                                 nextPanePos = null,
724                                 prevPaneWidth = null,
725                                 nextPaneWidth = null,
726                                 pagePos = isHorizontal ? e.pageX : e.pageY,
727                                 splitview = null;
728
729                         movement = pagePos - moveData.pagePos;
730                         if ( movement > 0 ) {
731                                 movement = Math.min( Math.max( moveData.nextPaneWidth - self.minPaneWidth, 0 ), movement );
732                         } else {
733                                 movement = Math.max( Math.max( moveData.prevPaneWidth - self.minPaneWidth, 0 ) * -1, movement );
734                         }
735
736                         nextPanePos = moveData.nextPanePos + movement;
737                         prevPaneWidth = Math.max( moveData.prevPaneWidth + movement, 0 );
738                         nextPaneWidth = Math.max( moveData.nextPaneWidth - movement, 0 );
739                         targetPos = moveData.targetPos + movement;
740
741                         moveTarget.css( isHorizontal ? { left : targetPos } : { top : targetPos } );
742                         prevPane.css( isHorizontal ? { width : prevPaneWidth } : { height : prevPaneWidth } );
743                         nextPane.css( isHorizontal ? { width : nextPaneWidth, left : nextPanePos } :
744                                                                                         { height : nextPaneWidth, top : nextPanePos } );
745
746                         if ( splitviewInPrev.length ) {
747                                 splitview = splitviewInPrev.data( "splitview" );
748                                 splitview._refresh( true, false );
749                         }
750
751                         if ( splitviewInNext.length ) {
752                                 splitview = splitviewInNext.data( "splitview" );
753                                 splitview._refresh( true, true );
754                         }
755                 },
756
757                 _stop : function ( e ) {
758                         if ( !this.moveData || !this.moveTarget ) {
759                                 return;
760                         }
761
762                         var self = this,
763                                 $el = self.element,
764                                 opt = self.options,
765                                 $panes = self.panes,
766                                 panesLength = $panes.length,
767                                 isHorizontal = opt.dividerVertical,
768                                 moveData = self.moveData,
769                                 moveTarget = self.moveTarget,
770                                 prevPane = moveData.prevPane,
771                                 nextPane = moveData.nextPane,
772                                 splitviewInPrev = moveData.splitviewInPrev,
773                                 splitviewInNext = moveData.splitviewInNext,
774                                 spliterWidth = moveData.spliterWidth,
775                                 spliterSize = spliterWidth * ( panesLength - 1 ),
776                                 movement = null,
777                                 targetPos = null,
778                                 nextPanePos = null,
779                                 prevPaneWidth = null,
780                                 nextPaneWidth = null,
781                                 displayStyle = $el.css( "display" ),
782                                 parentWidth = self.containerSize[ 0 ],
783                                 parentHeight = self.containerSize[ 1 ],
784                                 width = parentWidth - self._horizontalBoundary(),
785                                 height = parentHeight - self._verticalBoundary(),
786                                 availableWidth = isHorizontal ?
787                                                                         ( width - spliterSize ) :
788                                                                         ( height - spliterSize ),
789                                 sum = 0;
790
791                         moveTarget.removeClass( "ui-spliter-active" );
792
793                         // ratio calculation
794                         $panes.each( function ( i ) {
795                                 var $pane = $( this ),
796                                         paneWidth = isHorizontal ? $pane.width() : $pane.height();
797
798                                 sum += paneWidth;
799                         });
800
801                         $panes.each( function ( i ) {
802                                 var $pane = $( this ),
803                                         paneWidth = isHorizontal ? $pane.width() : $pane.height();
804
805                                 self.options.ratio[ i ] = paneWidth / sum;
806                         });
807
808                         self.moveData = null;
809                 },
810
811                 _fixed : function ( isFix ) {
812                         var self = this,
813                                 spliters = self.spliters;
814
815                         $.each( spliters, function ( i ) {
816                                 var $spliter = $( this );
817
818                                 if ( isFix ) {
819                                         $spliter.addClass( "ui-fixed" );
820                                 } else {
821                                         $spliter.removeClass( "ui-fixed" );
822                                 }
823                         });
824
825                         self._layout();
826                 },
827
828                 _dividerVertical : function ( isDividerVertical ) {
829                         var self = this,
830                                 $el = self.element,
831                                 isHorizontal = isDividerVertical,
832                                 $panes = null,
833                                 $spliters = null,
834                                 $bar = null,
835                                 $handle = null;
836
837                         $panes = $el.children( ".ui-pane" );
838                         $spliters = $el.children( ".ui-spliter" );
839                         $bar = $spliters.children( ".ui-spliter-bar" );
840                         $handle = $bar.children( ".ui-spliter-handle" );
841
842                         $el.removeClass( "ui-direction-vertical" );
843                         $el.removeClass( "ui-direction-horizontal" );
844                         $el.addClass( "ui-splitview ui-direction-" + self._direction( isHorizontal ) );
845
846                         $panes.css( {
847                                 "left" : "",
848                                 "top" : "",
849                                 "width" : "",
850                                 "height" : ""
851                         });
852
853                         $spliters.css( {
854                                 "left" : "",
855                                 "top" : "",
856                                 "width" : "",
857                                 "height" : ""
858                         });
859
860                         $bar.css( {
861                                 "width" : "",
862                                 "height" : ""
863                         });
864
865                         $handle.css( {
866                                 "left" : "",
867                                 "top" : ""
868                         });
869
870                         if ( self._getContainerSize( $el[ 0 ].style.width, $el[ 0 ].style.height ) ) {
871                                 self._layout();
872                         }
873                 },
874
875                 _ratio : function ( ratioParam ) {
876                         var self = this,
877                                 $el = self.element,
878                                 $panes = $el.children( ".ui-pane" ),
879                                 panesLength = $panes.length;
880
881                         self._convertRatio( ratioParam, panesLength );
882                         self._layout();
883                 },
884
885                 _refresh : function ( initRatio, fromFirstPane ) {
886                         var self = this,
887                                 $el = self.element;
888
889                         initRatio = !!initRatio;
890                         fromFirstPane = !!fromFirstPane;
891
892                         if ( self._getContainerSize( $el[ 0 ].style.width, $el[ 0 ].style.height ) ) {
893                                 self._layout( initRatio, fromFirstPane );
894                         }
895                 },
896
897                 pane : function ( id, element ) {
898                         if ( typeof id !== "string" ) {
899                                 return null;
900                         }
901
902                         var self = this,
903                                 $el = self.element,
904                                 $targetPane = $el.children( id ),
905                                 $targetView = null,
906                                 elementParent = null;
907
908                         if ( !$targetPane.hasClass( "ui-pane" ) ) {
909                                 return null;
910                         }
911
912                         // getter
913                         if ( !element ) {
914                                 return $targetPane.contents();
915                         }
916
917                         // setter
918                         if ( $targetPane.hasClass( "ui-scrollview-clip" ) ) {
919                                 $targetPane.scrollview( "scrollTo", 0, 0, 0 );
920
921                                 $targetView = $targetPane.children( ".ui-scrollview-view" );
922                                 if ( !$targetView.length ) {
923                                         return null;
924                                 }
925                         } else {
926                                 $targetView = $targetPane;
927                         }
928
929                         elementParent = element.parent();
930                         if ( elementParent.length && elementParent[ 0 ] === $targetView[ 0 ] ) {
931                                 return;
932                         }
933
934                         $targetView.empty().append( element ).trigger( "create" );
935                         $targetView.fadeIn( 'fast' );
936                 },
937
938                 maximize : function ( id ) {
939                         if ( typeof id !== "string" ) {
940                                 return;
941                         }
942
943                         var self = this,
944                                 $el = self.element,
945                                 $panes = self.panes,
946                                 $targetPane = $el.children( id );
947
948                         if ( !$targetPane.hasClass( "ui-pane" ) ) {
949                                 return;
950                         }
951
952                         self.savedRatio = self.options.ratio.slice();
953
954                         self.options.ratio = [];
955                         $panes.each( function ( i ) {
956                                 self.options.ratio.push( ( this === $targetPane[ 0 ] ) ? 1 : 0 );
957                         });
958
959                         self._layout();
960                 },
961
962                 restore : function () {
963                         var self = this;
964
965                         if ( !self.savedRatio.length ) {
966                                 return;
967                         }
968
969                         self.options.ratio = self.savedRatio.slice();
970                         self._adjustRatio( self.panes.length );
971
972                         self._layout();
973                 }
974         });
975
976         $( document ).bind( "pagecreate create", function ( e ) {
977                 $.tizen.splitview.prototype.enhanceWithin( e.target );
978         });
979 } ( jQuery, window, document ) );
980