
/*
* jQuery Mobile Framework : scrollview plugin
* Copyright (c) 2010 Adobe Systems Incorporated - Kin Blas (jblas@adobe.com)
* Licensed under the MIT (MIT-LICENSE.txt) license.
* Note: Code is in draft form and is subject to change
* Modified by Koeun Choi <koeun.choi@samsung.com>
* Modified by Minkyu Kang <mk7.kang@samsung.com>
*/

(function ( $, window, document, undefined ) {

	/**
	 * Resizes page content height according to footer
	 * header elements, and page padding
	 * @param {HTMLElement|jQuery} page
	 */
	function resizePageContentHeight( page ) {
		var $page = $( page ),
			$content = $page.children(".ui-content"),
			hh = $page.children(".ui-header").outerHeight() || 0,
			fh = $page.children(".ui-footer").outerHeight() || 0,
			pt = parseFloat( $content.css("padding-top") ),
			pb = parseFloat( $content.css("padding-bottom") ),
			wh = $( window ).height();

		$content.height( wh - (hh + fh) - (pt + pb) );
	}

	/**
	 * MomentumTracker - helper class to ease momentum
	 * movement calculations
	 * @class
	 * @param {Object} options
	 */
	function MomentumTracker( options ) {
		this.options = $.extend( {}, options );
		this.easing = "easeOutQuad";
		this.reset();
	}

	/**
	 * Scroll states dictionary
	 * @type {Object}
	 */
	var tstates = {
		scrolling: 0,
		overshot:  1,
		snapback:  2,
		done:      3
	};

	/**
	 * Returns current time in miliseconds
	 * @return {number}
	 */
	function getCurrentTime() {
		return Date.now();
	};

	function bitwiseAbs( e ) {
		return ( e ^ (e>>31)) - (e>>31);
	}

	jQuery.widget( "tizen.scrollview", jQuery.mobile.widget, {
		/**
		 * Default options
		 * @type {Object}
		 */
		options: {
			/**
			 * Direction of scroll, can be:
			 * "x" for horizontal scroll
			 * "y" for vertical scroll
			 * null for horizontal and vertical scroll
			 * @type {string|null}
			 */
			direction:         null,  // "x", "y", or null for both.

			/**
			 * Internal timer inteval
			 * @type {number}
			 */
			timerInterval:     10,

			/**
			 * Duration of the scrolling animation in miliseconds
			 * @type {number}
			 */
			scrollDuration:    1000,

			/**
			 * Duration of the overshoot animation in miliseconds
			 * @type {number}
			 */
			overshootDuration: 250,

			/**
			 * Duration of snapback animation in miliseconds
			 * @type {number}
			 */
			snapbackDuration:  500,

			/**
			 * Scroll detection threshold
			 * @type {number}
			 */
			moveThreshold:     10,

			/**
			 * Maximal time between mouse movements while scrolling
			 * @type {number}
			 */
			moveIntervalThreshold:     150,

			/**
			 * Scroll method type, can be "translate" or "position"
			 * @type {string}
			 */
			scrollMethod:      "translate",

			/**
			 * The event fired when started scrolling
			 * @type {string}
			 */
			startEventName:    "scrollstart",

			/**
			 * The event fired on each scroll update (movement)
			 * @type {string}
			 */
			updateEventName:   "scrollupdate",

			/**
			 * The event fired after scroll stopped
			 * @type {string}
			 */
			stopEventName:     "scrollstop",

			/**
			 * Determines the event group for detecting scroll
			 * if $.support.touch has truthy value the group
			 * that starts scroll will be touch events, otherwise
			 * mouse events will be used
			 * @type {string}
			 */
			eventType:         $.support.touch ? "touch" : "mouse",

			/**
			 * Determines if we should show the scrollbars
			 * @type {boolean}
			 */
			showScrollBars:    true,

			/**
			 * Determines if overshoot animation is enabled
			 * @type {boolean}
			 */
			overshootEnable:   false,

			/**
			 * Determines if we enable the window scroll
			 * @type {boolean}
			 */
			outerScrollEnable: false,

			/**
			 * Determines if the overflow animation is enabled
			 * @type {boolean}
			 */
			overflowEnable:    true,

			/**
			 * Determines if we allow scroll jumps
			 * @type {boolean}
			 */
			scrollJump:        false
		},

		/**
		 * Returns view height
		 * @private
		 * @return {number}
		 */
		_getViewHeight: function () {
			return this._$view.height();
		},

		/**
		 * Returns view width
		 * @private
		 * @return {number}
		 */
		_getViewWidth: function () {
			return this._$view.width();
		},

		/**
		 * Changes specified elements position to relative if
		 * previous position state was static
		 * @private
		 * @param {jQuery} $ele
		 */
		_makePositioned: function ( $ele ) {
			if ( $ele.css("position") === "static" ) {
				$ele.css( "position", "relative" );
			}
		},

		/**
		 * Creates scrollview widget,
		 * binds events and initiaties timers
		 * @private
		 */
		_create: function () {
			var direction,
				self = this;

			this._$clip = $( this.element ).addClass("ui-scrollview-clip");

			if ( this._$clip.children(".ui-scrollview-view").length ) {
				this._$view = this._$clip.children(".ui-scrollview-view");
			} else {
				this._$view = this._$clip.wrapInner("<div></div>").children()
							.addClass("ui-scrollview-view");
			}

			if ( this.options.scrollMethod === "translate" ) {
				if ( this._$view.css("transform") === undefined ) {
					this.options.scrollMethod = "position";
				}
			}

			this._$clip.css( "overflow", "hidden" );
			this._makePositioned( this._$clip );

			this._makePositioned( this._$view );
			this._$view.css( { left: 0, top: 0 } );

			this._view_height = this._getViewHeight();

			this._sx = 0;
			this._sy = 0;

			direction = this.options.direction;

			this._hTracker = ( direction !== "y" ) ?
					new MomentumTracker( this.options ) : null;
			this._vTracker = ( direction !== "x" ) ?
					new MomentumTracker( this.options ) : null;

			this._timerInterval = this.options.timerInterval;
			this._timerID = 0;

			this._timerCB = function () {
				self._handleMomentumScroll();
			};

			this._add_event();
			this._add_scrollbar();
			this._add_scroll_jump();
			this._add_overflow_indicator();
			this._moveInterval = 10; /* Add Interval */
			this._clipHeight = 0;
		},

		/**
		 * Starts momentum scroll after user stopped
		 * scrolling
		 * @private
		 * @param {number} speedX Horizontal speed
		 * @param {number} speedY Vertical speed
		 */
		_startMScroll: function ( speedX, speedY ) {
			var keepGoing = false,
				duration = this.options.scrollDuration,
				ht = this._hTracker,
				vt = this._vTracker,
				c,
				v;

			this._$clip.trigger( this.options.startEventName );

			if ( ht ) {
				c = this._$clip.width();
				v = this._getViewWidth();

				if ( (( this._sx === 0 && speedX > 0 ) ||
					( this._sx === -(v - c) && speedX < 0 )) &&
						v > c ) {
					return;
				}

				ht.start( this._sx, speedX,
					duration, (v > c) ? -(v - c) : 0, 0 );
				keepGoing = !ht.done();
			}

			if ( vt ) {
				c = this._$clip.height();
				v = this._getViewHeight();

				if ( (( this._sy === 0 && speedY > 0 ) ||
					( this._sy === -(v - c) && speedY < 0 )) &&
						v > c ) {
					return;
				}

				vt.start( this._sy, speedY,
					duration, (v > c) ? -(v - c) : 0, 0 );
				keepGoing = keepGoing || !vt.done();
			}

			if ( keepGoing ) {
				this._timerID = setTimeout( this._timerCB, this._timerInterval );
			} else {
				this._stopMScroll();
			}
		},

		/**
		 * Ends momentum scroll
		 * @private
		 */
		_stopMScroll: function () {
			if ( this._timerID ) {
				this._$clip.trigger( this.options.stopEventName );
				clearTimeout( this._timerID );
			}
			this._timerID = 0;

			if ( this._vTracker ) {
				this._vTracker.reset();
			}

			if ( this._hTracker ) {
				this._hTracker.reset();
			}

			this._hideScrollBars();
			this._hideOverflowIndicator();
		},

		/**
		 * Updates scroll while in momentum scroll mode
		 * @private
		 */
		_handleMomentumScroll: function () {
			var keepGoing = false,
				x = 0,
				y = 0,
				scroll_height = 0,
				self = this,
				vt = this._vTracker,
				ht = this._hTracker;

			if ( this._outerScrolling ) {
				return;
			}

			if ( vt ) {
				vt.update( this.options.overshootEnable );
				y = vt.getPosition();
				keepGoing = !vt.done();

				if ( vt.getRemained() > this.options.overshootDuration ) {
					scroll_height = this._getViewHeight() - this._$clip.height();

					if ( !vt.isAvail() ) {
						if ( this._speedY > 0 ) {
							this._outerScroll( vt.getRemained() / 3, scroll_height );
						} else {
							this._outerScroll( y - vt.getRemained() / 3, scroll_height );
						}
					} else if ( vt.isMin() ) {
						this._outerScroll( y - vt.getRemained() / 3, scroll_height );

					} else if ( vt.isMax() ) {
						this._outerScroll( vt.getRemained() / 3, scroll_height );
					}
				}
			}

			if ( ht ) {
				ht.update( this.options.overshootEnable );
				x = ht.getPosition();
				keepGoing = keepGoing || !ht.done();
			}

			this._setScrollPosition( x, y );
			this._$clip.trigger( this.options.updateEventName,
					[ { x: x, y: y } ] );

			if ( keepGoing ) {
				this._timerID = setTimeout( this._timerCB, this._timerInterval );
			} else {
				this._stopMScroll();
			}
		},

		/**
		 * Sets css translate transformation for element
		 * @param {jQuery} $ele
		 * @param {number} x
		 * @param {number} y
		 * @param {number} duration
		 */
		_setElementTransform: function ( $ele, x, y, duration ) {
			var translate,
				transition;

			if ( !duration || duration === undefined ) {
				transition = "none";
			} else {
				transition =  "-webkit-transform " + duration / 1000 + "s ease-out";
			}

			if ( $.support.cssTransform3d ) {
				translate = "translate3d(" + x + "," + y + ", 0px)";
			} else {
				translate = "translate(" + x + "," + y + ")";
			}

			$ele.css({
				"-moz-transform": translate,
				"-webkit-transform": translate,
				"-ms-transform": translate,
				"-o-transform": translate,
				"transform": translate,
				"-webkit-transition": transition
			});
		},

		/**
		 * Applies scroll end effect according to direction
		 * @param {string} dir Direction, can be "in" or "out"
		 */
		_setEndEffect: function ( dir ) {
			var scroll_height = this._getViewHeight() - this._$clip.height();

			if ( this._softkeyboard ) {
				if ( this._effect_dir ) {
					this._outerScroll( -scroll_height - this._softkeyboardHeight,
							scroll_height );
				} else {
					this._outerScroll( this._softkeyboardHeight, scroll_height );
				}
				return;
			}

			if ( dir === "in" ) {
				if ( this._endEffect ) {
					return;
				}

				this._endEffect = true;
				this._setOverflowIndicator( this._effect_dir );
				this._showOverflowIndicator();
			} else if ( dir === "out" ) {
				if ( !this._endEffect ) {
					return;
				}

				this._endEffect = false;
			} else {
				this._endEffect = false;
				this._setOverflowIndicator();
				this._showOverflowIndicator();
			}
		},

		/**
		 * Calibrates scroll position and scroll end effect
		 * @private
		 * @param {number} x
		 * @param {number} y
		 */
		_setCalibration: function ( x, y ) {
			if ( this.options.overshootEnable ) {
				this._sx = x;
				this._sy = y;
				return;
			}

			var $v = this._$view,
				$c = this._$clip,
				dirLock = this._directionLock,
				scroll_height = 0,
				scroll_width = 0,
				vh,
				ch;

			if ( dirLock !== "y" && this._hTracker ) {
				scroll_width = $v.width() - $c.width();

				if ( x >= 0 ) {
					this._sx = 0;
				} else if ( x < -scroll_width ) {
					this._sx = -scroll_width;
				} else {
					this._sx = x;
				}

				if ( scroll_width < 0 ) {
					this._sx = 0;
				}
			}

			if ( dirLock !== "x" && this._vTracker ) {
				vh = this._getViewHeight();
				ch = $c.height();
				/*
				When used changePage() function, this._getViewHeight() value set 0.
				So scroll_height has incorrect value and showed indicator incorrectly.
				Below condition is exception handling that avoid this situation.
				*/
				if ( vh != 0 && ch > 0 ) {
					scroll_height = vh - ch;
				}

				if ( y > 0 ) {
					this._sy = 0;

					this._effect_dir = 0;
					this._setEndEffect( "in" );
				} else if ( y < -scroll_height ) {
					this._sy = -scroll_height;

					this._effect_dir = 1;
					this._setEndEffect( "in" );
				} else {
					if ( this._endEffect && this._sy !== y ) {
						this._setEndEffect();
					}

					this._sy = y;
				}

				if ( scroll_height < 0 ) {
					this._sy = 0;
				}
			}
		},

		/**
		 * Moves scroll to specified position
		 * @private
		 * @param {number} x
		 * @param {number} y
		 * @param {number} duration
		 */
		_setScrollPosition: function ( x, y, duration ) {
			var $v = this._$view,
				sm = this.options.scrollMethod,
				$vsb = this._$vScrollBar,
				$hsb = this._$hScrollBar,
				$sbt;

			this._setCalibration( x, y );

			x = this._sx;
			y = this._sy;

			if ( sm === "translate" ) {
				this._setElementTransform( $v, x + "px", y + "px", duration );
			} else {
				$v.css( {left: x + "px", top: y + "px"} );
			}

			if ( $vsb ) {
				$sbt = $vsb.find(".ui-scrollbar-thumb");

				if ( sm === "translate" ) {
					if ( bitwiseAbs( this._moveInterval - bitwiseAbs(y)) > 20 ) {
						/* update scrollbar every 20(clientY) move*/
						/* Add Interval */
						this._setElementTransform( $sbt, "0px",
							-y / this._getViewHeight() * this._clipHeight + "px",
							duration );
					}
				} else {
					$sbt.css( "top", -y / this._getViewHeight() * 100 + "%" );
				}
			}

			if ( $hsb ) {
				$sbt = $hsb.find(".ui-scrollbar-thumb");

				if ( sm === "translate" ) {
					this._setElementTransform( $sbt,
						-x / $v.outerWidth() * $sbt.parent().width() + "px", "0px",
						duration);
				} else {
					$sbt.css("left", -x / $v.width() * 100 + "%");
				}
			}
		},

		/**
		 * Handles window scrolling
		 * @private
		 * @param {number} y
		 * @param {number} scroll_height
		 */
		_outerScroll: function ( y, scroll_height ) {
			var self = this,
				top = $( window ).scrollTop() - window.screenTop,
				sy = 0,
				duration = this.options.snapbackDuration,
				start = getCurrentTime(),
				tfunc;

			if ( !this.options.outerScrollEnable ) {
				return;
			}

			if ( this._$clip.jqmData("scroll") !== "y" ) {
				return;
			}

			if ( this._outerScrolling ) {
				return;
			}

			if ( y > 0 ) {
				sy = ( window.screenTop ? window.screenTop : -y );
			} else if ( y < -scroll_height ) {
				sy = -y - scroll_height;
			} else {
				return;
			}

			tfunc = function () {
				var elapsed = getCurrentTime() - start;

				if ( elapsed >= duration ) {
					window.scrollTo( 0, top + sy );
					self._outerScrolling = undefined;

					self._stopMScroll();
				} else {
					ec = $.easing.easeOutQuad( elapsed / duration,
							elapsed, 0, 1, duration );

					window.scrollTo( 0, top + ( sy * ec ) );
					self._outerScrolling = setTimeout( tfunc, self._timerInterval );
				}
			};
			this._outerScrolling = setTimeout( tfunc, self._timerInterval );
		},

		/**
		 * Scrolls to specified position with easeOutQuad calculations
		 * @private
		 * @param {number} x
		 * @param {number} y
		 * @param {number} duration
		 */
		_scrollTo: function ( x, y, duration ) {
			var self = this,
				start = getCurrentTime(),
				efunc = $.easing.easeOutQuad,
				sx = this._sx,
				sy = this._sy,
				dx = x - sx,
				dy = y - sy,
				tfunc;

			x = -x;
			y = -y;

			tfunc = function () {
				var elapsed = getCurrentTime() - start,
				    ec;

				if ( elapsed >= duration ) {
					self._timerID = 0;
					self._setScrollPosition( x, y );
				} else {
					ec = efunc( elapsed / duration, elapsed, 0, 1, duration );

					self._setScrollPosition( sx + ( dx * ec ), sy + ( dy * ec ) );
					self._timerID = setTimeout( tfunc, self._timerInterval );
				}
			};

			this._timerID = setTimeout( tfunc, this._timerInterval );
		},

		/**
		 * Scrolls to specified position
		 * If scroll method is css translation or duration is a
		 * falsy value, the position is changed via translation,
		 * otherwise it's animated to that position
		 * @param {number} x
		 * @param {number} y
		 * @param {number} duration
		 */
		scrollTo: function ( x, y, duration ) {
			this._stopMScroll();
			this._didDrag = false;

			if ( !duration || this.options.scrollMethod === "translate" ) {
				this._setScrollPosition( x, y, duration );
			} else {
				this._scrollTo( x, y, duration );
			}
		},

		/**
		 * Centers scroll to view the specified child element
		 * @param {Element|jQuery} target
		 */
		centerToElement: function ( element ) {
			var $clip = this._$clip,
				$view = this._$view,
				$element = element.get ? element : $( element ),
				delta = ( $clip.height() / 2 ) - ( element.height() / 2 ),
				elementPosition = element.position().top;

			element.parentsUntil( $view ).each( function () {
				var $parent = $( this );
				elementPosition += ( $parent.position().top + parseFloat( $parent.css( "marginTop" ) ) + parseFloat( $parent.css( "paddingTop" ) ) );
			});

			this.scrollTo( this._sx, -( elementPosition - delta ) );
		},

		/**
		 * Checks if the specified child element is visible
		 * and centers the scroll on it if it's not visible
		 * @param {Element|jQuery}
		 */
		ensureElementIsVisible: function ( element ) {
			var $element = element.get ? element : $( element ),
				$clip = this._$clip,
				clipHeight = $clip.height(),
				clipTop = $clip.offset().top,
				clipBottom = clipTop + clipHeight,
				elementHeight = $element.height(),
				elementTop = $element.offset().top,
				elementBottom = elementTop + elementHeight,
				elementFits = clipHeight > elementHeight,
				$anchor,
				anchorPosition = 0,
				findPositionAnchor = function ( input ) {
					var $label,
						id = input.attr( "id" );
					if ( input.is( ":input" ) && id ) {
						$label = input.siblings( "label[for=" + id + "]" );
						if ( $label.length > 0 ) {
							return $label.eq( 0 );
						}
					}
					return input;
				};

			switch( true ) {
				case elementFits && clipTop < elementTop && clipBottom > elementBottom: // element fits in view is inside clip area
					// pass, element position is ok
					break;
				case elementFits && clipTop < elementTop && clipBottom < elementBottom: // element fits in view but its visible only at top
				case elementFits && clipTop > elementTop && clipBottom > elementBottom: // element fits in view but its visible only at bottom
				case elementFits: // element fits in view but is not visible
					this.centerToElement(element);
					break;
				case clipTop < elementTop && clipBottom < elementBottom: // element visible only at top
				case clipTop > elementTop && clipBottom > elementBottom: // element visible only at bottom
					// pass, we cant do anything, if we move the scroll
					// the user could lost view of something he scrolled to
					break;
				default: // element is not visible
					$anchor = findPositionAnchor( $element );
					anchorPosition = $anchor.position().top + parseFloat( $anchor.css("marginTop" ) );
					$anchor.parentsUntil($view).each(function () {
						var $p = $( this );
						anchorPosition += ( $p.position().top + parseFloat( $p.css("marginTop" ) ) );
					});
					this.scrollTo( self._sx, -anchorPosition );
					break;
			}
		},

		/**
		 * Returns current scroll position {x,y}
		 * @return {Object}
		 */
		getScrollPosition: function () {
			return { x: -this._sx, y: -this._sy };
		},

		/**
		 * Skipps dragging
		 * @param {Boolean}
		 */
		skipDragging: function ( value ) {
			this._skip_dragging = value;
		},

		/**
		 * Returns scroll hierarchy in an array of elements
		 * @private
		 * @return {Array}
		 */
		_getScrollHierarchy: function () {
			var svh = [],
				d;

			this._$clip.parents( ".ui-scrollview-clip").each( function () {
				d = $( this ).jqmData("scrollview");
				if ( d ) {
					svh.unshift( d );
				}
			} );
			return svh;
		},

		/**
		 * Returns ancestor for specified direction
		 * @private
		 * @param {string} dir
		 */
		_getAncestorByDirection: function ( dir ) {
			var svh = this._getScrollHierarchy(),
				n = svh.length,
				sv,
				svdir;

			while ( 0 < n-- ) {
				sv = svh[n];
				svdir = sv.options.direction;

				if (!svdir || svdir === dir) {
					return sv;
				}
			}
			return null;
		},

		/**
		 * Handles dragstart event
		 * @private
		 * @param {Event} e
		 * @param {number} ex Event x position
		 * @param {number} ey Event y position
		 */
		_handleDragStart: function ( e, ex, ey ) {
			this._stopMScroll();

			this._didDrag = false;
			this._skip_dragging = false;
			this._clipHeight = this._$clip.height();
			var target = $( e.target ),
				self = this,
				$c = this._$clip,
				svdir = this.options.direction;

			/* should prevent the default behavior when click the button */
			this._is_button = target.is( '.ui-btn' ) ||
					target.is( '.ui-btn-text' ) ||
					target.is( '.ui-btn-inner' ) ||
					target.is( '.ui-btn-inner .ui-icon' );

			/* should prevent the default behavior when click the slider */
			if ( target.parents('.ui-slider').length || target.is('.ui-slider') ) {
				this._skip_dragging = true;
				return;
			}

			if ( target.is('textarea') ) {
				target.bind( "scroll", function () {
					self._skip_dragging = true;
					target.unbind("scroll");
				});
			}

			/*
			 * We need to prevent the default behavior to
			 * suppress accidental selection of text, etc.
			 */
			this._is_inputbox = target.is(':input') ||
					target.parents(':input').length > 0;

			if ( this._is_inputbox ) {
				target.one( "resize.scrollview", function () {
					if ( ey > $c.height() ) {
						self.scrollTo( -ex, self._sy - ey + $c.height(),
							self.options.snapbackDuration );
					}
				});
			}

			if ( this.options.eventType === "mouse" && !this._is_inputbox && !this._is_button ) {
				e.preventDefault();
			}

			this._lastX = ex;
			this._lastY = ey;
			this._startY = ey;
			this._doSnapBackX = false;
			this._doSnapBackY = false;
			this._speedX = 0;
			this._speedY = 0;
			this._directionLock = "";

			this._lastMove = 0;
			this._enableTracking();

			this._set_scrollbar_size();
		},

		/**
		 * Propagates dragging
		 * @private
		 * @param {jQuery} sv
		 * @param {Event} e
		 * @param {number} ex
		 * @param {number} ey
		 * @param {string} dir
		 */
		_propagateDragMove: function ( sv, e, ex, ey, dir ) {
			this._hideScrollBars();
			this._hideOverflowIndicator();
			this._disableTracking();
			sv._handleDragStart( e, ex, ey );
			sv._directionLock = dir;
			sv._didDrag = this._didDrag;
		},

		/**
		 * Handles drag event
		 * @private
		 * @param {Event}
		 * @param {number} ex
		 * @param {number} ey
		 * @return {boolean|undefined}
		 */
		_handleDragMove: function ( e, ex, ey ) {
			this._moveInterval = ey;
			if ( this._skip_dragging ) {
				return;
			}

			if ( !this._dragging ) {
				return;
			}

			if ( !this._is_inputbox && !this._is_button ) {
				e.preventDefault();
			}

			var mt = this.options.moveThreshold,
				dx = ex - this._lastX,
				dy = ey - this._lastY,
				svdir = this.options.direction,
				dir = null,
				x,
				y,
				sv,
				scope,
				newX,
				newY,
				dirLock;

			this._lastMove = getCurrentTime();

			if ( !this._directionLock ) {
				x = Math.abs( dx );
				y = Math.abs( dy );

				if ( x < mt && y < mt ) {
					return false;
				}

				if ( x < y && (x / y) < 0.5 ) {
					dir = "y";
				} else if ( x > y && (y / x) < 0.5 ) {
					dir = "x";
				}

				if ( svdir && dir && svdir !== dir ) {
					/*
					 * This scrollview can't handle the direction the user
					 * is attempting to scroll. Find an ancestor scrollview
					 * that can handle the request.
					 */

					sv = this._getAncestorByDirection( dir );
					if ( sv ) {
						this._propagateDragMove( sv, e, ex, ey, dir );
						return false;
					}
				}

				this._directionLock = svdir || (dir || "none");
			}

			newX = this._sx;
			newY = this._sy;
			dirLock = this._directionLock;

			if ( dirLock !== "y" && this._hTracker ) {
				x = this._sx;
				this._speedX = dx;
				newX = x + dx;

				this._doSnapBackX = false;

				scope = ( newX > 0 || newX < this._maxX );

				if ( scope && dirLock === "x" ) {
					sv = this._getAncestorByDirection("x");
					if ( sv ) {
						this._setScrollPosition( newX > 0 ?
								0 : this._maxX, newY );
						this._propagateDragMove( sv, e, ex, ey, dir );
						return false;
					}

					newX = x + ( dx / 2 );
					this._doSnapBackX = true;
				}
			}

			if ( dirLock !== "x" && this._vTracker ) {
				if ( Math.abs( this._startY - ey ) < mt && dirLock !== "xy" && this._didDrag === false ) {
					return;
				}

				y = this._sy;
				this._speedY = dy;
				newY = y + dy;

				this._doSnapBackY = false;

				scope = ( newY > 0 || newY < this._maxY );

				if ( scope && dirLock === "y" ) {
					sv = this._getAncestorByDirection("y");
					if ( sv ) {
						this._setScrollPosition( newX,
								newY > 0 ? 0 : this._maxY );
						this._propagateDragMove( sv, e, ex, ey, dir );
						return false;
					}

					newY = y + ( dy / 2 );
					this._doSnapBackY = true;
				}
			}

			if ( this.options.overshootEnable === false ) {
				this._doSnapBackX = false;
				this._doSnapBackY = false;
			}

			this._lastX = ex;
			this._lastY = ey;

			this._setScrollPosition( newX, newY );

			if ( this._didDrag === false ) {
				this._didDrag = true;
				this._showScrollBars();
				this._showOverflowIndicator();

				this._$clip.parents(".ui-scrollview-clip").each( function () {
					$( this ).scrollview( "skipDragging", true );
				} );
			}
		},

		/**
		 * Handles drag stop event, and returns drag status
		 * @param {Event} e
		 * @return {Boolean|undefined}
		 */
		_handleDragStop: function ( e ) {
			var self = this;

			if ( this._skip_dragging ) {
				return;
			}

			var l = this._lastMove,
				t = getCurrentTime(),
				doScroll = (l && (t - l) <= this.options.moveIntervalThreshold),
				sx = ( this._hTracker && this._speedX && doScroll ) ?
						this._speedX : ( this._doSnapBackX ? 1 : 0 ),
				sy = ( this._vTracker && this._speedY && doScroll ) ?
						this._speedY : ( this._doSnapBackY ? 1 : 0 ),
				svdir = this.options.direction,
				x,
				y;

			if ( sx || sy ) {
				if ( !this._setGestureScroll( sx, sy ) ) {
					this._startMScroll( sx, sy );
				}
			} else {
				this._hideScrollBars();
				this._hideOverflowIndicator();
			}

			this._disableTracking();

			if ( this._endEffect ) {
				setTimeout( function () {
					self._setEndEffect( "out" );
					self._hideScrollBars();
					self._hideOverflowIndicator();
				}, 300 );
			}

			return !this._didDrag;
		},

		/**
		 * Detects gestures and sets proper gesture direction
		 * @private
		 * @param {number} sx
		 * @param {number} sy
		 * @return {boolean}
		 */
		_setGestureScroll: function ( sx, sy ) {
			var self = this,
				reset = function () {
					clearTimeout( self._gesture_timer );
					self._gesture_dir = 0;
					self._gesture_timer = undefined;
				},
				direction = {
					top: 0,
					bottom: 1,
					left: 2,
					right: 3
				};

			if ( !sy && !sx ) {
				return false;
			}

			if ( Math.abs( sx ) > Math.abs( sy ) ) {
				dir = sx > 0 ? direction.left : direction.right;
			} else {
				dir = sy > 0 ? direction.top : direction.bottom;
			}

			if ( !this._gesture_timer ) {
				this._gesture_dir = dir;

				this._gesture_timer = setTimeout( function () {
					reset();
				}, 1000 );

				return false;
			}

			if ( this._gesture_dir !== dir ) {
				reset();
				return false;
			}

			return false;
		},

		/**
		 * Enables dragging
		 * @private
		 */
		_enableTracking: function () {
			this._dragging = true;
		},

		/**
		 * Disables dragging
		 * @private
		 */
		_disableTracking: function () {
			this._dragging = false;
		},

		/**
		 * Shows scrollbars
		 * When interval is specified, the scrollbars will be
		 * hidden after the specified time in miliseconds
		 * @private
		 * @param {number} [interval]
		 */
		_showScrollBars: function ( interval ) {
			var vclass = "ui-scrollbar-visible",
				self = this;

			if ( !this.options.showScrollBars ) {
				return;
			}
			if ( this._scrollbar_showed ) {
				return;
			}

			if ( this._$vScrollBar ) {
				this._$vScrollBar.addClass( vclass );
			}
			if ( this._$hScrollBar ) {
				this._$hScrollBar.addClass( vclass );
			}

			this._scrollbar_showed = true;

			if ( interval ) {
				setTimeout( function () {
					self._hideScrollBars();
				}, interval );
			}
		},

		/**
		 * Hides scrollbars
		 * @private
		 */
		_hideScrollBars: function () {
			var vclass = "ui-scrollbar-visible";

			if ( !this.options.showScrollBars ) {
				return;
			}
			if ( !this._scrollbar_showed ) {
				return;
			}

			if ( this._$vScrollBar ) {
				this._$vScrollBar.removeClass( vclass );
			}
			if ( this._$hScrollBar ) {
				this._$hScrollBar.removeClass( vclass );
			}

			this._scrollbar_showed = false;
		},

		/**
		 * Sets opacities for the oveflow indicator
		 * according to specified direction. The direction
		 * is optional. Specify 1 for top, 0 for bottom, and
		 * a falsy value for both
		 * @private
		 * @param {number} [dir] 0
		 */
		_setOverflowIndicator: function ( dir ) {
			if ( dir === 1 ) {
				this._display_indicator_top = "none";
				this._display_indicator_bottom = "block";
			} else if ( dir === 0 ) {
				this._display_indicator_top = "block";
				this._display_indicator_bottom = "none";
			} else {
				this._display_indicator_top = "block";
				this._display_indicator_bottom = "block";
			}
		},

		/**
		 * Display overflow indicator
		 * @private
		 */
		_showOverflowIndicator: function () {
			if ( !$( this.element ).is( ".ui-content" ) ) {
				return true;
			}

			if ( !this.options.overflowEnable || !this._overflowAvail || this._softkeyboard ) {
				return;
			}

			this._overflow_top.css( "display", this._display_indicator_top );
			this._overflow_bottom.css( "display", this._display_indicator_bottom );

			this._overflow_showed = true;
		},

		/**
		 * Hide overflow indicator
		 * @private
		 */
		_hideOverflowIndicator: function () {
			if ( !this.options.overflowEnable || !this._overflowAvail || this._softkeyboard ) {
				return;
			}

			if ( this._overflow_showed === false ) {
				return;
			}

			this._overflow_top.css( "display", "none" );
			this._overflow_bottom.css( "display", "none" );

			this._overflow_showed = false;
			this._setOverflowIndicator();
		},

		/**
		 * Bind events
		 * @private
		 * @return {boolean|undefined}
		 */
		_add_event: function () {
			var self = this,
				$c = this._$clip,
				$v = this._$view;

			if ( this.options.eventType === "mouse" ) {
				this._dragEvt = "mousedown mousemove mouseup click mousewheel";

				this._dragCB = function ( e ) {
					switch ( e.type ) {
					case "mousedown":
						return self._handleDragStart( e,
								e.clientX, e.clientY );

					case "mousemove":
						return self._handleDragMove( e,
								e.clientX, e.clientY );

					case "mouseup":
						return self._handleDragStop( e );

					case "click":
						return !self._didDrag;

					case "mousewheel":
						var old = self.getScrollPosition();
						self.scrollTo( -old.x,
							-(old.y - e.originalEvent.wheelDelta) );
						break;
					}
				};
			} else {
				this._dragEvt = "touchstart touchmove touchend";
				var _in_progress = false;
				this._dragCB = function ( e ) {
					var touches = e.originalEvent.touches;

					switch ( e.type ) {
					case "touchstart":
						if ( touches.length != 1 || _in_progress ) {
							return;
						}

						_in_progress = true;

						return self._handleDragStart( e,
								touches[0].pageX, touches[0].pageY );

					case "touchmove":
						if ( !_in_progress || touches.length != 1) {
							return;
						}

						return self._handleDragMove( e,
								touches[0].pageX, touches[0].pageY );

					case "touchend":
						if ( !_in_progress ) {
							return;
						}

						_in_progress = false;

						if ( touches.length != 0 ) {
							return;
						}

						return self._handleDragStop( e );
					}
				};
			};

			$v.bind( this._dragEvt, this._dragCB );

			// N_SE-35696 / N_SE-35800
			var clipScrollDelta = 0,
				clipScrollLast = 0;
			$c.on( "scroll", function () {
				var clipScrollTop = $c.scrollTop(),
					currentPositon = self.getScrollPosition(),
					inputs;

				clipScrollDelta = clipScrollTop - clipScrollLast;
				clipScrollLast = clipScrollTop;

				if ( clipScrollDelta > 0 ) {
					inputs = $v.find( ":input.ui-focus" );
					$c.scrollTop( 0 );
					if ( inputs.length ) {
						// CHECK WHERE WE ARE IN THE INPUTS
						clipScrollDelta = 0;
					}
					self.scrollTo( -currentPositon.x, -( currentPositon.y + clipScrollDelta ) );
				}
			} );

			$v.bind( "keydown", function ( e ) {
				var $focusedElement;

				if ( e.keyCode == 9 ) {
					return false;
				}

				$focusedElement = $c.find( ".ui-focus" );
				if ( !$focusedElement.length ) {
					return;
				}
				self.ensureElementIsVisible( $focusedElement );

				return;
			});

			$v.bind( "keyup", function ( e ) {
				var $input;

				if ( e.keyCode !== 9 ) {
					return;
				}

				/* Tab Key */
				$input = $( this ).find( ":input.ui-focus" ).eq( 0 );
				if ( !$input ) {
					return;
				}
				self.ensureElementIsVisible( $input );
				$input.focus();

				return false;
			});

			$c.bind( "updatelayout", function ( e ) {
				var sy,
					vh,
					view_h = self._getViewHeight();

				if ( !$c.height() || !view_h ) {
					self.scrollTo( 0, 0, 0 );
					return;
				}

				sy = $c.height() - view_h;
				vh = view_h - self._view_height;

				self._view_height = view_h;

				if ( vh == 0 || vh > $c.height() / 2 ) {
					return;
				}

				if ( sy > 0 ) {
					self.scrollTo( 0, 0, 0 );
				} else if ( self._sy - sy <= -vh ) {
					self.scrollTo( 0, self._sy,
						self.options.snapbackDuration );
				} else if ( self._sy - sy <= vh + self.options.moveThreshold ) {
					self.scrollTo( 0, sy,
						self.options.snapbackDuration );
				}
			});

			$( window ).bind( "resize", function ( e ) {
				var focused,
					view_h = self._getViewHeight();

				if ( $(".ui-page-active").get(0) !== $c.closest(".ui-page").get(0) ) {
					return;
				}

				if ( !$c.height() || !view_h ) {
					return;
				}

				focused = $c.find(".ui-focus");

				if ( focused ) {
					focused.trigger("resize.scrollview");
				}

				/* calibration - after triggered throttledresize */
				setTimeout( function () {
					var view_w = $v.outerWidth(),
						cw = $c.outerWidth(),
						scroll_x,
						scroll_y;
					if ( self._sy < $c.height() - self._getViewHeight() ) {
						scroll_y = $c.height() - self._getViewHeight();
						scroll_x = 0;
					}
					if ( self._sx < cw - view_w ) {
						scroll_x = cw - view_w;
						scroll_y = scroll_y || 0;
					}
					if (scroll_x || scroll_y) {
						self.scrollTo( scroll_x, scroll_y, self.options.overshootDuration );
					}
				}, 260 );

				self._view_height = view_h;
				self._clipHeight = self._$clip.height();
			});

			$( window ).bind( "vmouseout", function ( e ) {
				var drag_stop = false;

				if ( $(".ui-page-active").get(0) !== $c.closest(".ui-page").get(0) ) {
					return;
				}

				if ( !self._dragging ) {
					return;
				}

				if ( e.pageX < 0 || e.pageX > $( window ).width() ) {
					drag_stop = true;
				}

				if ( e.pageY < 0 || e.pageY > $( window ).height() ) {
					drag_stop = true;
				}

				if ( drag_stop ) {
					self._hideScrollBars();
					self._hideOverflowIndicator();
					self._disableTracking();
				}
			});

			this._softkeyboard = false;
			this._softkeyboardHeight = 0;

			window.addEventListener( "softkeyboardchange", function ( e ) {
				if ( $(".ui-page-active").get(0) !== $c.closest(".ui-page").get(0) ) {
					return;
				}

				self._softkeyboard = ( e.state === "on" ? true : false );
				self._softkeyboardHeight = parseInt( e.height ) *
						( $( window ).width() / window.screen.availWidth );
			});

			$c.closest(".ui-page")
				.bind( "pageshow", function ( e ) {
					self._view_height = self._$view.height();

					/* should be called after pagelayout */
					setTimeout( function () {
						self._view_height = self._getViewHeight();
						self._set_scrollbar_size();
						self._setScrollPosition( self._sx, self._sy );
						self._showScrollBars( 2000 );
					}, 0 );
				});

			$c.closest(".ui-page").find( ".ui-popup" )
				.bind( "popupafteropen", function ( e ) {
					if ( !$( self.element ).parents().is( ".ui-ctxpopup" ) ) {
						return true;
					}

                                        setTimeout( function () {
                                                self._setScrollPosition( self._sx, self._sy );
						self._showScrollBars( 2000 );
                                        }, 0 );
				});
		},

		/**
		 * Adds scrollbar elements to DOM
		 * @private
		 */
		_add_scrollbar: function () {
			var $c = this._$clip,
				prefix = "<div class=\"ui-scrollbar ui-scrollbar-",
				suffix = "\"><div class=\"ui-scrollbar-track\"><div class=\"ui-scrollbar-thumb\"></div></div></div>";

			if ( !this.options.showScrollBars ) {
				return;
			}

			if ( this._vTracker ) {
				$c.append( prefix + "y" + suffix );
				this._$vScrollBar = $c.children(".ui-scrollbar-y");
			}
			if ( this._hTracker ) {
				$c.append( prefix + "x" + suffix );
				this._$hScrollBar = $c.children(".ui-scrollbar-x");
			}

			this._scrollbar_showed = false;
		},

		/**
		 * Adds scroll jump button to DOM
		 * @private
		 */
		_add_scroll_jump: function () {
			var $c = this._$clip,
				self = this,
				top_btn,
				left_btn;

			if ( !this.options.scrollJump ) {
				return;
			}

			if ( this._vTracker ) {
				top_btn = $( '<div class="ui-scroll-jump-top-bg">' +
						'<div data-role="button" data-inline="true" data-icon="scrolltop" data-style="box"></div></div>' );
				$c.append( top_btn ).trigger("create");

				top_btn.bind( "vclick", function () {
					self.scrollTo( 0, 0, self.options.overshootDuration );
				} );
			}

			if ( this._hTracker ) {
				left_btn = $( '<div class="ui-scroll-jump-left-bg">' +
						'<div data-role="button" data-inline="true" data-icon="scrollleft" data-style="box"></div></div>' );
				$c.append( left_btn ).trigger("create");

				left_btn.bind( "vclick", function () {
					self.scrollTo( 0, 0, self.options.overshootDuration );
				} );
			}
		},

		/**
		 * Adds overflow indicator to DOM
		 * @private
		 */
		_add_overflow_indicator: function () {
			if ( !this.options.overflowEnable ) {
				return;
			}

			this._overflow_top = $( '<div class="ui-overflow-indicator-top"></div>' );
			this._overflow_bottom = $( '<div class="ui-overflow-indicator-bottom"></div>' );

			this._$clip.append( this._overflow_top );
			this._$clip.append( this._overflow_bottom );

			this._display_indicator_top = "block";
			this._display_indicator_bottom = "block";
			this._overflow_showed = false;
		},

		/**
		 * Sets the size of the scrollbars
		 * @private
		 */
		_set_scrollbar_size: function () {
			var $c = this._$clip,
				$v = this._$view,
				cw = 0,
				vw = 0,
				ch = 0,
				vh = 0,
				thumb;

			if ( !this.options.showScrollBars ) {
				return;
			}

			if ( this._hTracker ) {
				cw = $c.width();
				vw = $v.width();
				this._maxX = cw - vw;

				if ( this._maxX > 0 ) {
					this._maxX = 0;
				}
				if ( this._$hScrollBar && vw ) {
					thumb = this._$hScrollBar.find(".ui-scrollbar-thumb");
					thumb.css( "width", (cw >= vw ? "0" :
							(Math.floor(cw / vw * 100) || 1) + "%") );
				}
			}

			if ( this._vTracker ) {
				ch = $c.height();
				vh = this._getViewHeight();
				this._maxY = ch - vh;

				if ( this._maxY > 0 || vh === 0 ) {
					this._maxY = 0;
				}
				if ( ( this._$vScrollBar && vh ) || vh === 0 ) {
					thumb = this._$vScrollBar.find(".ui-scrollbar-thumb");
					thumb.css( "height", (ch >= vh ? "0" :
							(Math.floor(ch / vh * 100) || 1) + "%") );

					this._overflowAvail = !!thumb.height();
				}
			}
		}
	});

	/**
	 * Momentum tracker
	 */
	$.extend( MomentumTracker.prototype, {
		/**
		 * Starts momentum callculations
		 * @param {number} pos
		 * @param {number} speed
		 * @param {number} duration
		 * @param {number} minPos
		 * @param {number} maxPos
		 */
		start: function ( pos, speed, duration, minPos, maxPos ) {
			var tstate = ( pos < minPos || pos > maxPos ) ?
					tstates.snapback : tstates.scrolling,
				pos_temp;

			this.state = ( speed !== 0 ) ? tstate : tstates.done;
			this.pos = pos;
			this.speed = speed;
			this.duration = ( this.state === tstates.snapback ) ?
					this.options.snapbackDuration : duration;
			this.minPos = minPos;
			this.maxPos = maxPos;

			this.fromPos = ( this.state === tstates.snapback ) ? this.pos : 0;
			pos_temp = ( this.pos < this.minPos ) ? this.minPos : this.maxPos;
			this.toPos = ( this.state === tstates.snapback ) ? pos_temp : 0;

			this.startTime = getCurrentTime();
		},

		/**
		 * Resets momentum tracker calculations and sets
		 * state to done
		 */
		reset: function () {
			this.state = tstates.done;
			this.pos = 0;
			this.speed = 0;
			this.minPos = 0;
			this.maxPos = 0;
			this.duration = 0;
			this.remained = 0;
		},

		/**
		 * Recalculate momentum tracker estimates
		 * @param {boolean} overshootEnable
		 * @return {number} position
		 */
		update: function ( overshootEnable ) {
			var state = this.state,
				cur_time = getCurrentTime(),
				duration = this.duration,
				elapsed =  cur_time - this.startTime,
				dx,
				x,
				didOverShoot;

			if ( state === tstates.done ) {
				return this.pos;
			}

			elapsed = elapsed > duration ? duration : elapsed;

			this.remained = duration - elapsed;

			if ( state === tstates.scrolling || state === tstates.overshot ) {
				dx = this.speed *
					( 1 - $.easing[this.easing]( elapsed / duration,
								elapsed, 0, 1, duration ) );

				x = this.pos + dx;

				didOverShoot = ( state === tstates.scrolling ) &&
					( x < this.minPos || x > this.maxPos );

				if ( didOverShoot ) {
					x = ( x < this.minPos ) ? this.minPos : this.maxPos;
				}

				this.pos = x;

				if ( state === tstates.overshot ) {
					if ( !overshootEnable ) {
						this.state = tstates.done;
					}
					if ( elapsed >= duration ) {
						this.state = tstates.snapback;
						this.fromPos = this.pos;
						this.toPos = ( x < this.minPos ) ?
								this.minPos : this.maxPos;
						this.duration = this.options.snapbackDuration;
						this.startTime = cur_time;
						elapsed = 0;
					}
				} else if ( state === tstates.scrolling ) {
					if ( didOverShoot && overshootEnable ) {
						this.state = tstates.overshot;
						this.speed = dx / 2;
						this.duration = this.options.overshootDuration;
						this.startTime = cur_time;
					} else if ( elapsed >= duration ) {
						this.state = tstates.done;
					}
				}
			} else if ( state === tstates.snapback ) {
				if ( elapsed >= duration ) {
					this.pos = this.toPos;
					this.state = tstates.done;
				} else {
					this.pos = this.fromPos + (( this.toPos - this.fromPos ) *
						$.easing[this.easing]( elapsed / duration,
							elapsed, 0, 1, duration ));
				}
			}

			return this.pos;
		},

		/**
		 * Checks if momentum state is done
		 * @return {boolean}
		 */
		done: function () {
			return this.state === tstates.done;
		},

		/**
		 * Checks if the position is minimal
		 * @return {boolean}
		 */
		isMin: function () {
			return this.pos === this.minPos;
		},

		/**
		 * Checks if the position is maximal
		 * @return {boolean}
		 */
		isMax: function () {
			return this.pos === this.maxPos;
		},

		/**
		 * Check if momentum tracking is available
		 * @return {boolean}
		 */
		isAvail: function () {
			return !( this.minPos === this.maxPos );
		},

		/**
		 * Returns remaining time
		 * @return {number}
		 */
		getRemained: function () {
			return this.remained;
		},

		/**
		 * Returns current position
		 * @return {number}
		 */
		getPosition: function () {
			return this.pos;
		}
	});

	$( document ).bind( 'pagecreate create', function ( e ) {
		var $page = $( e.target ),
			content_scroll = $page.find(".ui-content").jqmData("scroll");

		/* content scroll */
		if ( $.support.scrollview === undefined ) {
			$.support.scrollview = true;
		}

		if ( $.support.scrollview === true && content_scroll === undefined ) {
			content_scroll = "y";
		}

		if ( content_scroll !== "y" ) {
			content_scroll = "none";
		}

		$page.find(".ui-content").attr( "data-scroll", content_scroll );

		$page.find(":jqmData(scroll)").not(".ui-scrollview-clip").each( function () {
			if ( $( this ).hasClass("ui-scrolllistview") ) {
				$( this ).scrolllistview();
			} else {
				var st = $( this ).jqmData("scroll"),
					dir = st && ( st.search(/^[xy]/) !== -1 ) ? st : null,
					content = $(this).hasClass("ui-content"),
					opts;

				if ( st === "none" ) {
					return;
				}

				opts = {
					direction: dir || undefined,
					overflowEnable: content,
					scrollMethod: $( this ).jqmData("scroll-method") || undefined,
					scrollJump: $( this ).jqmData("scroll-jump") || undefined
				};

				$( this ).scrollview( opts );
			}
		});
	});

	$( document ).bind( 'pageshow', function ( e ) {
		var $page = $( e.target ),
			scroll = $page.find(".ui-content").jqmData("scroll");

		if ( scroll === "y" ) {
			resizePageContentHeight( e.target );
		}
	});

}( jQuery, window, document ) );



/* ***************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 *
 *	Author: Minkyu Kang <mk7.kang@samsung.com>
 */

/*
 * Gallery widget
 *
 * HTML Attributes
 *
 *  data-role: set to 'gallery'
 *  data-index: start index
 *  data-vertical-align: set to top or middle or bottom.
 *
 * APIs
 *
 *  add(file): add the image (parameter: url of iamge)
 *  remove(index): remove the image (parameter: index of image)
 *  refresh(index): refresh the widget, should be called after add or remove. (parameter: start index)
 *  empty: remove all of images from the gallery
 *  length: get length of images
 *  value(index): get or set current index of gallery (parameter: index of image)
 *
 * Events
 *
 *  N/A
 *
 * Example
 *
 * <div data-role="gallery" id="gallery" data-index="3" data-vertical-align="middle">
 *	<img src="01.jpg">
 *	<img src="02.jpg">
 *	<img src="03.jpg">
 *	<img src="04.jpg">
 *	<img src="05.jpg">
 * </div>
 *
 *
 * $('#gallery-add').bind('vmouseup', function ( e ) {
 *	$('#gallery').gallery('add', '9.jpg');
 *	$('#gallery').gallery('add', '10.jpg');
 *	$('#gallery').gallery('refresh');
 * });
 *
 * $('#gallery-del').bind('vmouseup', function ( e ) {
 *	$('#gallery').gallery('remove');
 * });
 *
 */

 /**
	@class Gallery
	The gallery widget shows images in a gallery on the screen. <br/><br/> To add an gallery widget to the application, use the following code:

		<div data-role="gallery" id="gallery" data-vertical-align="middle" data-index="3">
			<img src="01.jpg">
			<img src="02.jpg">
			<img src="03.jpg">
			<img src="04.jpg">
			<img src="05.jpg">
		</div>
*/
/**
	@property {Integer} data-index
	Defines the index number of the first image in the gallery.
	<br/>The default value is 0.
*/
/**
	@property {String} data-vertical-align
	Defines the image alignment. The alignment options are top, middle, and bottom.
	<br/>The default value is top.
*/
/**
	@method add
	The add method is used to add an image to the gallery. The image_file attribute defines the image file URL.

		<div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
		$("#gallery").gallery('add', [image_file]);
*/
/**
	@method remove
	The remove method is used to delete an image from the gallery. The image_index attribute defines the index of the image to be deleted. If not set removes current image.

		<div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
		$("#gallery").gallery('remove', [image_index]);
*/
/**
	@method refresh
	The refresh method is used to refresh the gallery. This method must be called after adding images to the gallery.

		<div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
		$("#gallery").gallery('refresh');
*/
/**
	@method empty
	The empty method is used to remove all of images from the gallery.

		<div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
		$("#gallery").gallery('empty');
*/
/**
	@method length
	The length method is used to get length of images.

		<div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
		length = $("#gallery").gallery('length');
*/
/**
	@method value
	The value method is used to get or set current index of gallery. The image_index attribute defines the index of the image to be set. If not get current index.

		<div id="gallery" data-role="gallery" data-vertical-align="middle"></div>
		value = $("#gallery").gallery('value');
		$("#gallery").gallery('value', [image_index]);
*/
(function ( $, window, undefined ) {
	$.widget( "tizen.gallery", $.mobile.widget, {
		options: {
			flicking: false,
			duration: 500
		},

		dragging: false,
		moving: false,
		max_width: 0,
		max_height: 0,
		org_x: 0,
		org_time: null,
		cur_img: null,
		prev_img: null,
		next_img: null,
		images: [],
		images_hold: [],
		index: 0,
		align_type: null,
		direction: 1,
		container: null,
		orientationEventFire: false,

		_resize: function ( index ) {
			var img = this.images[index],
				width = this.images[index].width(),
				height = this.images[index].height(),
				margin = 0,
				ratio,
				img_max_width = this.max_width - margin,
				img_max_height = this.max_height - margin;

			ratio = height / width;

			if( img_max_width == 0 && isNaN( img_max_height ) ) {
				/*
				Exception : When image max width and height has incorrect value.
				This exception is occured when this.max_width value is 0 and this.max_height value is NaN when page transition like rotation.
				This exception affect that image width and height values are 0.
				*/
				img.width( width );
				img.height( width * ratio );
			} else {
				if ( width > img_max_width ) {
					img.width( img_max_width );
					img.height( img_max_width * ratio );
				}

				height = img.height();

				if ( height > img_max_height ) {
					img.height( img_max_height );
					img.width( img_max_height / ratio );
				}
			}
		},

		_align: function ( index, obj ) {
			var img = this.images[index],
				img_top = 0;

			if ( !obj ) {
				return;
			}
			if ( !obj.length ) {
				return;
			}

			if ( this.align_type == "middle" ) {
				img_top = ( this.max_height - img.height() ) / 2;
			} else if ( this.align_type == "bottom" ) {
				img_top = this.max_height - img.height();
			} else {
				img_top = 0;
			}

			obj.css( 'top', img_top + 'px' );
		},

		_attach: function ( index, obj ) {
			var self = this,
				processing = function () {
					self._resize( index );
					self._align( index, obj );

				},
				loading = function () {
					if ( self.images[index] === undefined ) {
						return;
					}

					if ( !self.images[index].height() ) {
						setTimeout( loading, 10 );
						return;
					}

					processing();
				};

			if ( !obj ) {
				return;
			}
			if ( !obj.length ) {
				return;
			}
			if ( index < 0 ) {
				return;
			}
			if ( !this.images.length ) {
				return;
			}
			if ( index >= this.images.length ) {
				return;
			}

			obj.css( "display", "block" );
			obj.css( "visibility", "hidden" );
			obj.append( this.images[index] );
			loading();
		},

		_detach: function ( index, obj ) {
			if ( !obj ) {
				return;
			}
			if ( !obj.length ) {
				return;
			}
			if ( index < 0 ) {
				return;
			}
			if ( index >= this.images.length ) {
				return;
			}

			obj.css( "display", "none" );
			this.images[index].removeAttr("style");
			this.images[index].detach();
		},

		_detach_all: function () {
			var i;

			for ( i = 0; i < this.images.length; i++ ) {
				this.images[i].detach();
			}
		},

		_drag: function ( _x ) {
			var delta,
				coord_x;

			if ( !this.dragging ) {
				return;
			}

			if ( this.options.flicking === false ) {
				delta = this.org_x - _x;

				// first image
				if ( delta < 0 && !this.prev_img.length ) {
					return;
				}
				// last image
				if ( delta > 0 && !this.next_img.length ) {
					return;
				}
			}

			coord_x = _x - this.org_x;

			this._moveLeft( this.cur_img , coord_x + 'px' );
			if ( this.next_img.length ) {
				this._moveLeft( this.next_img ,  coord_x + this.window_width + 'px' );
			}
			if ( this.prev_img.length ) {
				this._moveLeft( this.prev_img ,  coord_x - this.window_width + 'px' );
			}
		},

		_move: function ( _x ) {
			var delta = this.org_x - _x,
				flip = 0,
				drag_time,
				sec,
				self;

			if ( delta == 0 ) {
				return;
			}

			if ( delta > 0 ) {
				flip = delta < ( this.max_width * 0.45 ) ? 0 : 1;
			} else {
				flip = -delta < ( this.max_width * 0.45 ) ? 0 : 1;
			}

			if ( !flip ) {
				drag_time = Date.now() - this.org_time;

				if ( Math.abs( delta ) / drag_time > 1 ) {
					flip = 1;
				}
			}

			if ( flip ) {
				if ( delta > 0 && this.next_img.length ) {
					/* next */
					this._detach( this.index - 1, this.prev_img );

					this.prev_img = this.cur_img;
					this.cur_img = this.next_img;
					this.next_img = this.next_img.next();

					this.index++;

					if ( this.next_img.length ) {
						this._moveLeft( this.next_img ,  this.window_width + 'px' );
						this._attach( this.index + 1, this.next_img );
					}

					this.direction = 1;

				} else if ( delta < 0 && this.prev_img.length ) {
					/* prev */
					this._detach( this.index + 1, this.next_img );

					this.next_img = this.cur_img;
					this.cur_img = this.prev_img;
					this.prev_img = this.prev_img.prev();

					this.index--;

					if ( this.prev_img.length ) {
						this._moveLeft( this.prev_img , -this.window_width + 'px' );
						this._attach( this.index - 1, this.prev_img );
					}

					this.direction = -1;
				}
			}

			sec = this.options.duration;
			self = this;

			this.moving = true;

			setTimeout( function () {
				self.moving = false;
			}, sec - 25 );

			this._moveLeft( this.cur_img, 0 + 'px', sec );
			if ( this.next_img.length ) {
				this._moveLeft( this.next_img, this.window_width + 'px', sec );
			}
			if ( this.prev_img.length ) {
				this._moveLeft( this.prev_img, -this.window_width + 'px', sec );
			}
		},

		_add_event: function () {
			var self = this,
				date;

			this.container.bind( 'vmousemove', function ( e ) {
				e.preventDefault();

				if ( self.moving ) {
					return;
				}
				if ( !self.dragging ) {
					return;
				}

				self._drag( e.pageX );
			} );

			this.container.bind( 'vmousedown', function ( e ) {
				e.preventDefault();

				if ( self.moving ) {
					return;
				}

				self.dragging = true;

				self.org_x = e.pageX;

				self.org_time = Date.now();
			} );

			this.container.bind( 'vmouseup', function ( e ) {
				if ( self.moving ) {
					return;
				}

				self.dragging = false;

				self._move( e.pageX );
			} );

			this.container.bind( 'vmouseout', function ( e ) {
				if ( self.moving ) {
					return;
				}
				if ( !self.dragging ) {
					return;
				}

				if ( ( e.pageX < 20 ) ||
						( e.pageX > ( self.max_width - 20 ) ) ) {
					self._move( e.pageX );
					self.dragging = false;
				}
			} );
		},

		_del_event: function () {
			this.container.unbind( 'vmousemove' );
			this.container.unbind( 'vmousedown' );
			this.container.unbind( 'vmouseup' );
			this.container.unbind( 'vmouseout' );
		},
		_setTranslateposition : function ( $ele, value ) {
			var translate,
				cssArray = null,
				self = this;

			if ( $.support.cssTransform3d ) {
				translate = "translate3d(" + value + ", 0px, 0px)";
			} else {
				translate = "translate(" + value + ", 0px)";
			}
			cssArray = {"-moz-transform": translate,
					"-webkit-transform": translate,
					"-ms-transform": translate,
					"-o-transform": translate,
					"transform": translate};

			$ele.css(cssArray);
			return $ele;
		},
		_hidePrevNext : function() {
			var self = this;

			if( self.next_img ) {
				self.next_img.css( "visibility", "hidden" );
			}
			if( self.prev_img ) {
				self.prev_img.css( "visibility", "hidden" );
			}

		},
		_hideCur : function() {
			var self = this;
			if( self.cur_img ) {
				self.cur_img.css( "visibility", "hidden" );
			}
		},
		_moveLeft : function ( $ele , value , duration ) {
			var translate,
				transition = "",
				cssArray = null,
				self = this;

			if ( $.support.cssTransform3d ) {
				translate = "translate3d(" + value + ", 0px, 0px)";
			} else {
				translate = "translate(" + value + ", 0px)";
			}
			if( duration !== undefined ) {
				transition =  "-webkit-transform " + (duration / 1000)+ "s ease";
			}
			cssArray = {"-moz-transform": translate,
					"-webkit-transform": translate,
					"-ms-transform": translate,
					"-o-transform": translate,
					"transform": translate};
			if( transition !== "" ) {
				cssArray["-webkit-transition"] = transition ;
				if( value == "0px" ) {
					$ele.one( 'webkitTransitionEnd', self._hidePrevNext );
				} else {
					$ele.one( 'webkitTransitionEnd', self._hideCur );
				}
			}
			if( value == "0px" ) {
				$ele.css( "visibility", "visible" );
			}

			$ele.css(cssArray);
			return $ele;
		},
		_show: function () {
			/* resizing */
			this.window_width = $( window ).width();
			this.max_width = this._get_width();
			this.max_height = this._get_height();
			this.container.css( 'height', this.max_height );

			this.cur_img = $( 'div' ).find( '.ui-gallery-bg:eq(' + this.index + ')' );
			this.prev_img = this.cur_img.prev();
			this.next_img = this.cur_img.next();

			this._attach( this.index - 1, this.prev_img );
			this._attach( this.index, this.cur_img );
			this._attach( this.index + 1, this.next_img );

			this.cur_img.css( 'visibility', 'visible' );
			if ( this.prev_img.length ) {
				this._setTranslateposition( this.prev_img, -this.window_width + 'px');
			}

			this._moveLeft( this.cur_img, '0px');
			if ( this.next_img.length ) {
				this._setTranslateposition( this.next_img, this.window_width + 'px' );
			}
		},

		show: function () {
			if ( !this.images.length ) {
				return;
			}

			this._show();
			this._add_event();
		},

		_hide: function () {
			this._detach( this.index - 1, this.prev_img );
			this._detach( this.index, this.cur_img );
			this._detach( this.index + 1, this.next_img );
		},

		hide: function () {
			this._hide();
			this._del_event();
		},

		_get_width: function () {
			return $( this.element ).width();
		},

		_get_height: function () {
			var $page = $( this.element ).parentsUntil( 'ui-page' ),
				$content = $page.children( '.ui-content' ),
				header_h = $page.children( '.ui-header' ).outerHeight() || 0,
				footer_h = $page.children( '.ui-footer' ).outerHeight() || 0,
				padding = parseFloat( $content.css( 'padding-top' ) )
					+ parseFloat( $content.css( 'padding-bottom' ) ),
				content_h = $( window ).height() - header_h - footer_h - padding;

			return content_h;
		},

		_create: function () {
			var temp_img,
				self = this,
				index,
				i = 0;

			$( this.element ).wrapInner( '<div class="ui-gallery"></div>' );
			$( this.element ).find( 'img' ).wrap( '<div class="ui-gallery-bg"></div>' );

			this.container = $( this.element ).find('.ui-gallery');

			temp_img = $( 'div' ).find( '.ui-gallery-bg:first' );

			while ( temp_img.length ) {
				this.images[i] = temp_img.find( 'img' );
				temp_img = temp_img.next();
				i++;
			}

			this._detach_all();

			index = parseInt( $( this.element ).jqmData( 'index' ), 10 );
			if ( !index ) {
				index = 0;
			}
			if ( index < 0 ) {
				index = 0;
			}
			if ( index >= this.images.length ) {
				index = this.images.length - 1;
			}

			this.index = index;

			this.align_type = $( this.element ).jqmData( 'vertical-align' );

			$.extend( this, {
				_globalHandlers: [
					{
						src: $( window ),
						handler: {
							orientationchange: $.proxy( this, "_orientationHandler" ),
							resize: $.proxy( this, "_resizeHandler" )
						}
					}
				]
			});

			$.each( this._globalHandlers, function( idx, value ) {
				value.src.bind( value.handler );
			});
		},

		_update: function () {
			var image_file,
				bg_html,
				temp_img;

			while ( this.images_hold.length ) {
				image_file = this.images_hold.shift();

				bg_html = $( '<div class="ui-gallery-bg"></div>' );
				temp_img = $( '<img src="' + image_file + '"></div>' );

				bg_html.append( temp_img );
				this.container.append( bg_html );
				this.images.push( temp_img );
			}

			this._detach_all();
		},
		_resizeHandler: function() {
			var self = this;
			if( self.orientationEventFire ) {
				self.refresh();
				$( event.target ).trigger( "galleryorientationchanged", this );
				self.orientationEventFire = false;
			}
		},
		_orientationHandler: function() {
			var self = this;
			self.refresh();
			self.orientationEventFire = true;
		},
		refresh: function ( start_index ) {
			this._update();

			this._hide();

			if ( start_index === undefined ) {
				start_index = this.index;
			}
			if ( start_index < 0 ) {
				start_index = 0;
			}
			if ( start_index >= this.images.length ) {
				start_index = this.images.length - 1;
			}

			this.index = start_index;

			this._show();

			return this.index;
		},

		add: function ( file ) {
			this.images_hold.push( file );
		},

		remove: function ( index ) {
			var temp_img;

			if ( index === undefined ) {
				index = this.index;
			}

			if ( index < 0 || index >= this.images.length ) {
				return;
			}

			if ( index == this.index ) {
				temp_img = this.cur_img;

				if ( this.index == 0 ) {
					this.direction = 1;
				} else if ( this.index == this.images.length - 1 ) {
					this.direction = -1;
				}

				if ( this.direction < 0 ) {
					this.cur_img = this.prev_img;
					this.prev_img = this.prev_img.prev();
					if ( this.prev_img.length ) {
						this._moveLeft( this.prev_img, -this.window_width + 'px' );
						this._attach( index - 2, this.prev_img );
					}
					this.index--;
				} else {
					this.cur_img = this.next_img;
					this.next_img = this.next_img.next();
					if ( this.next_img.length ) {
						this._moveLeft( this.next_img, this.window_width + 'px' );
						this._attach( index + 2, this.next_img );
					}
				}
				this._moveLeft( this.cur_img, '0px', this.options.duration );

			} else if ( index == this.index - 1 ) {
				temp_img = this.prev_img;
				this.prev_img = this.prev_img.prev();
				if ( this.prev_img.length ) {
					this._moveLeft( this.prev_img, -this.window_width + 'px' );
					this._attach( index - 1, this.prev_img );
				}
				this.index--;

			} else if ( index == this.index + 1 ) {
				temp_img = this.next_img;
				this.next_img = this.next_img.next();
				if ( this.next_img.length ) {
					this._moveLeft( this.next_img, this.window_width + 'px' );
					this._attach( index + 1, this.next_img );
				}

			} else {
				temp_img = $( 'div' ).find( '.ui-gallery-bg:eq(' + index + ')' );
			}

			this.images.splice( index, 1 );
			temp_img.detach();
		},

		empty: function () {
			this.images.splice( 0, this.images.length );
			this.container.find('.ui-gallery-bg').detach();
		},

		length: function () {
			return this.images.length;
		},

		value: function ( index ) {
			if ( index === undefined ) {
				return this.index;
			}

			this.refresh( index );
		},

		unbind: function() {
			$.each( this._globalHandlers, function( idx, value ) {
				value.src.unbind( value.handler );
			});
		},

		destory: function() {
			this.unbind();
		}

	}); /* End of widget */

	// auto self-init widgets
	$( document ).bind( "pagecreate create", function ( e ) {
		$( e.target ).find( ":jqmData(role='gallery')" ).gallery();
	});

	$( document ).bind( "pageshow", function ( e ) {
		$( e.target ).find( ":jqmData(role='gallery')" ).gallery( 'show' );
	});

	$( document ).bind( "pagebeforehide", function ( e ) {
		$( e.target ).find( ":jqmData(role='gallery')" ).gallery( 'hide' );
	} );

	$( document ).bind( "pageremove", function ( e ) {
		//unbind resize and orientationchange events
		$( e.target ).find( ":jqmData(role='gallery')" ).gallery( 'unbind' );
	});

}( jQuery, this ) );



/* ***************************************************************************
* style : normal, check
* option :
*    - folded : decide to show divider press effect or not
*    - line : decide to draw divider line or not
*/
/**
	@class ListDivider
	The list divider widget is used as a list separator for grouping lists. List dividers can be used in Tizen as described in the jQueryMobile documentation for list dividers.<br/>
	To add a list divider widget to the application, use the following code:

		<li data-role="list-divider" data-style="check">
		<form><input type="checkbox" name="c2line-check1" /></form></li>

	The list divider can define callbacks for events as described in the jQueryMobile documentation for list events. <br/> You can use methods with the list divider as described in the jQueryMobile documentation for list methods.

	@since tizen2.0	
*/
/**
	@property {String} data-style
	Sets the style of the list divider. The style options are dialogue, check, expandable, and checkexpandable.
*/

(function ( $, undefined ) {
	$.widget( "tizen.listdivider", $.mobile.widget, {
		options: {
			initSelector: ":jqmData(role='list-divider')",
			folded : false,
			listDividerLine : true
		},

		_create: function () {

			var $listdivider = this.element,
				openStatus = true,
				expandSrc,
				listDividerLine = true,
				style = $listdivider.attr( "data-style" );

			if ( $listdivider.data("line") === false ) {
				this.options.listDividerLine = false;
			}

			if ( $listdivider.data("folded") === true ) {
				this.options.folded = true;
			}

			if ( style == undefined || style === "normal" || style === "check" ) {
				if ( this.options.folded ) {
					$listdivider.buttonMarkup();
				} else {
					$listdivider.wrapInner("<span class='ui-btn-text'></span>");
				}

				if ( this.options.listDividerLine ) {
					expandSrc = "<span class='ui-divider-normal-line'></span>";
					if ( this.options.folded ) {
						$( expandSrc ).appendTo( $listdivider.children( ".ui-btn-inner" ) );
					} else {
						$( expandSrc ).appendTo( $listdivider);
					}
				}
			}

			$listdivider.bind( "vclick", function ( event, ui ) {
			/* need to implement expand/collapse divider */
			});
		}
	});

	//auto self-init widgets
	$( document ).bind( "pagecreate create", function ( e ) {
		$( $.tizen.listdivider.prototype.options.initSelector, e.target ).listdivider();
	});
}( jQuery ) );



/* ***************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 *
 * Authors: Yonghwi Park <yonghwi0324.park@samsung.com>
 *		 Wonseop Kim <wonseop.kim@samsung.com>
*/

/**
 *
 * MultiMediaView is a widget that lets the user view and handle multimedia contents.
 * Video and audio elements are coded as standard HTML elements and enhanced by the 
 * MultiMediaview to make them attractive and usable on a mobile device.
 *
 * HTML Attributes:
 *			data-theme : Set a theme of widget.
 *				If this value is not defined, widget will use parent`s theme. (optional)
 *			data-controls : If this value is 'true', widget will use belonging controller.
 *				If this value is 'false', widget will use browser`s controller.
 *				Default value is 'true'.
 *			data-full-screen : Set a status that full-screen when inital start.
 *				Default value is 'false'.
 *
 * APIs:
 *			width( [number] )
 *					: Get or set the width of widget.
 *					The first argument is the width of widget.
 *					If no first argument is specified, will act as a getter.
 *			height( [number] )
 *					: Get or set the height of widget.
 *					The first argument is the height of widget.
 *					If no first argument is specified, will act as a getter.
 *			fullScreen( [boolean] )
 *					: Get or Set the status of full-screen.
 *					If no first argument is specified, will act as a getter.
 *
 * Events:
 *
 *			N/A
 *
 * Examples:
 *
 *			VIDEO :
 *				<video data-controls="true" style="width:100%;">
 *					<source src="media/oceans-clip.mp4" type="video/mp4" />
 *					Your browser does not support the video tag.
 *				</video>
 *
 *			AUDIO :
 *				<audio data-controls="true" style="width:100%;">
 *					<source src="media/Over the horizon.mp3" type="audio/mp3" />
 *					Your browser does not support the audio tag.
 *				</audio>
 *
 */
/**
	@class MutimediaView
	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.

	To add a multimedia view widget to the application, use the following code:
	
		// Video player control
		<video data-controls="true" style="width:100%;">
		<source src="<VIDEO_FILE_URL>" type="video/mp4" /> Your browser does not support the video tag. </video>
		// Audio player control
		<audio data-controls="true" style="width:100%;"> <source src="<AUDIO_FILE_URL>" type="audio/mp3" /> Your browser does not support the audio tag.
		</audio>
*/
/**
	@property {Boolean} data-control
	Sets the controls for the widget.
	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.
*/
/**
	@property {Boolean} data-full-screen
	Defines whether the widget opens in the fullscreen view mode.
	The default value is false.
*/
/**
	@property {String} data-theme
	Sets the widget theme.
	If the value is not set, the parent control's theme is used
*/
/**
	@method width
	The width method is used to get (if no value is defined) or set the multimedia view widget width:
		<video>
			 <source src="test.mp4" type="video/mp4" />
		</video>
		$(".selector").multimediaview("width", [value]);
*/
/**
	@method height
	The height method is used to get (if no value is defined) or set the multimedia view widget height:
		<video>
			<source src="test.mp4" type="video/mp4" />
		</video>
		$(".selector").multimediaview("height", [value]);
*/
/**
	@method fullScreen
	The fullScreen method is used to get (if no value is defined) or set the full-screen mode of the multimedia view widget. If the value is true, the full-screen mode is used; otherwise the multimedia view widget runs in the normal mode.

		<video>
			<source src="test.mp4" type="video/mp4" />
		</video>
		$(".selector").multimediaview("fullScreen", [value]);
*/
( function ( $, document, window, undefined ) {
	$.widget( "tizen.multimediaview", $.mobile.widget, {
		options: {
			theme: null,
			controls: true,
			fullScreen: false,
			initSelector: "video, audio"
		},

		_create: function () {
			var self = this,
				view = self.element,
				viewElement = view[0],
				isVideo = ( viewElement.nodeName === "VIDEO" ),
				option = self.options,
				parentTheme = $.mobile.getInheritedTheme( view, "s" ),
				theme = option.theme || parentTheme,
				width = viewElement.style.getPropertyValue( "width" ) || "",
				wrap = $( "<div class='ui-multimediaview-wrap ui-multimediaview-" + theme + "'>" ),
				control = null;

			$.extend( this, {
				role: null,
				controlTimer: null,
				isVolumeHide: true,
				backupView: null,
				_reserveVolume: -1,
				_isVideo: isVideo
			});

			view.addClass( "ui-multimediaview" );
			control = self._createControl();
			control.hide();

			$( ".ui-button", control ).addClass( "ui-shadow ui-btn-corner-all" );
			$( ".ui-volumecontrol .ui-handle", control ).addClass( "ui-shadow ui-btn-corner-circle" );

			view.wrap( wrap ).after( control );

			if ( isVideo ) {
				control.addClass( "ui-multimediaview-video" );
			} else {
				self.width( width );
				self.options.fullScreen = false;
			}

			if ( option.controls && view.attr( "controls" ) ) {
				view.removeAttr( "controls" );
			}

			self._addEvent();
		},

		_resize: function () {
			this._resizeFullscreen( this.options.fullScreen );
			this._resizeControl();
			this._updateSeekBar();
			this._updateVolumeState();
		},

		_resizeControl: function () {
			var self = this,
				view = self.element,
				viewElement = view[0],
				isVideo = self._isVideo,
				wrap = view.parent( ".ui-multimediaview-wrap" ),
				control = wrap.find( ".ui-multimediaview-control" ),
				buttons = control.find( ".ui-button" ),
				playpauseButton = control.find( ".ui-playpausebutton" ),
				seekBar = control.find( ".ui-seekbar" ),
				durationLabel = control.find( ".ui-durationlabel" ),
				timestampLabel = control.find( ".ui-timestamplabel" ),
				volumeControl = control.find( ".ui-volumecontrol" ),
				volumeBar = volumeControl.find( ".ui-volumebar" ),
				width = ( isVideo ? view.width() : wrap.width() ),
				height = ( isVideo ? view.height() : control.height() ),
				offset = view.offset(),
				controlHeight = control.height(),
				availableWidth = 0,
				controlOffset = null;

			if ( control ) {
				if ( isVideo ) {
					controlOffset = control.offset();
					controlOffset.left = offset.left;
					controlOffset.top = offset.top + height - controlHeight;
					control.offset( controlOffset );
				}
				control.width( width );
			}

			if ( seekBar ) {
				availableWidth = control.width() - ( buttons.outerWidth( true ) * buttons.length );
				availableWidth -= ( parseInt( buttons.eq( 0 ).css( "margin-left" ), 10 ) + parseInt( buttons.eq( 0 ).css( "margin-right" ), 10 ) ) * buttons.length;
				if ( !self.isVolumeHide ) {
					availableWidth -= volumeControl.outerWidth( true );
				}
				seekBar.width( availableWidth );
			}

			if ( durationLabel && !isNaN( viewElement.duration ) ) {
				durationLabel.find( "p" ).text( self._convertTimeFormat( viewElement.duration ) );
			}

			if ( viewElement.autoplay && viewElement.paused === false ) {
				playpauseButton.removeClass( "ui-play-icon" ).addClass( "ui-pause-icon" );
			}

			if ( seekBar.width() < ( volumeBar.width() + timestampLabel.width() + durationLabel.width() ) ) {
				durationLabel.hide();
			} else {
				durationLabel.show();
			}
		},

		_resizeFullscreen: function ( isFullscreen ) {
			if ( !this._isVideo ) {
				return;
			}

			var self = this,
				view = self.element,
				viewElement = view[0],
				wrap = view.parent( ".ui-multimediaview-wrap" ),
				control = wrap.find( ".ui-multimediaview-control" ),
				fullscreenButton = control.find( ".ui-fullscreenbutton" ),
				currentPage = $( ".ui-page-active" ),
				playpauseButton = control.find( ".ui-playpausebutton" ),
				timestampLabel = control.find( ".ui-timestamplabel" ),
				seekBar = control.find( ".ui-seekbar" ),
				durationBar = seekBar.find( ".ui-duration" ),
				currenttimeBar = seekBar.find( ".ui-currenttime" ),
				body = $( "body" )[0],
				header = currentPage.children( ".ui-header" ),
				footer = currentPage.children( ".ui-footer" ),
				docWidth = 0,
				docHeight = 0;

			if ( isFullscreen ) {
				if ( !self.backupView ) {
					self.backupView = {
						width: viewElement.style.getPropertyValue( "width" ) || "",
						height: viewElement.style.getPropertyValue( "height" ) || "",
						position: view.css( "position" ),
						zindex: view.css( "z-index" ),
						wrapHeight: wrap[0].style.getPropertyValue( "height" ) || ""
					};
				}
				docWidth = body.clientWidth;
				docHeight = body.clientHeight - 1;

				header.hide();
				footer.hide();
				view.parents().each( function ( e ) {
					var element = $( this );
					element.addClass( "ui-fullscreen-parents" )
						.siblings()
						.addClass( "ui-multimediaview-siblings-off" );
				});
				fullscreenButton.removeClass( "ui-fullscreen-on" ).addClass( "ui-fullscreen-off" );

				wrap.height( docHeight );
				view.width( docWidth ).height( docHeight );
			} else {
				if ( !self.backupView ) {
					return;
				}

				header.show();
				footer.show();
				view.parents().each( function ( e ) {
					var element = $( this );
					element.removeClass( "ui-fullscreen-parents" )
						.siblings()
						.removeClass( "ui-multimediaview-siblings-off" );
				});

				fullscreenButton.removeClass( "ui-fullscreen-off" ).addClass( "ui-fullscreen-on" );

				wrap.css( "height", self.backupView.wrapHeight );
				view.css( {
					"width": self.backupView.width,
					"height": self.backupView.height,
					"position": self.backupView.position,
					"z-index": self.backupView.zindex
				});
				self.backupView = null;

				$( window ).trigger( "throttledresize" );
			}
		},

		_addEvent: function () {
			var self = this,
				view = self.element,
				option = self.options,
				viewElement = view[0],
				isVideo = self._isVideo,
				control = view.parent( ".ui-multimediaview-wrap" ).find( ".ui-multimediaview-control" ),
				playpauseButton = control.find( ".ui-playpausebutton" ),
				timestampLabel = control.find( ".ui-timestamplabel" ),
				durationLabel = control.find( ".ui-durationlabel" ),
				volumeButton = control.find( ".ui-volumebutton" ),
				volumeControl = control.find( ".ui-volumecontrol" ),
				volumeBar = volumeControl.find( ".ui-volumebar" ),
				volumeGuide = volumeControl.find( ".ui-guide" ),
				volumeHandle = volumeControl.find( ".ui-handle" ),
				fullscreenButton = control.find( ".ui-fullscreenbutton" ),
				seekBar = control.find( ".ui-seekbar" ),
				durationBar = seekBar.find( ".ui-duration" ),
				currenttimeBar = seekBar.find( ".ui-currenttime" ),
				touchStartEvt = ( $.support.touch ? "touchstart" : "mousedown" ),
				touchMoveEvt = ( $.support.touch ? "touchmove" : "mousemove" ) + ".multimediaview",
				touchEndEvt = ( $.support.touch ? "touchend" : "mouseup" ) + ".multimediaview",
				$document = $( document );

			view.bind( "loadedmetadata.multimediaview", function ( e ) {
				if ( !isNaN( viewElement.duration ) ) {
					durationLabel.find( "p" ).text( self._convertTimeFormat( viewElement.duration ) );
				}
				self._resize();
			}).bind( "timeupdate.multimediaview", function ( e ) {
				self._updateSeekBar();
			}).bind( "play.multimediaview", function ( e ) {
				playpauseButton.removeClass( "ui-play-icon" ).addClass( "ui-pause-icon" );
			}).bind( "pause.multimediaview", function ( e ) {
				playpauseButton.removeClass( "ui-pause-icon" ).addClass( "ui-play-icon" );
			}).bind( "ended.multimediaview", function ( e ) {
				if ( typeof viewElement.loop == "undefined" || viewElement.loop === "" ) {
					self.stop();
				}
			}).bind( "volumechange.multimediaview", function ( e ) {
				if ( viewElement.muted && viewElement.volume > 0.1 ) {
					volumeButton.removeClass( "ui-volume-icon" ).addClass( "ui-mute-icon" );
					self._reserveVolume = viewElement.volume;
					viewElement.volume = 0;
				} else if ( self._reserveVolume !== -1 && !viewElement.muted ) {
					volumeButton.removeClass( "ui-mute-icon" ).addClass( "ui-volume-icon" );
					viewElement.volume = self._reserveVolume;
					self._reserveVolume = -1;
				} else if ( viewElement.volume < 0.1 ) {
					volumeButton.removeClass( "ui-volume-icon" ).addClass( "ui-mute-icon" );
				} else {
					volumeButton.removeClass( "ui-mute-icon" ).addClass( "ui-volume-icon" );
				}

				if ( !self.isVolumeHide ) {
					self._updateVolumeState();
				}
			}).bind( "durationchange.multimediaview", function ( e ) {
				if ( !isNaN( viewElement.duration ) ) {
					durationLabel.find( "p" ).text( self._convertTimeFormat( viewElement.duration ) );
				}
				self._resize();
			}).bind( "click.multimediaview", function ( e ) {
				if ( !self.options.controls ) {
					return;
				}

				control.fadeToggle( "fast" );
				self._resize();
			}).bind( "multimediaviewinit", function ( e ) {
				if ( option.controls ) {
					control.show();
				}
				self._resize();
			});

			$( ".ui-button", control ).bind( touchStartEvt, function () {
				var button = $( this ).addClass( "ui-button-down" );

				$document.bind( touchMoveEvt, function () {
					button.trigger( touchEndEvt );
				});
			}).bind( touchEndEvt, function () {
				$( this ).removeClass( "ui-button-down" );
				$document.unbind( touchMoveEvt );
			});

			playpauseButton.bind( "click.multimediaview", function () {
				self._endTimer();

				if ( viewElement.paused ) {
					viewElement.play();
				} else {
					viewElement.pause();
				}

				if ( isVideo ) {
					self._startTimer();
				}
			});

			fullscreenButton.bind( "click.multimediaview", function ( e ) {
				e.preventDefault();
				self.fullScreen( !self.options.fullScreen );
				self._resize();
				self._endTimer();
				e.stopPropagation();
			});

			seekBar.bind( touchStartEvt, function ( e ) {
				var x = $.support.touch ? e.originalEvent.changedTouches[0].pageX : e.pageX,
					duration = viewElement.duration,
					durationOffset = durationBar.offset(),
					durationWidth = durationBar.width(),
					timerate = ( x - durationOffset.left ) / durationWidth,
					time = duration * timerate;

				if ( !viewElement.played.length ) {
					return;
				}

				viewElement.currentTime = time;

				self._endTimer();

				e.preventDefault();

				control.bind( touchMoveEvt, function ( e ) {
					var x = $.support.touch ? e.originalEvent.changedTouches[0].pageX : e.pageX,
						timerate = ( x - durationOffset.left ) / durationWidth;

					viewElement.currentTime = duration * timerate;

					e.stopPropagation();
				}).bind( touchEndEvt, function () {
					control.unbind( ".multimediaview" );
					$document.unbind( touchMoveEvt );
					if ( viewElement.paused ) {
						viewElement.pause();
					} else {
						viewElement.play();
					}
					e.stopPropagation();
				});

				$document.bind( touchMoveEvt, function () {
					control.trigger( touchEndEvt );
				});
			});

			volumeButton.bind( "click.multimediaview", function () {
				if ( self.isVolumeHide ) {
					var view = self.element,
						volume = viewElement.volume;

					self.isVolumeHide = false;
					volumeControl.fadeIn( "fast", function () {
						self._updateVolumeState();
						self._updateSeekBar();
					});
					self._resize();
				} else {
					self.isVolumeHide = true;
					volumeControl.fadeOut( "fast", function () {
						self._resize();
					});
				}
			});

			volumeBar.bind( touchStartEvt, function ( e ) {
				var baseX = $.support.touch ? e.originalEvent.changedTouches[0].pageX : e.pageX,
					volumeGuideLeft = volumeGuide.offset().left,
					volumeGuideWidth = volumeGuide.width(),
					volumeBase = volumeGuideLeft + volumeGuideWidth,
					handlerOffset = volumeHandle.offset(),
					volumerate = ( baseX - volumeGuideLeft ) / volumeGuideWidth,
					currentVolume = ( baseX - volumeGuideLeft ) / volumeGuideWidth;

				self._endTimer();
				volumeHandle.addClass( "ui-button-down" );
				self._setVolume( currentVolume.toFixed( 2 ) );

				e.preventDefault();

				control.bind( touchMoveEvt, function ( e ) {
					var x = $.support.touch ? e.originalEvent.changedTouches[0].pageX : e.pageX,
						currentVolume = ( x - volumeGuideLeft );
					currentVolume = ( currentVolume < 0 ) ? 0 : currentVolume / volumeGuideWidth;
					self._setVolume( ( currentVolume > 1 ) ? 1 : currentVolume.toFixed( 2 ) );

					e.stopPropagation();
				}).bind( touchEndEvt, function () {
					control.unbind( ".multimediaview" );
					$document.unbind( touchMoveEvt );
					volumeHandle.removeClass( "ui-button-down" );
					e.stopPropagation();
				});

				$document.bind( touchMoveEvt, function () {
					control.trigger( touchEndEvt );
				});
			});
		},

		_removeEvent: function () {
			var view = this.element,
				control = view.parent( ".ui-multimediaview-wrap" ).find( ".ui-multimediaview-control" ),
				playpauseButton = control.find( ".ui-playpausebutton" ),
				fullscreenButton = control.find( ".ui-fullscreenbutton" ),
				seekBar = control.find( ".ui-seekbar" ),
				volumeControl = control.find( ".ui-volumecontrol" ),
				volumeBar = volumeControl.find( ".ui-volumebar" ),
				volumeHandle = volumeControl.find( ".ui-handle" );

			view.unbind( ".multimediaview" );
			playpauseButton.unbind( ".multimediaview" );
			fullscreenButton.unbind( ".multimediaview" );
			seekBar.unbind( ".multimediaview" );
			volumeBar.unbind( ".multimediaview" );
			volumeHandle.unbind( ".multimediaview" );
		},

		_createControl: function () {
			var view = this.element,
				viewElement = view[0],
				control = $( "<span></span>" ).addClass( "ui-multimediaview-control" ),
				playpauseButton = $( "<span></span>" ).addClass( "ui-playpausebutton ui-button ui-play-icon" ),
				seekBar = $( "<span></span>" ).addClass( "ui-seekbar ui-multimediaview-bar" ),
				timestampLabel = $( "<span><p>00:00:00</p></span>" ).addClass( "ui-timestamplabel" ),
				durationLabel = $( "<span><p>00:00:00</p></span>" ).addClass( "ui-durationlabel" ),
				volumeButton = $( "<span></span>" ).addClass( "ui-volumebutton ui-button" ),
				volumeControl = $( "<span></span>" ).addClass( "ui-volumecontrol" ),
				volumeBar = $( "<div></div>" ).addClass( "ui-volumebar ui-multimediaview-bar" ),
				volumeGuide = $( "<span></span>" ).addClass( "ui-guide ui-multimediaview-bar-bg" ),
				volumeValue = $( "<span></span>" ).addClass( "ui-value ui-multimediaview-bar-highlight" ),
				volumeHandle = $( "<span></span>" ).addClass( "ui-handle" ),
				fullscreenButton = $( "<span></span>" ).addClass( "ui-fullscreenbutton ui-button" ),
				durationBar = $( "<span></span>" ).addClass( "ui-duration ui-multimediaview-bar-bg" ),
				currenttimeBar = $( "<span></span>" ).addClass( "ui-currenttime ui-multimediaview-bar-highlight" );

			seekBar.append( durationBar ).append( currenttimeBar ).append( durationLabel ).append( timestampLabel );

			volumeButton.addClass( viewElement.muted ? "ui-mute-icon" : "ui-volume-icon" );
			volumeBar.append( volumeGuide ).append( volumeValue ).append( volumeHandle );
			volumeControl.append( volumeBar );

			control.append( playpauseButton ).append( seekBar ).append( volumeControl ).append( volumeButton );

			if ( this._isVideo ) {
				$( fullscreenButton ).addClass( "ui-fullscreen-on" );
				control.append( fullscreenButton );
			}
			volumeControl.hide();

			return control;
		},

		_startTimer: function ( duration ) {
			this._endTimer();

			if ( !duration ) {
				duration = 3000;
			}

			var self = this,
				view = self.element,
				control = view.parent( ".ui-multimediaview-wrap" ).find( ".ui-multimediaview-control" ),
				volumeControl = control.find( ".ui-volumecontrol" );

			self.controlTimer = setTimeout( function () {
				self.isVolumeHide = true;
				self.controlTimer = null;
				volumeControl.hide();
				control.fadeOut( "fast" );
			}, duration );
		},

		_endTimer: function () {
			if ( this.controlTimer ) {
				clearTimeout( this.controlTimer );
				this.controlTimer = null;
			}
		},

		_convertTimeFormat: function ( systime ) {
			if ( !$.isNumeric( systime ) ) {
				return "Playback Error";
			}

			var ss = parseInt( systime % 60, 10 ).toString(),
				mm = parseInt( ( systime / 60 ) % 60, 10 ).toString(),
				hh = parseInt( systime / 3600, 10 ).toString(),
				time =	( ( hh.length < 2  ) ? "0" + hh : hh ) + ":" +
						( ( mm.length < 2  ) ? "0" + mm : mm ) + ":" +
						( ( ss.length < 2  ) ? "0" + ss : ss );

			return time;
		},

		_updateSeekBar: function ( currenttime ) {
			var view = this.element,
				viewElement = view[0],
				duration = viewElement.duration,
				control = view.parent( ".ui-multimediaview-wrap" ).find( ".ui-multimediaview-control" ),
				seekBar = control.find(  ".ui-seekbar"  ),
				durationBar = seekBar.find( ".ui-duration" ),
				currenttimeBar = seekBar.find( ".ui-currenttime" ),
				timestampLabel = control.find( ".ui-timestamplabel" ),
				durationOffset = durationBar.offset(),
				durationWidth = durationBar.width(),
				durationHeight = durationBar.height(),
				timebarWidth = 0;

			if ( typeof currenttime === "undefined" ) {
				currenttime = viewElement.currentTime;
			}
			timebarWidth = parseInt( currenttime / duration * durationWidth, 10 );
			durationBar.offset( durationOffset );
			currenttimeBar.offset( durationOffset ).width( timebarWidth );
			timestampLabel.find( "p" ).text( this._convertTimeFormat( currenttime ) );
		},

		_updateVolumeState: function () {
			var view = this.element,
				control = view.parent( ".ui-multimediaview-wrap" ).find( ".ui-multimediaview-control" ),
				volumeControl = control.find( ".ui-volumecontrol" ),
				volumeButton = control.find( ".ui-volumebutton" ),
				volumeBar = volumeControl.find( ".ui-volumebar" ),
				volumeGuide = volumeControl.find( ".ui-guide" ),
				volumeValue = volumeControl.find( ".ui-value" ),
				volumeHandle = volumeControl.find( ".ui-handle" ),
				handlerWidth = volumeHandle.width(),
				handlerHeight = volumeHandle.height(),
				volumeGuideHeight = volumeGuide.height(),
				volumeGuideWidth = volumeGuide.width(),
				volumeGuideTop = 0,
				volumeGuideLeft = 0,
				volumeBase = 0,
				handlerOffset = null,
				volume = view[0].volume;

			volumeGuideTop = parseInt( volumeGuide.offset().top, 10 );
			volumeGuideLeft = parseInt( volumeGuide.offset().left, 10 );
			volumeBase = volumeGuideLeft;
			handlerOffset = volumeHandle.offset();
			handlerOffset.top = volumeGuideTop - parseInt( ( handlerHeight - volumeGuideHeight ) / 2, 10 );
			handlerOffset.left = volumeBase + parseInt( volumeGuideWidth * volume, 10 ) - parseInt( handlerWidth / 2, 10 );
			volumeHandle.offset( handlerOffset );
			volumeValue.offset( volumeGuide.offset() ).width( parseInt( volumeGuideWidth * ( volume ), 10 ) );
		},

		_setVolume: function ( value ) {
			var viewElement = this.element[0];

			if ( value < 0.0 || value > 1.0 ) {
				return;
			}

			viewElement.volume = value;
		},

		width: function ( value ) {
			if ( this.options.fullScreen ) {
				return;
			}

			var view = this.element,
				wrap = view.parent( ".ui-multimediaview-wrap" );

			if ( arguments.length === 0 ) {
				return view.width();
			}

			if ( !this._isVideo ) {
				wrap.width( value );
			}

			view.width( value );
			this._resize();
		},

		height: function ( value ) {
			if ( !this._isVideo || this.options.fullScreen ) {
				return;
			}

			var view = this.element;

			if ( arguments.length === 0 ) {
				return view.height();
			}

			view.height( value );
			this._resize();
		},

		fullScreen: function ( value ) {
			if ( !this._isVideo ) {
				return;
			}

			var view = this.element,
				option = this.options;

			if ( arguments.length === 0 ) {
				return option.fullScreen;
			}

			view.parents( ".ui-scrollview-clip" ).scrollview( "scrollTo", 0, 0 );

			this.options.fullScreen = value;

			this._resize();
		},

		refresh: function () {
			this._resize();
		}
	});

	$( document ).bind( "pagecreate create", function ( e ) {
		$.tizen.multimediaview.prototype.enhanceWithin( e.target );
	}).bind( "pagechange", function ( e ) {
		$( e.target ).find( ".ui-multimediaview" ).each( function () {
			var view = $( this ),
				viewElement = view[0];

			if ( viewElement.autoplay ) {
				viewElement.play();
			}
			view.multimediaview( "refresh" );
		});
	}).bind( "pagebeforechange", function ( e ) {
		$( e.target ).find( ".ui-multimediaview" ).each( function () {
			var view = $( this ),
				viewElement = view[0],
				isFullscreen = view.multimediaview( "fullScreen" );

			if ( isFullscreen ) {
				view.multimediaview( "fullScreen", !isFullscreen );
			}

			if ( viewElement.played.length !== 0 ) {
				viewElement.pause();
			}
		});
	});

	$( window ).bind( "resize orientationchange", function ( e ) {
		$( ".ui-page-active" ).find( ".ui-multimediaview" ).multimediaview( "refresh" );
	});

} ( jQuery, document, window ) );



/* ***************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software" ),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 */

// most of following codes are derived from jquery.mobile.scrollview.js
(function ( $, window, document, undefined ) {

	function circularNum( num, total ) {
		var n = num % total;
		if ( n < 0 ) {
			n = total + n;
		}
		return n;
	}

	function setElementTransform( $ele, x, y ) {
		var v = "translate3d( " + x + "," + y + ", 0px)";
		$ele.css({
			"-ms-transform": v,
			"-o-transform": v,
			"-moz-transform": v,
			"-webkit-transform": v,
			"transform": v
		} );
	}

	function MomentumTracker( options ) {
		this.options = $.extend( {}, options );
		this.easing = "easeOutQuad";
		this.reset();
	}

	var tstates = {
		scrolling : 0,
		done : 1
	};

	function getCurrentTime() {
		return Date.now();
	}

	$.extend( MomentumTracker.prototype, {
		start: function ( pos, speed, duration ) {
			this.state = ( speed != 0 ) ? tstates.scrolling : tstates.done;
			this.pos = pos;
			this.speed = speed;
			this.duration = duration;

			this.fromPos = 0;
			this.toPos = 0;

			this.startTime = getCurrentTime();
		},

		reset: function () {
			this.state = tstates.done;
			this.pos = 0;
			this.speed = 0;
			this.duration = 0;
		},

		update: function () {
			var state = this.state,
				duration,
				elapsed,
				dx,
				x;

			if ( state == tstates.done ) {
				return this.pos;
			}

			duration = this.duration;
			elapsed = getCurrentTime() - this.startTime;
			elapsed = elapsed > duration ? duration : elapsed;

			dx = this.speed * ( 1 - $.easing[this.easing](elapsed / duration, elapsed, 0, 1, duration ) );

			x = this.pos + dx;
			this.pos = x;

			if ( elapsed >= duration ) {
				this.state = tstates.done;
			}

			return this.pos;
		},

		done: function () {
			return this.state == tstates.done;
		},

		getPosition: function () {
			return this.pos;
		}
	} );

	jQuery.widget( "mobile.circularview", jQuery.mobile.widget, {
		options: {
			fps:				60,

			scrollDuration:		2000,

			moveThreshold:		10,
			moveIntervalThreshold:	150,

			startEventName:		"scrollstart",
			updateEventName:	"scrollupdate",
			stopEventName:		"scrollstop",

			eventType:			$.support.touch	? "touch" : "mouse",

			delayedClickSelector: "a, .ui-btn",
			delayedClickEnabled: false
		},

		_makePositioned: function ( $ele ) {
			if ( $ele.css( 'position' ) == 'static' ) {
				$ele.css( 'position', 'relative' );
			}
		},

		_create: function () {
			var self = this;

			this._items = $( this.element ).jqmData('list');
			this._$clip = $( this.element ).addClass( "ui-scrollview-clip" );
			this._$clip.wrapInner( '<div class="ui-scrollview-view"></div>' );
			this._$view = $('.ui-scrollview-view', this._$clip );
			this._$list = $( 'ul', this._$clip );

			this._$clip.css( "overflow", "hidden" );
			this._makePositioned( this._$clip );

			this._$view.css( "overflow", "hidden" );
			this._tracker = new MomentumTracker( this.options );

			this._timerInterval = 1000 / this.options.fps;
			this._timerID = 0;

			this._timerCB = function () { self._handleMomentumScroll(); };

			this.refresh();

			this._addBehaviors();
		},

		reflow: function () {
			var xy = this.getScrollPosition();
			this.refresh();
			this.scrollTo( xy.x, xy.y );
		},

		refresh: function () {
			var itemsPerView;

			this._$clip.width( $(window).width() );
			this._clipWidth = this._$clip.width();
			this._$list.empty();
			this._$list.append(this._items[0]);
			this._itemWidth = $(this._items[0]).outerWidth();
			$(this._items[0]).detach();

			itemsPerView = this._clipWidth / this._itemWidth;
			itemsPerView = Math.ceil( itemsPerView * 10 ) / 10;
			this._itemsPerView = parseInt( itemsPerView, 10 );
			while ( this._itemsPerView + 1 > this._items.length ) {
				$.merge( this._items, $(this._items).clone() );
			}
			this._rx = -this._itemWidth;
			this._sx = -this._itemWidth;
			this._setItems();
		},

		_startMScroll: function ( speedX, speedY ) {
			this._stopMScroll();

			var keepGoing = false,
				duration = this.options.scrollDuration,
				t = this._tracker,
				c = this._clipWidth,
				v = this._viewWidth;

			this._$clip.trigger( this.options.startEventName);

			t.start( this._rx, speedX, duration, (v > c ) ? -(v - c) : 0, 0 );
			keepGoing = !t.done();

			if ( keepGoing ) {
				this._timerID = setTimeout( this._timerCB, this._timerInterval );
			} else {
				this._stopMScroll();
			}
			//console.log( "startmscroll" + this._rx + "," + this._sx );
		},

		_stopMScroll: function () {
			if ( this._timerID ) {
				this._$clip.trigger( this.options.stopEventName );
				clearTimeout( this._timerID );
			}

			this._timerID = 0;

			if ( this._tracker ) {
				this._tracker.reset();
			}
			//console.log( "stopmscroll" + this._rx + "," + this._sx );
		},

		_handleMomentumScroll: function () {
			var keepGoing = false,
				v = this._$view,
				x = 0,
				y = 0,
				t = this._tracker;

			if ( t ) {
				t.update();
				x = t.getPosition();

				keepGoing = !t.done();

			}

			this._setScrollPosition( x, y );
			this._rx = x;

			this._$clip.trigger( this.options.updateEventName, [ { x: x, y: y } ] );

			if ( keepGoing ) {
				this._timerID = setTimeout( this._timerCB, this._timerInterval );
			} else {
				this._stopMScroll();
			}
		},

		_setItems: function () {
			var i,
				$item;

			for ( i = -1; i < this._itemsPerView + 1; i++ ) {
				$item = this._items[ circularNum( i, this._items.length ) ];
				this._$list.append( $item );
			}
			setElementTransform( this._$view, this._sx + "px", 0 );
			this._$view.width( this._itemWidth * ( this._itemsPerView + 2 ) );
			this._viewWidth = this._$view.width();
		},

		_setScrollPosition: function ( x, y ) {
			var sx = this._sx,
				dx = x - sx,
				di = parseInt( dx / this._itemWidth, 10 ),
				i,
				idx,
				$item;

			if ( di > 0 ) {
				for ( i = 0; i < di; i++ ) {
					this._$list.children().last().detach();
					idx = -parseInt( ( sx / this._itemWidth ) + i + 3, 10 );
					$item = this._items[ circularNum( idx, this._items.length ) ];
					this._$list.prepend( $item );
					//console.log( "di > 0 : " + idx );
				}
			} else if ( di < 0 ) {
				for ( i = 0; i > di; i-- ) {
					this._$list.children().first().detach();
					idx = this._itemsPerView - parseInt( ( sx / this._itemWidth ) + i, 10 );
					$item = this._items[ circularNum( idx, this._items.length ) ];
					this._$list.append( $item );
					//console.log( "di < 0 : " + idx );
				}
			}

			this._sx += di * this._itemWidth;

			setElementTransform( this._$view, ( x - this._sx - this._itemWidth ) + "px", 0 );

			//console.log( "rx " + this._rx + "sx " + this._sx );
		},

		_enableTracking: function () {
			$(document).bind( this._dragMoveEvt, this._dragMoveCB );
			$(document).bind( this._dragStopEvt, this._dragStopCB );
		},

		_disableTracking: function () {
			$(document).unbind( this._dragMoveEvt, this._dragMoveCB );
			$(document).unbind( this._dragStopEvt, this._dragStopCB );
		},

		_getScrollHierarchy: function () {
			var svh = [],
				d;
			this._$clip.parents( '.ui-scrollview-clip' ).each( function () {
				d = $( this ).jqmData( 'circulaview' );
				if ( d ) {
					svh.unshift( d );
				}
			} );
			return svh;
		},

		centerTo: function ( selector, duration ) {
			var i,
				newX;

			for ( i = 0; i < this._items.length; i++ ) {
				if ( $( this._items[i]).is( selector ) ) {
					newX = -( i * this._itemWidth - this._clipWidth / 2 + this._itemWidth * 1.5 );
					this.scrollTo( newX + this._itemWidth, 0 );
					this.scrollTo( newX, 0, duration );
					return;
				}
			}
		},

		scrollTo: function ( x, y, duration ) {
			this._stopMScroll();
			if ( !duration ) {
				this._setScrollPosition( x, y );
				this._rx = x;
				return;
			}

			var self = this,
				start = getCurrentTime(),
				efunc = $.easing.easeOutQuad,
				sx = this._rx,
				sy = 0,
				dx = x - sx,
				dy = 0,
				tfunc,
				elapsed,
				ec;

			this._rx = x;

			tfunc = function () {
				elapsed = getCurrentTime() - start;
				if ( elapsed >= duration ) {
					self._timerID = 0;
					self._setScrollPosition( x, y );
					self._$clip.trigger("scrollend");
				} else {
					ec = efunc( elapsed / duration, elapsed, 0, 1, duration );
					self._setScrollPosition( sx + ( dx * ec ), sy + ( dy * ec ) );
					self._timerID = setTimeout( tfunc, self._timerInterval );
				}
			};

			this._timerID = setTimeout( tfunc, this._timerInterval );
		},

		getScrollPosition: function () {
			return { x: -this._rx, y: 0 };
		},

		_handleDragStart: function ( e, ex, ey ) {
			$.each( this._getScrollHierarchy(), function ( i, sv ) {
				sv._stopMScroll();
			} );

			this._stopMScroll();

			if ( this.options.delayedClickEnabled ) {
				this._$clickEle = $( e.target ).closest( this.options.delayedClickSelector );
			}
			this._lastX = ex;
			this._lastY = ey;
			this._speedX = 0;
			this._speedY = 0;
			this._didDrag = false;

			this._lastMove = 0;
			this._enableTracking();

			this._ox = ex;
			this._nx = this._rx;

			if ( this.options.eventType == "mouse" || this.options.delayedClickEnabled ) {
				e.preventDefault();
			}
			//console.log( "scrollstart" + this._rx + "," + this._sx );
			e.stopPropagation();
		},

		_handleDragMove: function ( e, ex, ey ) {
			this._lastMove = getCurrentTime();

			var dx = ex - this._lastX,
				dy = ey - this._lastY;

			this._speedX = dx;
			this._speedY = 0;

			this._didDrag = true;

			this._lastX = ex;
			this._lastY = ey;

			this._mx = ex - this._ox;

			this._setScrollPosition( this._nx + this._mx, 0 );

			//console.log( "scrollmove" + this._rx + "," + this._sx );
			return false;
		},

		_handleDragStop: function ( e ) {
			var l = this._lastMove,
				t = getCurrentTime(),
				doScroll = l && ( t - l ) <= this.options.moveIntervalThreshold,
				sx = ( this._tracker && this._speedX && doScroll ) ? this._speedX : 0,
				sy = 0;

			this._rx = this._mx ? this._nx + this._mx : this._rx;

			if ( sx ) {
				this._startMScroll( sx, sy );
			}

			//console.log( "scrollstop" + this._rx + "," + this._sx );

			this._disableTracking();

			if ( !this._didDrag && this.options.delayedClickEnabled && this._$clickEle.length ) {
				this._$clickEle
					.trigger( "mousedown" )
					.trigger( "mouseup" )
					.trigger( "click" );
			}

			if ( this._didDrag ) {
				e.preventDefault();
				e.stopPropagation();
			}

			return this._didDrag ? false : undefined;
		},

		_addBehaviors: function () {
			var self = this;

			if ( this.options.eventType === "mouse" ) {
				this._dragStartEvt = "mousedown";
				this._dragStartCB = function ( e ) {
					return self._handleDragStart( e, e.clientX, e.clientY );
				};

				this._dragMoveEvt = "mousemove";
				this._dragMoveCB = function ( e ) {
					return self._handleDragMove( e, e.clientX, e.clientY );
				};

				this._dragStopEvt = "mouseup";
				this._dragStopCB = function ( e ) {
					return self._handleDragStop( e );
				};

				this._$view.bind( "vclick", function (e) {
					return !self._didDrag;
				} );

			} else { //touch
				this._dragStartEvt = "touchstart";
				this._dragStartCB = function ( e ) {
					var t = e.originalEvent.targetTouches[0];
					return self._handleDragStart(e, t.pageX, t.pageY );
				};

				this._dragMoveEvt = "touchmove";
				this._dragMoveCB = function ( e ) {
					var t = e.originalEvent.targetTouches[0];
					return self._handleDragMove(e, t.pageX, t.pageY );
				};

				this._dragStopEvt = "touchend";
				this._dragStopCB = function ( e ) {
					return self._handleDragStop( e );
				};
			}
			this._$view.bind( this._dragStartEvt, this._dragStartCB );
		}
	} );

	$( document ).bind( "pagecreate create", function ( e ) {
		$( $.mobile.circularview.prototype.options.initSelector, e.target ).circularview();
	} );

}( jQuery, window, document ) ); // End Component



/*
 * jQuery Mobile Widget @VERSION
 *
 * This software is licensed under the MIT licence (as defined by the OSI at
 * http://www.opensource.org/licenses/mit-license.php)
 *
 * ***************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 * Copyright (c) 2011 by Intel Corporation Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 *
 * Authors: Elliot Smith <elliot.smith@intel.com>
 *		 Yonghwi Park <yonghwi0324.park@samsung.com>
 */

// fastscroll is a scrollview controller, which binds
// a scrollview to a a list of short cuts; the shortcuts are built
// from the text on dividers in the list. Clicking on a shortcut
// instantaneously jumps the scrollview to the selected list divider;
// mouse movements on the shortcut column move the scrollview to the
// list divider matching the text currently under the touch; a popup
// with the text currently under the touch is also displayed.
//
// To apply, add the attribute data-fastscroll="true" to a listview
// (a <ul> or <ol> element inside a page). Alternatively, call
// fastscroll() on an element.
//
// The closest element with class ui-scrollview-clip is used as the
// scrollview to be controlled.
//
// If a listview has no dividers or a single divider, the widget won't
// display.

/**
	@class fastscroll
	The shortcut scroll widget shows a shortcut list that is bound to its parent scroll bar and respective list view. This widget is displayed as a text pop-up representing shortcuts to different list dividers in the list view. If you select a shortcut text from the shortcut scroll, the parent list view is moved to the location representing the selected shortcut.

	To add a shortcut scroll widget to the application, use the following code:

		<div class="content" data-role="content" data-scroll="y">
			<ul id="contacts" data-role="listview" data-fastscroll="true">
				<li>Anton</li>
			</ul>
		</div>

	For the shortcut scroll widget to be visible, the parent list view must have multiple list dividers.
*/

/**
	@property {Boolean}  data-fastscroll
	When set to true, creates a shortcut scroll using the HTML unordered list (&lt;ul&gt;) element.
*/
/**
	@method fastscroll
	The shortcut scroll is created for the closest list view with the ui-scrollview-clip class.
*/
/**
	@method indexString
	The indexString method is used to get (if no value is defined) or set the string to present the index.

		<div class="content" data-role="content" data-scroll="y">
			ul id="contacts" data-role="listview" data-fastscroll="true">
				<li data-role="list-divider">A</li>
				<li>Anton</li>
			</ul>
		</div>

		$(".selector").fastscroll( "indexString" [, indexAlphabet] );
*/
(function ( $, undefined ) {

	$.widget( "tizen.fastscroll", $.mobile.widget, {
		options: {
			initSelector: ":jqmData(fastscroll)"
		},

		_primaryLanguage: null,
		_secondLanguage: null,
		_dividerMap: {},
		_charSet: null,

		_create: function () {
			var $el = this.element,
				self = this,
				$popup,
				page = $el.closest( ':jqmData(role="page")' ),
				jumpToDivider;

			this.scrollview = $el.addClass( 'ui-fastscroll-target' ).closest( '.ui-scrollview-clip' );
			this.shortcutsContainer = $( '<div class="ui-fastscroll" aria-label="Fast scroll bar, double tap to fast scroll mode" tabindex="0"/>' );
			this.shortcutsList = $( '<ul aria-hidden="true"></ul>' );

			// popup for the hovering character
			this.scrollview.append($( '<div class="ui-fastscroll-popup"></div>' ) );
			$popup = this.scrollview.find( '.ui-fastscroll-popup' );

			this.shortcutsContainer.append( this.shortcutsList );
			this.scrollview.append( this.shortcutsContainer );

			// find the bottom of the last item in the listview
			this.lastListItem = $el.children().last();

			// remove scrollbars from scrollview
			this.scrollview.find( '.ui-scrollbar' ).hide();

			this.jumpToDivider = function ( divider ) {
				// get the vertical position of the divider (so we can scroll to it)
				var dividerY = $( divider ).position().top,
					// find the bottom of the last list item
					bottomOffset = self.lastListItem.outerHeight( true ) + self.lastListItem.position().top,
					scrollviewHeight = self.scrollview.height(),

				// check that after the candidate scroll, the bottom of the
				// last item will still be at the bottom of the scroll view
				// and not some way up the page
					maxScroll = bottomOffset - scrollviewHeight,
					dstOffset;

				dividerY = ( dividerY > maxScroll ? maxScroll : dividerY );

				// don't apply a negative scroll, as this means the
				// divider should already be visible
				dividerY = Math.max( dividerY, 0 );

				// apply the scroll
				self.scrollview.scrollview( 'scrollTo', 0, -dividerY );

				dstOffset = self.scrollview.offset();
			};

			this.shortcutsList
			// bind mouse over so it moves the scroller to the divider
				.bind( 'touchstart mousedown vmousedown touchmove vmousemove vmouseover', function ( e ) {
					// Get coords relative to the element
					var coords = $.mobile.tizen.targetRelativeCoordsFromEvent( e ),
						shortcutsListOffset = self.shortcutsList.offset();

					self.shortcutsContainer.addClass( "ui-fastscroll-hover" );

					// If the element is a list item, get coordinates relative to the shortcuts list
					if ( e.target.tagName.toLowerCase() === "li" ) {
						coords.x += $( e.target ).offset().left - shortcutsListOffset.left;
						coords.y += $( e.target ).offset().top  - shortcutsListOffset.top;
					}

					if ( e.target.tagName.toLowerCase() === "span" ) {
						coords.x += $( e.target ).parent().offset().left - shortcutsListOffset.left;
						coords.y += $( e.target ).parent().offset().top  - shortcutsListOffset.top;
					}

					self.shortcutsList.find( 'li' ).each( function () {
						var listItem = $( this );
						$( listItem )
							.removeClass( "ui-fastscroll-hover" )
							.removeClass( "ui-fastscroll-hover-down" );
					});
					// Hit test each list item
					self.shortcutsList.find( 'li' ).each( function () {
						var listItem = $( this ),
							l = listItem.offset().left - shortcutsListOffset.left,
							t = listItem.offset().top  - shortcutsListOffset.top,
							r = l + Math.abs(listItem.outerWidth( true ) ),
							b = t + Math.abs(listItem.outerHeight( true ) ),
							unit,
							baseTop,
							baseBottom,
							omitSet,
							i;

						if ( coords.x >= l && coords.x <= r && coords.y >= t && coords.y <= b ) {
							if ( listItem.text() !== "." ) {
								self._hitItem( listItem );
							} else {
								omitSet = listItem.data( "omitSet" );
								unit = ( b - t ) / omitSet.length;
								for ( i = 0; i < omitSet.length; i++ ) {
									baseTop = t + ( i * unit );
									baseBottom = baseTop + unit;
									if ( coords.y >= baseTop && coords.y <= baseBottom ) {
										self._hitOmitItem( listItem, omitSet.charAt( i ) );
									}
								}
							}
							return false;
						}
						return true;
					} );

					e.preventDefault();
					e.stopPropagation();
				} )
				// bind mouseout of the fastscroll container to remove popup
				.bind( 'touchend mouseup vmouseup vmouseout', function () {
					$popup.hide();
					$( ".ui-fastscroll-hover" ).removeClass( "ui-fastscroll-hover" );
					$( ".ui-fastscroll-hover-first-item" ).removeClass( "ui-fastscroll-hover-first-item" );
					$( ".ui-fastscroll-hover-down" ).removeClass( "ui-fastscroll-hover-down" );
					self.shortcutsContainer.removeClass( "ui-fastscroll-hover" );
				} );

			if ( page && !( page.is( ':visible' ) ) ) {
				page.bind( 'pageshow', function () { self.refresh(); } );
			} else {
				self.refresh();
			}

			// refresh the list when dividers are filtered out
			$el.bind( 'updatelayout', function () {
				self.refresh();
			} );
		},

		_findClosestDivider: function ( targetChar ) {
			var i,
				dividerMap = this._dividerMap,
				charSet = this._charSet,
				charSetLen = charSet.length,
				targetIdx = charSet.indexOf( targetChar ),
				lastDivider,
				subDivider = null;

			for ( i = 0; i < targetIdx; ++i ) {
				lastDivider = dividerMap[ charSet.charAt( i ) ];
				if ( lastDivider !== undefined ) {
					subDivider = lastDivider;
				}
			}
			if ( !subDivider ) {
				for ( ++i; i < charSetLen; ++i ) {
					lastDivider = dividerMap[ charSet.charAt( i ) ];
					if ( lastDivider !== undefined ) {
						subDivider = lastDivider;
						break;
					}
				}
			}
			return subDivider;
		},

		_hitOmitItem: function ( listItem, text ) {
			var $popup = this.scrollview.find( '.ui-fastscroll-popup' ),
				divider;

			divider = this._dividerMap[ text ] || this._findClosestDivider( text );
			if ( typeof divider !== "undefined" ) {
				this.jumpToDivider( $( divider ) );
			}

			$popup.text( text ).show();

			$( listItem ).addClass( "ui-fastscroll-hover" );
			if ( listItem.index() === 0 ) {
				$( listItem ).addClass( "ui-fastscroll-hover-first-item" );
			}
			$( listItem ).siblings().eq( listItem.index() ).addClass( "ui-fastscroll-hover-down" );
		},

		_hitItem: function ( listItem  ) {
			var $popup = this.scrollview.find( '.ui-fastscroll-popup' ),
				text = listItem.text(),
				divider;

			if ( text === "#" ) {
				divider = this._dividerMap.number;
			} else {
				divider = this._dividerMap[ text ] || this._findClosestDivider( text );
			}

			if ( typeof divider !== "undefined" ) {
				this.jumpToDivider( $( divider ) );
			}

			$popup.text( text ).show();

			$( listItem ).addClass( "ui-fastscroll-hover" );
			if ( listItem.index() === 0 ) {
				$( listItem ).addClass( "ui-fastscroll-hover-first-item" );
			}
			$( listItem ).siblings().eq( listItem.index() ).addClass( "ui-fastscroll-hover-down" );
		},

		_focusItem: function ( listItem ) {
			var self = this,
				$popup = self.scrollview.find( '.ui-fastscroll-popup' );

			listItem.focusin( function ( e ) {
				self.shortcutsList.attr( "aria-hidden", false );
				self._hitItem( listItem );
			}).focusout( function ( e ) {
				self.shortcutsList.attr( "aria-hidden", true );
				$popup.hide();
				$( ".ui-fastscroll-hover" ).removeClass( "ui-fastscroll-hover" );
				$( ".ui-fastscroll-hover-first-item" ).removeClass( "ui-fastscroll-hover-first-item" );
				$( ".ui-fastscroll-hover-down" ).removeClass( "ui-fastscroll-hover-down" );
			});
		},

		_contentHeight: function () {
			var self = this,
				$content = $( '.ui-scrollview-clip' ),
				header = null,
				footer = null,
				paddingValue = 0,
				clipSize = $( window ).height();

			if ( $content.hasClass( "ui-content" ) ) {
				paddingValue = parseInt( $content.css( "padding-top" ), 10 );
				clipSize = clipSize - ( paddingValue || 0 );
				paddingValue = parseInt( $content.css( "padding-bottom" ), 10 );
				clipSize = clipSize - ( paddingValue || 0 );
				header = $content.siblings( ".ui-header:visible" );
				footer = $content.siblings( ".ui-footer:visible" );

				if ( header ) {
					if ( header.outerHeight( true ) === null ) {
						clipSize = clipSize - ( $( ".ui-header" ).outerHeight() || 0 );
					} else {
						clipSize = clipSize - header.outerHeight( true );
					}
				}
				if ( footer ) {
					clipSize = clipSize - footer.outerHeight( true );
				}
			} else {
				clipSize = $content.height();
			}
			return clipSize;
		},

		_omit: function ( numOfItems, maxNumOfItems ) {
			var maxGroupNum = parseInt( ( maxNumOfItems - 1 ) / 2, 10 ),
				numOfExtraItems = numOfItems - maxNumOfItems,
				groupPos = [],
				omitInfo = [],
				groupPosLength,
				group,
				size,
				i;

			if ( ( maxNumOfItems < 3 ) || ( numOfItems <= maxNumOfItems ) ) {
				return;
			}

			if ( numOfExtraItems >= maxGroupNum ) {
				size = 2;
				group = 1;
				groupPosLength = maxGroupNum;
			} else {
				size = maxNumOfItems / ( numOfExtraItems + 1 );
				group = size;
				groupPosLength = numOfExtraItems;
			}

			for ( i = 0; i < groupPosLength; i++ ) {
				groupPos.push( parseInt( group, 10 ) );
				group += size;
			}

			for ( i = 0; i < maxNumOfItems; i++ ) {
				omitInfo.push( 1 );
			}

			for ( i = 0; i < numOfExtraItems; i++ ) {
				omitInfo[ groupPos[ i % maxGroupNum ] ]++;
			}

			return omitInfo;
		},

		_createDividerMap: function () {
			var primaryCharacterSet = this._primaryLanguage ? this._primaryLanguage.replace( /,/g, "" ) : null,
				secondCharacterSet = this._secondLanguage ? this._secondLanguage.replace( /,/g, "" ) : null,
				numberSet = "0123456789",
				dividers = this.element.find( '.ui-li-divider' ),
				map = {},
				matchToDivider,
				makeCharacterSet,
				indexChar,
				i;

			matchToDivider = function ( index, divider ) {
				if ( $( divider ).text() === indexChar ) {
					map[ indexChar ] = divider;
				}
			};

			makeCharacterSet = function ( index, divider ) {
				primaryCharacterSet += $( divider ).text();
			};

			if ( primaryCharacterSet === null ) {
				primaryCharacterSet = "";
				dividers.each( makeCharacterSet );
			}

			for ( i = 0; i < primaryCharacterSet.length; i++ ) {
				indexChar = primaryCharacterSet.charAt( i );
				dividers.each( matchToDivider );
			}

			if ( secondCharacterSet !== null ) {
				for ( i = 0; i < secondCharacterSet.length; i++ ) {
					indexChar = secondCharacterSet.charAt( i );
					dividers.each( matchToDivider );
				}
			}

			dividers.each( function ( index, divider ) {
				if ( numberSet.search( $( divider ).text() ) !== -1  ) {
					map.number = divider;
					return false;
				}
			});

			this._dividerMap = map;
			this._charSet = primaryCharacterSet + secondCharacterSet;
		},

		indexString: function ( indexAlphabet ) {
			var self = this,
				characterSet = [];

			if ( typeof indexAlphabet === "undefined" ) {
				return self._primaryLanguage + ":" + self._secondLanguage;
			}

			characterSet = indexAlphabet.split( ":" );
			self._primaryLanguage = characterSet[ 0 ];
			if ( characterSet.length === 2 ) {
				self._secondLanguage = characterSet[ 1 ];
			}
		},

		refresh: function () {
			var self = this,
				primaryCharacterSet = self._primaryLanguage ? self._primaryLanguage.replace( /,/g, "" ) : null,
				secondCharacterSet = self._secondLanguage ? self._secondLanguage.replace( /,/g, "" ) : null,
				contentHeight = self._contentHeight(),
				shapItem = $( '<li tabindex="0" aria-label="double to move Number list"><span aria-hidden="true">#</span><span aria-label="Number"/></li>' ),
				$popup = this.scrollview.find( '.ui-fastscroll-popup' ),
				omitIndex = 0,
				makeCharacterSet,
				makeOmitSet,
				itemHandler,
				containerHeight,
				shortcutsItems,
				shortcutItem,
				shortcutsTop,
				minClipHeight,
				maxNumOfItems,
				numOfItems,
				minHeight,
				omitInfo,
				dividers,
				listItems,
				emptySize,
				correction,
				indexChar,
				lastIndex,
				seconds,
				height,
				size,
				i;

			makeCharacterSet = function ( index, divider ) {
				primaryCharacterSet += $( divider ).text();
			};

			makeOmitSet = function ( index, length ) {
				var count,
					omitSet = "";

				for ( count = 0; count < length; count++ ) {
					omitSet += primaryCharacterSet[ index + count ];
				}

				return omitSet;
			};

			self._createDividerMap();

			self.shortcutsList.find( 'li' ).remove();

			// get all the dividers from the list and turn them into shortcuts
			dividers = self.element.find( '.ui-li-divider' );

			// get all the list items
			listItems = self.element.find('li').not('.ui-li-divider');

			// only use visible dividers
			dividers = dividers.filter( ':visible' );
			listItems = listItems.filter( ':visible' );

			if ( dividers.length < 2 ) {
				self.shortcutsList.hide();
				return;
			}

			self.shortcutsList.show();
			self.lastListItem = listItems.last();
			self.shortcutsList.append( shapItem );
			self._focusItem( shapItem );

			if ( primaryCharacterSet === null ) {
				primaryCharacterSet = "";
				dividers.each( makeCharacterSet );
			}

			minHeight = shapItem.outerHeight( true );
			maxNumOfItems = parseInt( contentHeight / minHeight - 1, 10 );
			numOfItems = primaryCharacterSet.length;

			maxNumOfItems = secondCharacterSet ? maxNumOfItems - 2 : maxNumOfItems;

			if ( maxNumOfItems < 3 ) {
				shapItem.remove();
				return;
			}

			omitInfo = self._omit( numOfItems, maxNumOfItems );

			for ( i = 0; i < primaryCharacterSet.length; i++ ) {
				indexChar = primaryCharacterSet.charAt( i );
				shortcutItem = $( '<li tabindex="0" aria-label="double to move ' + indexChar + ' list">' + indexChar + '</li>' );

				self._focusItem( shortcutItem );

				if ( typeof omitInfo !== "undefined" && omitInfo[ omitIndex ] > 1 ) {
					shortcutItem = $( '<li>.</li>' );
					shortcutItem.data( "omitSet",  makeOmitSet( i, omitInfo[ omitIndex ] ) );
					i += omitInfo[ omitIndex ] - 1;
				}

				self.shortcutsList.append( shortcutItem );
				omitIndex++;
			}

			if ( secondCharacterSet !== null ) {
				lastIndex = secondCharacterSet.length - 1;
				seconds = [];

				seconds.push( secondCharacterSet.charAt( 0 ) );
				seconds.push( secondCharacterSet.charAt( lastIndex ) );

				for ( i = 0; i < seconds.length; i++ ) {
					indexChar = seconds[ i ];
					shortcutItem = $( '<li tabindex="0" aria-label="double to move ' + indexChar + ' list">' + indexChar + '</li>' );

					self._focusItem( shortcutItem );
					shortcutItem.bind( 'vclick', itemHandler );
					self.shortcutsList.append( shortcutItem );
				}
			}

			containerHeight = self.shortcutsContainer.outerHeight( true );
			emptySize = contentHeight - containerHeight;
			shortcutsItems = self.shortcutsList.children();
			size = parseInt( emptySize / shortcutsItems.length, 10 );
			correction = emptySize - ( shortcutsItems.length * size );

			if ( emptySize > 0 ) {
				shortcutsItems.each( function ( index, item ) {
					height = $( item ).height() + size;
					if ( correction !== 0 ) {
						height += 1;
						correction -= 1;
					}
					$( item ).css( {
						height: height,
						lineHeight: height + "px"
					} );
				} );
			}

			// position the shortcut flush with the top of the first list divider
			shortcutsTop = dividers.first().position().top;
			self.shortcutsContainer.css( 'top', shortcutsTop );

			// make the scrollview clip tall enough to show the whole of the shortcutslist
			minClipHeight = shortcutsTop + self.shortcutsContainer.outerHeight() + 'px';
			self.scrollview.css( 'min-height', minClipHeight );

			$popup.text( "M" ) // Popup size is determined based on "M".
				.width( $popup.height() )
				.css( { marginLeft: -( $popup.outerWidth() / 2 ),
					marginTop: -( $popup.outerHeight() / 2 ) } );
		}
	} );

	$( document ).bind( "pagecreate create", function ( e ) {
		$( $.tizen.fastscroll.prototype.options.initSelector, e.target )
			.not( ":jqmData(role='none'), :jqmData(role='nojs')" )
			.fastscroll();
	} );

	$( window ).bind( "resize orientationchange", function ( e ) {
		$( ".ui-page-active .ui-fastscroll-target" ).fastscroll( "refresh" );
	} );
} ( jQuery ) );



/*
 *
 * This software is licensed under the MIT licence (as defined by the OSI at
 * http://www.opensource.org/licenses/mit-license.php)
 * 
 * ***************************************************************************
 * Copyright (C) 2011 by Intel Corporation Ltd.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 */

// Ensure that the given namespace is defined. If not, define it to be an empty object.
// This is kinda like the mkdir -p command.
(function (window) {
		window.ensureNS = (function () {
		var internalCache = {};
		return function ensureNS (ns) { // name just for debugging purposes
			var nsArr = ns.split(".").reverse(),
				nsSoFar = "",
				buffer = "",
				leaf = "",
				l = nsArr.length;
			while(--l >= 0) {
				leaf = nsArr[l];
				nsSoFar = nsSoFar + (nsSoFar.length > 0 ? "." : "") + leaf;
				if (!internalCache[nsSoFar]) {
					internalCache[nsSoFar] = true;
					buffer += "!window." + nsSoFar + ' && (window.' + nsSoFar + " = {});\n";
				}
			}
			buffer.length && (new Function(buffer))();
		};
	})();
})(this);



/*
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL licenses
 * http://phpjs.org/functions/range
 * original by: Waldo Malqui Silva
 * version: 1107.2516
 */
function range( low, high, step ) {
    // Create an array containing the range of integers or characters
    // from low to high (inclusive)  
    // 
    // version: 1107.2516
    // discuss at: http://phpjs.org/functions/range
    // +   original by: Waldo Malqui Silva
    // *     example 1: range ( 0, 12 );
    // *     returns 1: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
    // *     example 2: range( 0, 100, 10 );
    // *     returns 2: [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
    // *     example 3: range( 'a', 'i' );
    // *     returns 3: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']
    // *     example 4: range( 'c', 'a' );
    // *     returns 4: ['c', 'b', 'a']
	var matrix = [],
		inival,
		endval,
		plus,
		walker = step || 1,
		chars = false;

    if (!isNaN(low) && !isNaN(high)) {
        inival = low;
        endval = high;
    } else if (isNaN(low) && isNaN(high)) {
        chars = true;
        inival = low.charCodeAt(0);
        endval = high.charCodeAt(0);
    } else {
        inival = (isNaN(low) ? 0 : low);
        endval = (isNaN(high) ? 0 : high);
    }

    plus = ((inival > endval) ? false : true);
    if (plus) {
        while (inival <= endval) {
            matrix.push(((chars) ? String.fromCharCode(inival) : inival));
            inival += walker;
        }
    } else {
        while (inival >= endval) {
            matrix.push(((chars) ? String.fromCharCode(inival) : inival));
            inival -= walker;
        }
    }

    return matrix;
}



/* ***************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 *
 * Authors: Hyunsook Park <hyunsook.park@samsung.com>
 *			Wonseop Kim <wonseop.kim@samsung.com>
*/

( function ( $, undefined ) {
	$.webgl = {};

	$.webgl.shader = {
		_vertexShader: null,
		_fragmentShader: null,

		deleteShaders: function ( gl ) {
			gl.deleteShader( this._vertexShader );
			gl.deleteShader( this._fragmentShader );
		},

		addShaderProgram : function ( gl, vs, fs, isFile ) {
			var shaderProgram,
				vertexShaderSource = {},
				fragmentShaderSource = {};

			if ( isFile ) {
				vertexShaderSource = this.loadShaderFile( vs );
				fragmentShaderSource = this.loadShaderFile( fs );
			} else {
				vertexShaderSource.source = vs;
				fragmentShaderSource.source = fs;
			}

			this._vertexShader = this.getShader( gl, gl.VERTEX_SHADER, vertexShaderSource );
			this._fragmentShader = this.getShader( gl, gl.FRAGMENT_SHADER, fragmentShaderSource );

			shaderProgram = gl.createProgram();
			gl.attachShader( shaderProgram, this._vertexShader);
			gl.attachShader( shaderProgram, this._fragmentShader);
			gl.linkProgram( shaderProgram );

			if ( !gl.getProgramParameter( shaderProgram, gl.LINK_STATUS ) ) {
				window.alert( "Could not initialize Shaders!" );
			}
			return shaderProgram;
		},

		loadShaderFile : function ( path ) {
			var cache = null;
			$.ajax({
				async : false,
				url : path,
				success : function ( result ) {
					cache = {
						source: result
					};
				}
			});
			return cache;
		},

		getShader: function ( gl, type, script ) {
			var shader;

			if ( !gl || !type || !script ) {
				return null;
			}

			shader = gl.createShader( type );

			gl.shaderSource( shader, script.source );
			gl.compileShader( shader );

			if ( !gl.getShaderParameter( shader, gl.COMPILE_STATUS ) ) {
				window.alert( gl.getShaderInfoLog( shader ) );
				gl.deleteShader( shader );
				return null;
			}
			return shader;
		}
	};

	$.webgl.buffer = {
		attribBufferData: function ( gl, attribArray ) {
			var attribBuffer = gl.createBuffer();

			gl.bindBuffer( gl.ARRAY_BUFFER, attribBuffer );
			gl.bufferData( gl.ARRAY_BUFFER, attribArray, gl.STATIC_DRAW );
			gl.bindBuffer( gl.ARRAY_BUFFER, null );

			return attribBuffer;
		}
	};

} ( jQuery ) );


/* ***************************************************************************
	Flora License

	Version 1.1, April, 2013

	http://floralicense.org/license/

	TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

	1. Definitions.

	"License" shall mean the terms and conditions for use, reproduction,
	and distribution as defined by Sections 1 through 9 of this document.

	"Licensor" shall mean the copyright owner or entity authorized by
	the copyright owner that is granting the License.

	"Legal Entity" shall mean the union of the acting entity and
	all other entities that control, are controlled by, or are
	under common control with that entity. For the purposes of
	this definition, "control" means (i) the power, direct or indirect,
	to cause the direction or management of such entity,
	whether by contract or otherwise, or (ii) ownership of fifty percent (50%)
	or more of the outstanding shares, or (iii) beneficial ownership of
	such entity.

	"You" (or "Your") shall mean an individual or Legal Entity
	exercising permissions granted by this License.

	"Source" form shall mean the preferred form for making modifications,
	including but not limited to software source code, documentation source,
	and configuration files.

	"Object" form shall mean any form resulting from mechanical
	transformation or translation of a Source form, including but
	not limited to compiled object code, generated documentation,
	and conversions to other media types.

	"Work" shall mean the work of authorship, whether in Source or Object form,
	made available under the License, as indicated by a copyright notice
	that is included in or attached to the work (an example is provided
	in the Appendix below).

	"Derivative Works" shall mean any work, whether in Source or Object form,
	that is based on (or derived from) the Work and for which the editorial
	revisions, annotations, elaborations, or other modifications represent,
	as a whole, an original work of authorship. For the purposes of this License,
	Derivative Works shall not include works that remain separable from,
	or merely link (or bind by name) to the interfaces of, the Work and
	Derivative Works thereof.

	"Contribution" shall mean any work of authorship, including the original
	version of the Work and any modifications or additions to that Work or
	Derivative Works thereof, that is intentionally submitted to Licensor
	for inclusion in the Work by the copyright owner or by an individual or
	Legal Entity authorized to submit on behalf of the copyright owner.
	For the purposes of this definition, "submitted" means any form of
	electronic, verbal, or written communication sent to the Licensor or
	its representatives, including but not limited to communication on
	electronic mailing lists, source code control systems, and issue
	tracking systems that are managed by, or on behalf of, the Licensor
	for the purpose of discussing and improving the Work, but excluding
	communication that is conspicuously marked or otherwise designated
	in writing by the copyright owner as "Not a Contribution."

	"Contributor" shall mean Licensor and any individual or Legal Entity
	on behalf of whom a Contribution has been received by Licensor and
	subsequently incorporated within the Work.

	"Tizen Certified Platform" shall mean a software platform that complies
	with the standards set forth in the Tizen Compliance Specification
	and passes the Tizen Compliance Tests as defined from time to time
	by the Tizen Technical Steering Group and certified by the Tizen
	Association or its designated agent.

	2. Grant of Copyright License.  Subject to the terms and conditions of
	this License, each Contributor hereby grants to You a perpetual,
	worldwide, non-exclusive, no-charge, royalty-free, irrevocable
	copyright license to reproduce, prepare Derivative Works of,
	publicly display, publicly perform, sublicense, and distribute the
	Work and such Derivative Works in Source or Object form.

	3. Grant of Patent License.  Subject to the terms and conditions of
	this License, each Contributor hereby grants to You a perpetual,
	worldwide, non-exclusive, no-charge, royalty-free, irrevocable
	(except as stated in this section) patent license to make, have made,
	use, offer to sell, sell, import, and otherwise transfer the Work
	solely as incorporated into a Tizen Certified Platform, where such
	license applies only to those patent claims licensable by such
	Contributor that are necessarily infringed by their Contribution(s)
	alone or by combination of their Contribution(s) with the Work solely
	as incorporated into a Tizen Certified Platform to which such
	Contribution(s) was submitted. If You institute patent litigation
	against any entity (including a cross-claim or counterclaim
	in a lawsuit) alleging that the Work or a Contribution incorporated
	within the Work constitutes direct or contributory patent infringement,
	then any patent licenses granted to You under this License for that
	Work shall terminate as of the date such litigation is filed.

	4. Redistribution.  You may reproduce and distribute copies of the
	Work or Derivative Works thereof pursuant to the copyright license
	above, in any medium, with or without modifications, and in Source or
	Object form, provided that You meet the following conditions:

	  1. You must give any other recipients of the Work or Derivative Works
		 a copy of this License; and
	  2. You must cause any modified files to carry prominent notices stating
		 that You changed the files; and
	  3. You must retain, in the Source form of any Derivative Works that
		 You distribute, all copyright, patent, trademark, and attribution
		 notices from the Source form of the Work, excluding those notices
		 that do not pertain to any part of the Derivative Works; and
	  4. If the Work includes a "NOTICE" text file as part of its distribution,
		 then any Derivative Works that You distribute must include a readable
		 copy of the attribution notices contained within such NOTICE file,
		 excluding those notices that do not pertain to any part of
		 the Derivative Works, in at least one of the following places:
		 within a NOTICE text file distributed as part of the Derivative Works;
		 within the Source form or documentation, if provided along with the
		 Derivative Works; or, within a display generated by the Derivative Works,
		 if and wherever such third-party notices normally appear.
		 The contents of the NOTICE file are for informational purposes only
		 and do not modify the License.

	You may add Your own attribution notices within Derivative Works
	that You distribute, alongside or as an addendum to the NOTICE text
	from the Work, provided that such additional attribution notices
	cannot be construed as modifying the License. You may add Your own
	copyright statement to Your modifications and may provide additional or
	different license terms and conditions for use, reproduction, or
	distribution of Your modifications, or for any such Derivative Works
	as a whole, provided Your use, reproduction, and distribution of
	the Work otherwise complies with the conditions stated in this License.

	5. Submission of Contributions. Unless You explicitly state otherwise,
	any Contribution intentionally submitted for inclusion in the Work
	by You to the Licensor shall be under the terms and conditions of
	this License, without any additional terms or conditions.
	Notwithstanding the above, nothing herein shall supersede or modify
	the terms of any separate license agreement you may have executed
	with Licensor regarding such Contributions.

	6. Trademarks.  This License does not grant permission to use the trade
	names, trademarks, service marks, or product names of the Licensor,
	except as required for reasonable and customary use in describing the
	origin of the Work and reproducing the content of the NOTICE file.

	7. Disclaimer of Warranty. Unless required by applicable law or
	agreed to in writing, Licensor provides the Work (and each
	Contributor provides its Contributions) on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
	implied, including, without limitation, any warranties or conditions
	of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
	PARTICULAR PURPOSE. You are solely responsible for determining the
	appropriateness of using or redistributing the Work and assume any
	risks associated with Your exercise of permissions under this License.

	8. Limitation of Liability. In no event and under no legal theory,
	whether in tort (including negligence), contract, or otherwise,
	unless required by applicable law (such as deliberate and grossly
	negligent acts) or agreed to in writing, shall any Contributor be
	liable to You for damages, including any direct, indirect, special,
	incidental, or consequential damages of any character arising as a
	result of this License or out of the use or inability to use the
	Work (including but not limited to damages for loss of goodwill,
	work stoppage, computer failure or malfunction, or any and all
	other commercial damages or losses), even if such Contributor
	has been advised of the possibility of such damages.

	9. Accepting Warranty or Additional Liability. While redistributing
	the Work or Derivative Works thereof, You may choose to offer,
	and charge a fee for, acceptance of support, warranty, indemnity,
	or other liability obligations and/or rights consistent with this
	License. However, in accepting such obligations, You may act only
	on Your own behalf and on Your sole responsibility, not on behalf
	of any other Contributor, and only if You agree to indemnify,
	defend, and hold each Contributor harmless for any liability
	incurred by, or claims asserted against, such Contributor by reason
	of your accepting any such warranty or additional liability.

	END OF TERMS AND CONDITIONS

	APPENDIX: How to apply the Flora License to your work

	To apply the Flora License to your work, attach the following
	boilerplate notice, with the fields enclosed by brackets "[]"
	replaced with your own identifying information. (Don't include
	the brackets!) The text should be enclosed in the appropriate
	comment syntax for the file format. We also recommend that a
	file or class name and description of purpose be included on the
	same "printed page" as the copyright notice for easier
	identification within third-party archives.

	   Copyright [yyyy] [name of copyright owner]

	   Licensed under the Flora License, Version 1.1 (the "License");
	   you may not use this file except in compliance with the License.
	   You may obtain a copy of the License at

		   http://floralicense.org/license/

	   Unless required by applicable law or agreed to in writing, software
	   distributed under the License is distributed on an "AS IS" BASIS,
	   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	   See the License for the specific language governing permissions and
	   limitations under the License.

 *	Author: Minkyu Kang <mk7.kang@samsung.com>
 */

/*
 * Pinch Event
 *
 * Events
 *	pinchstart: triggered when start the touched two points
 *	pinch: triggered when move the touch point after pinchstart event occured
 *	pinchend: triggered when touchend event after pinchstart event occured
 *
 * Parameters
 *	point: touched points
 *	ratio: origin point-to-current point ratio for moving distance
 *
 *	$("#pinch").bind("pinch", function (e, p) {
 *		console.log("point[0].x: " + p.point[0].x);
 *		console.log("point[0].y: " + p.point[0].y);
 *		console.log("point[1].x: " + p.point[1].x);
 *		console.log("point[1].y: " + p.point[1].y);
 *		console.log("ratio: " + p.ratio);
 *	});
 *
 * Options
 *	$.mobile.pinch.enabled: true or false
 *	$.mobile.pinch.min: minimum value of ratio
 *	$.mobile.pinch.max: maximum value of ratio
 *	$.mobile.pinch.factor: scale factor of ratio
 *	$.mobile.pinch.threshold: move threshold of ratio
 *	$.mobile.pinch.interval: interval for pinch event
 */


( function( $, window, undefined ) {

pinch_event = {
	setup: function () {
		var thisObject = this,
			$this = $( thisObject );

		if ( !$.mobile.support.touch ) {
			return;
		}

		function getSize( point ) {
			var x = point[0].x - point[1].x,
				y = point[0].y - point[1].y;

			return Math.abs( x * y );
		}

		function getParameter( point, ratio ) {
			return { point: point, ratio: ratio };
		}

		$this.bind( "touchstart", function ( event ) {
			var data = event.originalEvent.touches,
				origin,
				last_ratio = 1,
				processing = false;

			if ( !$.mobile.pinch.enabled ) {
				return;
			}

			if ( data.length != 2 ) {
				return;
			}

			origin = [
					{ x: data[0].pageX, y: data[0].pageY },
					{ x: data[1].pageX, y: data[1].pageY }
			];

			$( event.target ).trigger( "pinchstart", getParameter( origin, undefined ) );

			function pinchHandler( event ) {
				var data = event.originalEvent.touches,
					current,
					ratio,
					delta,
					factor = $( window ).width() / $.mobile.pinch.factor;

				if ( processing ) {
					return;
				}

				if ( !origin ) {
					return;
				}

				current = [
						{ x: data[0].pageX, y: data[0].pageY },
						{ x: data[1].pageX, y: data[1].pageY }
				];

				delta = Math.sqrt( getSize( current ) / getSize( origin )  ) ;
				if( delta ) {
					ratio = delta;
				}

				if ( ratio < $.mobile.pinch.min ) {
					ratio = $.mobile.pinch.min;
				} else if ( ratio > $.mobile.pinch.max ) {
					ratio = $.mobile.pinch.max;
				}

				if ( Math.abs( ratio - last_ratio ) < $.mobile.pinch.threshold ) {
					return;
				}

				$( event.target ).trigger( "pinch", getParameter( current, ratio ) );

				last_ratio = ratio;

				if ( $.mobile.pinch.interval ) {
					processing = true;

					setTimeout( function () {
						processing = false;
					}, $.mobile.pinch.interval );
				}
			}

			$this.bind( "touchmove", pinchHandler )
				.one( "touchend", function ( event ) {
					$this.unbind( "touchmove", pinchHandler );
					$( event.target ).trigger( "pinchend",
								getParameter( undefined, last_ratio ) );

					origin = undefined;
					current = undefined;
					last_ratio = 1;
					processing = false;
				});
		});
	}
};

$.event.special["pinch"] = pinch_event;

$.mobile.pinch = {
	enabled: true,
	min: 0.1,
	max: 3,
	factor: 4,
	threshold: 0.01,
	interval: 50
};

})( jQuery, this );



/* ***************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 *
 * Authors: Hyunsook Park <hyunsook.park@samsung.com>
 *			Wonseop Kim <wonseop.kim@samsung.com>
*/

( function ( $, window, document, undefined ) {
	var _canvas = document.createElement( 'canvas' ),
		_context = _canvas.getContext( '2d' );

	function fileSystemErrorMessage( e ) {
		var FileError = window.FileError,
			msg = '';
		switch ( e.code ) {
		case FileError.QUOTA_EXCEEDED_ERR:
			msg = 'QUOTA_EXCEEDED_ERR';
			break;
		case FileError.NOT_FOUND_ERR:
			msg = 'NOT_FOUND_ERR';
			break;
		case FileError.SECURITY_ERR:
			msg = 'SECURITY_ERR';
			break;
		case FileError.INVALID_MODIFICATION_ERR:
			msg = 'INVALID_MODIFICATION_ERR';
			break;
		case FileError.INVALID_STATE_ERR:
			msg = 'INVALID_STATE_ERR';
			break;
		default:
			msg = 'Unknown Error';
			break;
		}
		return msg;
	}

	function getInternalURLFromURL( url ) {
		var internalURL = url.replace( /\//gi, "_" );
		return internalURL;
	}

	function resize( imagewidth, imageheight, thumbwidth, thumbheight, fit ) {
		var w = 0, h = 0, x = 0, y = 0,
			widthratio = imagewidth / thumbwidth,
			heightratio = imageheight / thumbheight,
			maxratio = Math.max( widthratio, heightratio );

		if ( fit ) {
			w = thumbwidth;
			h = thumbheight;
		} else {
			if ( maxratio > 1 ) {
				w = imagewidth / maxratio;
				h = imageheight / maxratio;
			} else {
				w = imagewidth;
				h = imageheight;
			}
			x = ( thumbwidth - w ) / 2;
			y = ( thumbheight - h ) / 2;
		}

		return { w: w, h: h, x: x, y: y };
	}

	function getThumbnail( img, thumbwidth, thumbheight, fit ) {
		var dimensions, url;
		_canvas.width = thumbwidth;
		_canvas.height = thumbheight;
		dimensions = resize( img.width, img.height, thumbwidth, thumbheight, fit );
		_context.fillStyle = "#000000";
		_context.fillRect ( 0, 0, thumbwidth, thumbheight );
		_context.drawImage( img, dimensions.x, dimensions.y, dimensions.w, dimensions.h );
		url = _canvas.toDataURL();
		return url;
	}

	$.imageloader = {
		_grantedBytes: 1024 * 1024,
		getThumbnail: function ( url, _callback ) {
			var internalURL, canvasDataURI;
			function errorHandler( e ) {
				var msg = fileSystemErrorMessage( e );
				if ( _callback ) {
					_callback( ( msg === "NOT_FOUND_ERR" ) ? msg : null );
				}
			}

			internalURL = getInternalURLFromURL( url );
			try {
				canvasDataURI = localStorage.getItem( internalURL );
				if ( _callback ) {
					_callback( ( canvasDataURI === null ) ? "NOT_FOUND_ERR" : canvasDataURI );
				}
			} catch ( e ) {
				if ( _callback ) {
					_callback( ( e.type === "non_object_property_load" ) ? "NOT_FOUND_ERR" : null );
				}
			}
		},

		setThumbnail: function ( url, _callback, thumbWidth, thumbHeight, fit ) {
			var image, internalURL, canvasDataURI;
			function errorHandler( e ) {
				var msg = fileSystemErrorMessage( e );
				if ( _callback ) {
					_callback( ( msg === "NOT_FOUND_ERR" ) ? msg : null );
				}
			}

			thumbWidth = thumbWidth || 128;
			thumbHeight = thumbHeight || 128;
			fit = fit || true;
			image = new Image();
			image.onload = function () {
				internalURL = getInternalURLFromURL( url );
				canvasDataURI = getThumbnail( this, thumbWidth, thumbHeight, fit );
				try {
					localStorage.setItem( internalURL, canvasDataURI );
					if ( _callback ) {
						_callback( canvasDataURI );
					}
				} catch ( e ) {
					if ( _callback ) {
						_callback( ( e.type === "non_object_property_load" ) ? "NOT_FOUND_ERR" : null );
					}
				}
			};
			image.src = url;
		},

		removeThumbnail: function ( url ) {
			var internalURL;
			function errorHandler( e ) {
				fileSystemErrorMessage( e );
			}

			internalURL = getInternalURLFromURL( url );
			try {
				localStorage.removeItem( internalURL );
			} catch ( e ) {
				throw e;
			}
		}
	};

} ( jQuery, window, document ) );



/* ***************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 *
 *  Author: Sanghee Lee <sang-hee.lee@samsung.com>
*/

/**
 *  Splitview is a widget which can show different HTML contents at the same time on each divided pane.
 *  A user can place Splitview controls on JQuery Mobile's Content area and arrange two panes on the widget.
 *  And HTML fragments or another Splitview also can be placed on the pane.
 *  The number of panes inside of Splitview is restricted as two.
 *  If a user define only one pane in Splitview, a empty pane will be added automatically,
 *  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.
 *  The HTML fragments of a pane should be composed of elements describing a part of Web page (e.g. <div>...</div>).
 *  Also widgets can be included in the HTML fragments.
 *
 *  HTML Attributes:
 *
 *      data-fixed : The resizing mode of panes - fixed and flexible mode.
 *              If the value is true, the panes' sizes will be fixed, or if not, it will be flexible. (Default : false)
 *      data-divider-vertical : The direction of dividers.
 *              If the value is true, the panes will be placed in horizontal direction,
 *              or if not, it will be placed in vertical direction. (Default : "true")
 *      data-ratio : The ratio of two panes' widths or heights. (Default : [ 1/2, 1/2 ]
 *
 *  APIs:
 *
 *      pane ( id [ , element ] )
 *          : This method replaces child contents of a pane indicated by id attribute with contents of inputted element.
 *            If second argument is not specified, it will act as a getter method.
 *            The string of id has to be started with "#" which means "id" of CSS selectors.
 *      maximize ( id )
 *          : This method maximizes a pane's size indicated by id.
 *            The string of id has to be started with "#" which means "id" of CSS selectors.
 *      restore ()
 *          : This method restores all panes' sizes to the ratio prior to maximization.
 *
 *  Examples:
 *
 *      <div data-role="splitview" data-fixed="false" data-divider-vertical="true" data-ratio="0.5, 0.5">
 *          <div class="ui-pane">pane0</div>
 *          <div class="ui-pane">pane1</div>
 *      </div>
 *
 */


/**
	@class Splitview
	Splitview widget enables a user to place and arrange several panes. Each divided pane can show repective HTML contents.

	To add a Splitview widget to the application, use the following code:

		<div data-role="splitview" data-fixed="false" data-divider-vertical="true" data-ratio="0.5, 0.5">
			<div class="ui-pane">pane0</div>
			<div class="ui-pane">pane1</div>
		</div>
*/

/**
	@property {Boolean} data-fixed
	The resizing mode of panes - fixed and flexible mode.
*/

/**
	@property {Boolean} data-divider-vertical
	The direction of dividers - horizontal or vertical.
 */

/**
	@property {Array} data-ratio
	The ratio of two panes' widths or heights.
*/

/**
	@method pane
	This method replaces child contents of a pane indicated by id attribute with contents of inputted element.
	If second argument is not specified, it will act as a getter method.

		<div data-role="splitview">
			<div class="ui-pane" id="pane0">pane0</div>
			<div class="ui-pane" id="pane1">pane1</div>
		</div>
		$(".selector").splitview("pane", id, element);
*/

/**
	@method maximize
	This method maximizes a pane's size indicated by id.

		<div data-role="splitview">
			<div class="ui-pane" id="pane0">pane0</div>
			<div class="ui-pane" id="pane1">pane1</div>
		</div>
		$(".selector").splitview("maximize", id);
*/

/**
	@method restore
	This method restores all panes' sizes to the ratio prior to maximization.

		<div data-role="splitview">
			<div class="ui-pane" id="pane0">pane0</div>
			<div class="ui-pane" id="pane1">pane1</div>
		</div>
		$(".selector").splitview("restore");
*/

( function ( $, window, document, undefined ) {
	$.widget( "tizen.splitview", $.mobile.widget, {
		options : {
			fixed : false,
			dividerVertical : true,
			ratio : [],
			initSelector : ":jqmData(role='splitview')"
		},

		_create : function () {
			var self = this,
				$el = self.element,
				opt = self.options,
				$panes = $el.children( ".ui-pane" ),
				panesLength = $panes.length,
				spliters = [],
				spliterBars = [],
				ratioAttr = this.element.attr( "data-ratio" ),
				containerSize = [ 0, 0 ],
				resizeTimer = null,
				i = 0;

			if ( panesLength !== 2 ) {
				if ( panesLength < 2 ) {
					for ( i = panesLength ; i < 2 ; ++i ) {
						self._addEmptyPanes();
					}
				} else {
					$panes.slice( 2 ).remove();
				}

				$panes = $el.children( ".ui-pane" );
				panesLength = $panes.length;
			}

			spliters[ 0 ] = $( "<a href='#' class='ui-spliter' aria-label='Drag scroll, double tap and move to adjust split area'></a>" ).insertAfter( $panes[ 0 ] );
			spliterBars[ 0 ] = $( "<div class='ui-spliter-bar'></div>" ).appendTo( spliters[ 0 ] );
			$( "<div class='ui-spliter-handle'></div>" ).appendTo( spliterBars[ 0 ] );

			$.extend( this, {
				moveTarget : null,
				moveData : {},
				spliters : spliters,
				spliterBars : spliterBars,
				panes : $panes,
				containerSize : containerSize,
				touchStatus : false,
				minPaneWidth : 50,
				savedRatio : []
			});

			self._bindTouchEvents();
			self._convertRatio( ratioAttr, $panes.length );

			$el.addClass( "ui-splitview ui-direction-" + self._direction( opt.dividerVertical ) );

			self._refresh();

			$( window ).unbind( ".splitview" )
				.bind( "pagechange.splitview resize.splitview", function ( event ) {
					$( ".ui-page-active .ui-splitview" ).each( function () {
						$( this ).data( "splitview" )._refresh();
					});
				});
		},

		_addEmptyPanes : function () {
			var self = this,
				$el = self.element,
				opt = self.options,
				$panes = $el.children( ".ui-pane" ),
				scrollAttribute = ( $.support.scrollview ) ? "data-scroll='y'" : "",
				pane = $( "<div class='ui-pane' " + scrollAttribute + "></div>" );

			if ( scrollAttribute.length ) {
				pane.scrollview( { direction: "y" } );
			}

			if ( !$panes.length ) {
				$el.append( pane );
			} else {
				$panes.last().after( pane );
			}
		},

		_direction : function ( isHorizontal ) {
			return isHorizontal ? "horizontal" : "vertical";
		},

		_isStyleSpecified : function ( cssString ) {
			return ( typeof cssString !== "undefined" && cssString.length );
		},

		_getContainerSize : function ( widthString, heightString ) {
			var self = this,
				$el = self.element,
				widthSpecified = self._isStyleSpecified( widthString ),
				heightSpecified = self._isStyleSpecified( heightString );

			self.containerSize[ 0 ] = ( widthSpecified ) ? $el.outerWidth( true ) : self._parentWidth();
			self.containerSize[ 1 ] = ( heightSpecified ) ? $el.outerHeight( true ) : self._parentHeight();

			if ( !self.containerSize[ 0 ] || !self.containerSize[ 1 ] ) {
				return false;
			}

			return true;
		},

		_parentWidth : function () {
			var $parent = this.element.parent();

			if ( !$parent && typeof $parent === "undefined" && !$parent.length ) {
				return $( window ).width();
			}

			return $parent.width();
		},

		_parentHeight : function () {
			var $parent = this.element.parent(),
				heightString = "",
				heightSpecified = false,
				parentHeight = 0;

			while ( $parent && typeof $parent !== "undefined" && $parent.length ) {
				if ( typeof $parent[ 0 ].style !== "undefined" ) {
					heightString = $parent[ 0 ].style.height;
					heightSpecified = ( typeof heightString !== "undefined" && heightString.length );
					if ( heightSpecified ) {
						parentHeight = $parent.height();
						break;
					}
				}

				$parent = $parent.parent();
			}

			if ( !heightSpecified ) {
				parentHeight = $(window).height();
			}

			return parentHeight;
		},

		_convertRatio : function ( ratioParam, panesLength ) {
			var self = this,
				ratio = [],
				loop = 0,
				type = typeof ratioParam,
				ratioArray = null,
				i;

			for ( i = 0; i < panesLength; ++i ) {
				ratio.push( 0 );
			}

			switch ( type ) {
			case "number":
				if ( panesLength ) {
					ratio[ 0 ] = ratioParam;
				}
				break;

			case "string":
				ratioArray = ratioParam.split( "," );
				loop = Math.min( ratioArray.length, panesLength );
				for ( i = 0; i < loop; ++i ) {
					ratio[ i ] = parseFloat( ratioArray[ i ] );
				}
				break;

			case "object":
				if ( !$.isArray( ratioParam ) ) {
					break;
				}

				loop = Math.min( ratioParam.length, panesLength );
				for ( i = 0; i < loop; ++i ) {
					type = typeof ratioParam[ i ];
					ratio[ i ] = ( type === "string" ) ? parseFloat( ratioParam[ i ] ) :
								( type === "number" ) ? ratioParam[ i ] : 0;
				}
				break;
			}

			self.options.ratio = ratio;
			self._adjustRatio( panesLength );
		},

		_adjustRatio : function ( panesLength ) {
			var self = this,
				ratio = self.options.ratio,
				sum = 0,
				remain = 0,
				value = 0,
				subValue = 0,
				subRemain = 0,
				i;

			if ( !panesLength ) {
				self.options.ratio = [];
				return;
			}

			for ( i in ratio ) {
				sum += ratio[ i ];
			}

			if ( sum !== 1 ) {
				remain = 1 - sum;
				value = remain / panesLength;

				for ( i in ratio ) {
					if ( value >= 0 ) {
						ratio[ i ] += value;
						remain = Math.max( 0, remain - value );
					} else {
						subRemain += value;
						subValue = Math.max( subRemain, ratio[ i ] * -1 );
						ratio[ i ] = Math.max( 0, ratio[ i ] + subValue );
						remain = Math.min( 0, remain - subValue );
						subRemain -= subValue;
					}
				}

				if ( remain ) {
					if ( remain > 0 ) {
						ratio[ ratio.length - 1 ] += remain;
					} else {
						for ( i = ratio.length - 1; i >= 0; --i ) {
							subValue = Math.max( remain, ratio[ i ] * -1 );
							ratio[ i ] = Math.max( 0, ratio[ i ] + subValue );
							remain = Math.min( 0, remain - subValue );
							if ( !remain ) {
								break;
							}
						}
					}
				}

				self.options.ratio = ratio;
			}
		},

		_setOption : function ( key, value ) {
			var self = this,
				orgValue = self.options[ key ];

			if ( orgValue === value ) {
				return;
			}

			$.Widget.prototype._setOption.apply( this, arguments );

			switch ( key ) {
			case "fixed":
				self._fixed( value );
				break;

			case "dividerVertical":
				self._dividerVertical( value );
				break;

			case "ratio":
				self._ratio( value );
				break;
			}
		},

		_subtractDiffWidth : function ( width, diff ) {
			var self = this;

			if ( width <= self.minPaneWidth ) {
				return {
					width: width,
					diff: diff
				};
			}

			width += diff;
			if ( width >= self.minPaneWidth ) {
				return {
					width: width,
					diff: 0
				};
			}

			return {
				width: self.minPaneWidth,
				diff: width - self.minPaneWidth
			};
		},

		_initRatio : function ( fromFirstPane, panes, isHorizontal, availableWidth ) {
			var self = this,
				sum = 0,
				widths = [],
				diff = 0,
				panesLength = panes.length,
				ret,
				i;

			panes.each( function ( i ) {
				var pane = $( this );
				widths.push( isHorizontal ? pane.width() : pane.height() );
				sum += widths[ i ];
			});

			diff = availableWidth - sum;
			if ( !diff ) {
				return widths;
			}

			if ( diff > 0 ) {
				widths[ fromFirstPane ? 0 : panesLength - 1 ] += diff;
			} else {
				if ( fromFirstPane ) {
					for ( i = 0; i < panesLength; ++i ) {
						ret = self._subtractDiffWidth( widths[ i ], diff );
						widths[ i ] = ret.width;
						diff = ret.diff;
						if ( !diff ) {
							break;
						}
					}
				} else {
					for ( i = panesLength - 1; i >= 0; --i ) {
						diff = self._subtractDiffWidth( widths[ i ], diff );
						widths[ i ] = ret.width;
						diff = ret.diff;
						if ( !diff ) {
							break;
						}
					}
				}
			}

			sum = 0;
			for ( i in widths ) {
				sum += widths[ i ];
			}

			for ( i in self.options.ratio ) {
				self.options.ratio[ i ] = widths[ i ] / sum;
			}

			return widths;
		},

		_horizontalBoundary : function () {
			var self = this,
				$el = self.element;

			return $el.outerWidth( true ) - $el.width();
		},

		_verticalBoundary : function () {
			var self = this,
				$el = self.element;

			return $el.outerHeight( true ) - $el.height();
		},

		_boundary : function ( type ) {
			var self = this,
				$el = self.element,
				computedStyle = window.getComputedStyle( $el[ 0 ], null ),
				margin = parseFloat( computedStyle[ "margin" + type ] ),
				border = parseFloat( computedStyle[ "border" + type + "Width" ] ),
				padding = parseFloat( computedStyle[ "padding" + type ] );

			return {
				margin: margin,
				border: border,
				padding: padding
			};
		},

		_layout : function ( initRatio, fromFirstPane ) {
			var self = this,
				$el = self.element,
				opt = self.options,
				isHorizontal = opt.dividerVertical,
				$panes = self.panes,
				spliters = self.spliters,
				spliterBars = self.spliterBars,
				spliterBar = self.spliterBars.length ? $( spliterBars[ 0 ] ) : null,
				spliterWidth = !spliterBar ? 0 :
								isHorizontal ? spliterBar.outerWidth() :
												spliterBar.outerHeight(),
				spliterBarMargin = !spliterBar ? 0 :
									isHorizontal ?
										spliterBar.outerWidth( true ) - spliterBar.outerWidth() :
										spliterBar.outerHeight( true ) - spliterBar.outerHeight(),
				panesLength = $panes.length,
				currentAvailable = 0,
				spliterSize = spliterWidth * ( panesLength - 1 ),
				parentWidth = self.containerSize[ 0 ],
				parentHeight = self.containerSize[ 1 ],
				width = parentWidth - self._horizontalBoundary(),
				height = parentHeight - self._verticalBoundary(),
				innerSize = isHorizontal ? height : width,
				availableWidth = isHorizontal ? width - spliterSize :
												height - spliterSize,
				initializedWidth = [],
				widthSum = 0,
				childSplitview = null;

			initRatio = !!initRatio;
			fromFirstPane = !!fromFirstPane;

			$el.css( {
				"min-width" : width,
				"min-height" : height
			});

			if ( initRatio ) {
				initializedWidth = self._initRatio( fromFirstPane, $panes, isHorizontal, availableWidth );
			}

			currentAvailable = availableWidth;
			$panes.each( function ( i ) {
				var $pane = $( this ),
					paneWidth = initRatio ? initializedWidth[ i ] :
										Math.floor( availableWidth * self.options.ratio[i] ),
					prevPane = ( ( i ) ? $panes.eq( i - 1 ) : null ),
					posValue = 0,
					widthValue = 0,
					heightValue = 0,
					boundary = 0;

				currentAvailable -= paneWidth;
				if ( i === ( panesLength - 1 ) ) {
					if ( self.touchStatus ) {
						paneWidth = self.moveData.nextPaneWidth = availableWidth - ( self.moveData.targetPos + spliterWidth );
					} else {
						paneWidth = Math.max( Math.min( paneWidth, self.minPaneWidth ), paneWidth + currentAvailable );
					}
				}

				widthSum += paneWidth;

				if ( !prevPane ) {
					boundary = self._boundary( isHorizontal ? "Left" : "Top" );
					posValue = boundary.padding;
				} else {
					posValue = parseInt( prevPane.css( isHorizontal ? "left" : "top" ), 10 );
					posValue += isHorizontal ? prevPane.width() : prevPane.height();
					posValue += spliterWidth;
				}

				widthValue = isHorizontal ? paneWidth : innerSize;
				heightValue = isHorizontal ? innerSize : paneWidth;

				$pane.css( {
					"width" : widthValue ,
					"height" : heightValue
				} );

				$pane.css( ( isHorizontal ? "left" : "top" ), posValue );
			});

			$panes.each( function ( i ) {
				var $pane = $( this ),
					paneWidth = isHorizontal ? $pane.width() : $pane.height();

				self.options.ratio[ i ] = paneWidth / widthSum;
			});

			$.each( spliters, function ( i ) {
				var spliter = $( this ),
					prevPane = $panes.eq( i ),
					bar = spliter.children( ".ui-spliter-bar" ),
					handle = bar.children( ".ui-spliter-handle" ),
					posValue = 0;

				if ( isHorizontal ) {
					posValue = parseInt( prevPane.css( "left" ), 10 ) + prevPane.width() - spliterBarMargin;
					spliter.outerHeight( innerSize ).css( "left", posValue );
				} else {
					posValue = parseInt( prevPane.css( "top" ), 10 ) + prevPane.height() - spliterBarMargin;
					spliter.outerWidth( innerSize ).css( "top", posValue );
				}

				if ( bar.length ) {
					bar[ isHorizontal ? "outerHeight" : "outerWidth" ]( innerSize );
				}
				if ( handle.length ) {
					handle.css( isHorizontal ? "top" : "left", ( innerSize - spliterWidth ) / 2 );
				}
			});

			childSplitview = $el.find( ".ui-splitview:first" );
			if ( !childSplitview.length ) {
				return;
			}

			childSplitview = childSplitview.data( "splitview" );
			if ( childSplitview ) {
				childSplitview._refresh();
			}
		},

		_bindTouchEvents : function () {
			var self = this,
				$el = self.element,
				$panes = self.panes,
				spliters = self.spliters;

			$.each( spliters, function ( i ) {
				var spliter = $( this );
				self._bindSpliterTouchEvents.call( self, spliter );
			});
		},

		_bindSpliterTouchEvents : function ( spliter ) {
			var self = this,
				$el = self.element,
				opt = self.options,
				touchStartEvt = ( $.support.touch ? "touchstart" : "mousedown" ),
				touchMoveEvt = ( $.support.touch ? "touchmove" : "mousemove" ) + ".splitview",
				touchEndEvt = ( $.support.touch ? "touchend" : "mouseup" ) + ".splitview";

			spliter.bind( touchStartEvt, { e : spliter }, function ( event ) {
				if ( self.options.fixed ) {
					return;
				}

				var realEvent = $.support.touch ? event.originalEvent.changedTouches[0] : event,
					targetSpliter = event.data.e,
					prevPane = targetSpliter.prev(),
					nextPane = targetSpliter.next(),
					splitviewInPrev = prevPane.find( ".ui-splitview:first" ),
					splitviewInNext = nextPane.find( ".ui-splitview:first" ),
					isHorizontal = opt.dividerVertical,
					spliterWidth = isHorizontal ?
									$( self.spliterBars[0] ).outerWidth() :
									$( self.spliterBars[0] ).outerHeight();

				self.moveTarget = targetSpliter;
				self.moveData = {
					spliterWidth : spliterWidth || 0,
					prevPane : prevPane,
					nextPane : nextPane,
					splitviewInPrev : splitviewInPrev,
					splitviewInNext : splitviewInNext,
					prevPanePos : parseInt( prevPane.css( isHorizontal ? "left" : "top" ), 10 ) || 0,
					prevPaneWidth : parseInt( prevPane.css( isHorizontal ? "width" : "height" ), 10 ) || 0,
					nextPanePos : parseInt( nextPane.css( isHorizontal ? "left" : "top" ), 10 ) || 0,
					nextPaneWidth : parseInt( nextPane.css( isHorizontal ? "width" : "height" ), 10 ) || 0,
					targetPos : parseInt( targetSpliter.css( isHorizontal ? "left" : "top" ), 10 ) || 0,
					pagePos : isHorizontal ? realEvent.pageX : realEvent.pageY
				};

				targetSpliter.addClass( "ui-spliter-active" );

				$el.bind( touchMoveEvt, function ( event ) {
					if ( !self.touchStatus ) {
						return;
					}
					event.stopPropagation();
					self._drag( $.support.touch ? event.originalEvent.changedTouches[0] : event );
				}).bind( touchEndEvt, function ( event ) {
					event.stopPropagation();
					self._stop( $.support.touch ? event.originalEvent.changedTouches[0] : event );
					self.touchStatus = false;
					$el.unbind( ".splitview" );
					$( document ).unbind( ".splitview" );
				});

				$( document ).bind( touchMoveEvt + " " + touchEndEvt, function () {
					$el.trigger( touchEndEvt );
				});

				event.preventDefault();
				self.touchStatus = true;
			});
		},

		_drag : function ( e ) {
			if ( !this.moveData || typeof this.moveData === "undefined" ) {
				return;
			}

			var self = this,
				$el = self.element,
				opt = self.options,
				isHorizontal = opt.dividerVertical,
				moveData = self.moveData,
				moveTarget = self.moveTarget,
				prevPane = moveData.prevPane,
				nextPane = moveData.nextPane,
				splitviewInPrev = moveData.splitviewInPrev,
				splitviewInNext = moveData.splitviewInNext,
				spliterWidth = moveData.spliterWidth,
				movement = null,
				targetPos = null,
				nextPanePos = null,
				prevPaneWidth = null,
				nextPaneWidth = null,
				pagePos = isHorizontal ? e.pageX : e.pageY,
				splitview = null;

			movement = pagePos - moveData.pagePos;
			if ( movement > 0 ) {
				movement = Math.min( Math.max( moveData.nextPaneWidth - self.minPaneWidth, 0 ), movement );
			} else {
				movement = Math.max( Math.max( moveData.prevPaneWidth - self.minPaneWidth, 0 ) * -1, movement );
			}

			nextPanePos = moveData.nextPanePos + movement;
			prevPaneWidth = Math.max( moveData.prevPaneWidth + movement, 0 );
			nextPaneWidth = Math.max( moveData.nextPaneWidth - movement, 0 );
			targetPos = moveData.targetPos + movement;

			moveTarget.css( isHorizontal ? { left : targetPos } : { top : targetPos } );
			prevPane.css( isHorizontal ? { width : prevPaneWidth } : { height : prevPaneWidth } );
			nextPane.css( isHorizontal ? { width : nextPaneWidth, left : nextPanePos } :
											{ height : nextPaneWidth, top : nextPanePos } );

			if ( splitviewInPrev.length ) {
				splitview = splitviewInPrev.data( "splitview" );
				splitview._refresh( true, false );
			}

			if ( splitviewInNext.length ) {
				splitview = splitviewInNext.data( "splitview" );
				splitview._refresh( true, true );
			}
		},

		_stop : function ( e ) {
			if ( !this.moveData || !this.moveTarget ) {
				return;
			}

			var self = this,
				$el = self.element,
				opt = self.options,
				$panes = self.panes,
				panesLength = $panes.length,
				isHorizontal = opt.dividerVertical,
				moveData = self.moveData,
				moveTarget = self.moveTarget,
				prevPane = moveData.prevPane,
				nextPane = moveData.nextPane,
				splitviewInPrev = moveData.splitviewInPrev,
				splitviewInNext = moveData.splitviewInNext,
				spliterWidth = moveData.spliterWidth,
				spliterSize = spliterWidth * ( panesLength - 1 ),
				movement = null,
				targetPos = null,
				nextPanePos = null,
				prevPaneWidth = null,
				nextPaneWidth = null,
				displayStyle = $el.css( "display" ),
				parentWidth = self.containerSize[ 0 ],
				parentHeight = self.containerSize[ 1 ],
				width = parentWidth - self._horizontalBoundary(),
				height = parentHeight - self._verticalBoundary(),
				availableWidth = isHorizontal ?
									( width - spliterSize ) :
									( height - spliterSize ),
				sum = 0;

			moveTarget.removeClass( "ui-spliter-active" );

			// ratio calculation
			$panes.each( function ( i ) {
				var $pane = $( this ),
					paneWidth = isHorizontal ? $pane.width() : $pane.height();

				sum += paneWidth;
			});

			$panes.each( function ( i ) {
				var $pane = $( this ),
					paneWidth = isHorizontal ? $pane.width() : $pane.height();

				self.options.ratio[ i ] = paneWidth / sum;
			});

			self.moveData = null;
		},

		_fixed : function ( isFix ) {
			var self = this,
				spliters = self.spliters;

			$.each( spliters, function ( i ) {
				var $spliter = $( this );

				if ( isFix ) {
					$spliter.addClass( "ui-fixed" );
				} else {
					$spliter.removeClass( "ui-fixed" );
				}
			});

			self._layout();
		},

		_dividerVertical : function ( isDividerVertical ) {
			var self = this,
				$el = self.element,
				isHorizontal = isDividerVertical,
				$panes = null,
				$spliters = null,
				$bar = null,
				$handle = null;

			$panes = $el.children( ".ui-pane" );
			$spliters = $el.children( ".ui-spliter" );
			$bar = $spliters.children( ".ui-spliter-bar" );
			$handle = $bar.children( ".ui-spliter-handle" );

			$el.removeClass( "ui-direction-vertical" );
			$el.removeClass( "ui-direction-horizontal" );
			$el.addClass( "ui-splitview ui-direction-" + self._direction( isHorizontal ) );

			$panes.css( {
				"left" : "",
				"top" : "",
				"width" : "",
				"height" : ""
			});

			$spliters.css( {
				"left" : "",
				"top" : "",
				"width" : "",
				"height" : ""
			});

			$bar.css( {
				"width" : "",
				"height" : ""
			});

			$handle.css( {
				"left" : "",
				"top" : ""
			});

			if ( self._getContainerSize( $el[ 0 ].style.width, $el[ 0 ].style.height ) ) {
				self._layout();
			}
		},

		_ratio : function ( ratioParam ) {
			var self = this,
				$el = self.element,
				$panes = $el.children( ".ui-pane" ),
				panesLength = $panes.length;

			self._convertRatio( ratioParam, panesLength );
			self._layout();
		},

		_refresh : function ( initRatio, fromFirstPane ) {
			var self = this,
				$el = self.element;

			initRatio = !!initRatio;
			fromFirstPane = !!fromFirstPane;

			if ( self._getContainerSize( $el[ 0 ].style.width, $el[ 0 ].style.height ) ) {
				self._layout( initRatio, fromFirstPane );
			}
		},

		pane : function ( id, element ) {
			if ( typeof id !== "string" ) {
				return null;
			}

			var self = this,
				$el = self.element,
				$targetPane = $el.children( id ),
				$targetView = null,
				elementParent = null;

			if ( !$targetPane.hasClass( "ui-pane" ) ) {
				return null;
			}

			// getter
			if ( !element ) {
				return $targetPane.contents();
			}

			// setter
			if ( $targetPane.hasClass( "ui-scrollview-clip" ) ) {
				$targetPane.scrollview( "scrollTo", 0, 0, 0 );

				$targetView = $targetPane.children( ".ui-scrollview-view" );
				if ( !$targetView.length ) {
					return null;
				}
			} else {
				$targetView = $targetPane;
			}

			elementParent = element.parent();
			if ( elementParent.length && elementParent[ 0 ] === $targetView[ 0 ] ) {
				return;
			}

			$targetView.empty().append( element ).trigger( "create" );
			$targetView.fadeIn( 'fast' );
		},

		maximize : function ( id ) {
			if ( typeof id !== "string" ) {
				return;
			}

			var self = this,
				$el = self.element,
				$panes = self.panes,
				$targetPane = $el.children( id );

			if ( !$targetPane.hasClass( "ui-pane" ) ) {
				return;
			}

			self.savedRatio = self.options.ratio.slice();

			self.options.ratio = [];
			$panes.each( function ( i ) {
				self.options.ratio.push( ( this === $targetPane[ 0 ] ) ? 1 : 0 );
			});

			self._layout();
		},

		restore : function () {
			var self = this;

			if ( !self.savedRatio.length ) {
				return;
			}

			self.options.ratio = self.savedRatio.slice();
			self._adjustRatio( self.panes.length );

			self._layout();
		}
	});

	$( document ).bind( "pagecreate create", function ( e ) {
		$.tizen.splitview.prototype.enhanceWithin( e.target );
	});
} ( jQuery, window, document ) );



/**
	@class Checkbox
	The check box widget shows a list of options on the screen where one or more can be selected. Check boxes can be used in Tizen as described in the jQueryMobile documentation for check boxes.<br/> To add a check box widget to the application, use the following code:

		<input type="checkbox" name="mycheck" id="check-test" class="favorite" />
		<label for="check-test">Favorite</label>
		<input type="checkbox" name="check-favorite" id="check-test2" checked="checked" disabled="disabled" class="favorite" />
		<label for="check-test2">Favorite Checked, Disabled</label>

	The check box can define callbacks for events as described in the jQueryMobile documentation for check box events.
	You can use methods with the check box as described in the jQueryMobile documentation for check box methods.

*/
/**
	@property {String} class
	Defines the check box style. <br/> The default value is check. If the value is set to favorite, a star-shaped check box is created.
*/



/* ***************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 *
 * Authors: Hyunsook Park <hyunsook.park@samsung.com>
 *			Wonseop Kim <wonseop.kim@samsung.com>
*/

( function ( $, window, undefined ) {
	var HALF_PI = Math.PI / 2,
		DEFAULT_STEP = 0.001,
		MotionPath = {},
		vec3 = window.vec3,
		arcLength3d = function ( p0, p1 ) {
			var d = [ p1[0] - p0[0], p1[1] - p0[1], p1[2] - p0[2] ],
				value = Math.sqrt( d[0] * d[0] + d[1] * d[1] + d[2] * d[2] );
			return value;
		};

	MotionPath.base = function () {};
	MotionPath.base.prototype = {
		points: [],
		step: DEFAULT_STEP,
		length: 0,
		levels: [],
		init: function ( data ) {},
		calculateLevel: function ( maxLevel ) {},
		calculateTotalLength: function () {},
		getPosition: function ( percent ) {},
		getPercent: function ( start, interval ) {},
		getAngle: function ( percent ) {}
	};

	MotionPath.bezier2d = function () {};
	MotionPath.bezier2d.prototype = $.extend( true, {}, MotionPath.base.prototype, {
		init: function ( data ) {
			this.points = data.points;
			this.step = data.step || DEFAULT_STEP;
			this.length = this.calculateTotalLength();
			this.levels = this.calculateLevel( data.maxLevel ) || [];
		},

		calculateLevel: function ( maxLevel ) {
			var totalLength = this.length,
				interval = totalLength / maxLevel,
				levels = [],
				i;

			if ( !maxLevel ) {
				return null;
			}

			for ( i = 0; i < maxLevel; i += 1 ) {
				levels[maxLevel - i] = this.getPercent( 0, interval * i );
			}

			return levels;
		},

		calculateTotalLength: function () {
			var step = this.step,
				current = this.getPosition( 0 ),
				last = current,
				length = 0,
				percent;
			for ( percent = step; percent <= 1; percent += step ) {
				current = this.getPosition( percent );
				length += arcLength3d( last, current );
				last = current;
			}
			return length;
		},

		getPosition: function ( percent ) {
			var points = this.points,
				getValue = function ( p1, c1, c2, p2, t ) {
					return Math.pow(1 - t, 3) * p1 +
						3 * t * Math.pow( 1 - t, 2 ) * c1 +
						3 * Math.pow( t, 2 ) * ( 1 - t ) * c2 +
						Math.pow( t, 3 ) * p2;
				},
				result = [
					getValue( points[0][0], points[1][0], points[2][0], points[3][0], percent ),
					getValue( points[0][2], points[1][2], points[2][2], points[3][2], percent )
				];
			return [ result[0], 0, result[1] ];
		},

		getPercent: function ( start, interval ) {
			var step = this.step,
				current = this.getPosition( start = start || 0 ),
				last = current,
				targetLength = start + interval,
				length = 0,
				percent;

			for ( percent = start + step; percent <= 1; percent += step ) {
				current = this.getPosition( percent );
				length += arcLength3d( last, current );
				if ( length >= targetLength ) {
					return percent;
				}
				last = current;
			}
			return 1;
		},

		getAngle: function ( percent ) {
			var points = this.points,
				getTangent = function ( p1, c1, c2, p2, t ) {
					return 3 * t * t * ( -p1 + 3 * c1 - 3 * c2 + p2 ) + 6 * t * ( p1 - 2 * c1 + c2 ) + 3 * ( -p1 + c1 );
				},
				tx = getTangent( points[0][0], points[1][0], points[2][0], points[3][0], percent ),
				ty = getTangent( points[0][2], points[1][2], points[2][2], points[3][2], percent );
			return Math.atan2( tx, ty ) - HALF_PI;
		}

	} );

	// clamped cubic B-spline curve
	// http://web.mit.edu/hyperbook/Patrikalakis-Maekawa-Cho/node17.html
	// http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/B-spline/bspline-curve-coef.html
	MotionPath.bspline = function () {};
	MotionPath.bspline.prototype = $.extend( true, {}, MotionPath.base.prototype, {
		_degree: 3,
		_numberOfControls : 0,
		_knotVectors: [],
		_numberOfKnots: 0,

		init: function ( data ) {
			this.points = data.points;
			this.step = data.step || DEFAULT_STEP;
			this._numberOfPoints = this.points.length - 1;
			this._numberOfKnots = this._numberOfPoints + this._degree + 1;

			var deltaKnot = 1 / ( this._numberOfKnots - ( 2 * this._degree ) ),
				v = deltaKnot,
				i = 0;

			while ( i <= this._numberOfKnots ) {
				if ( i <= this._degree ) {
					this._knotVectors.push( 0 );
				} else if ( i < this._numberOfKnots - this._degree + 1 ) {
					this._knotVectors.push( v );
					v += deltaKnot;
				} else {
					this._knotVectors.push( 1 );
				}
				i += 1;
			}

			this.length = this.calculateTotalLength();
			this.levels = this.calculateLevel( data.maxLevel ) || [];
		},

		_Np: function ( percent, i, degree ) {
			var knots = this._knotVectors,
				A = 0,
				B = 0,
				denominator = 0,
				N0 = function ( percent, i ) {
					return ( ( knots[i] <= percent && percent < knots[i + 1] ) ? 1 : 0 );
				};

			if ( degree === 1 ) {
				A = N0( percent, i );
				B = N0( percent, i + 1 );
			} else {
				A = this._Np( percent, i, degree - 1 );
				B = this._Np( percent, i + 1, degree - 1 );
			}

			denominator = knots[i + degree] - knots[i];
			A *= ( denominator !== 0 ) ? ( ( percent - knots[i] ) / denominator ) : 0;
			denominator = knots[i + degree + 1] - knots[i + 1];
			B *= ( denominator !== 0 ) ? ( ( knots[i + degree + 1] - percent ) / denominator ) : 0;

			return A + B;
		},

		calculateLevel: function ( maxLevel ) {
			var totalLength = this.length,
				interval = totalLength / maxLevel,
				levels = [],
				i;

			if ( !maxLevel ) {
				return null;
			}

			for ( i = 0; i < maxLevel; i += 1 ) {
				levels[maxLevel - i] = this.getPercent( 0, interval * i );
			}
			return levels;
		},

		calculateTotalLength: function () {
			var step = this.step,
				current = this.getPosition( 0 ),
				last = current,
				length = 0,
				percent;
			for ( percent = step; percent <= 1; percent += step ) {
				current = this.getPosition( percent );
				length += arcLength3d( last, current );
				last = current;
			}
			return length;
		},

		getPosition: function ( percent ) {
			var result = [], i, j, sum;
			percent = percent.toFixed( 4 );
			for ( j = 0; j < 3; j += 1 ) {
				sum = 0;
				for ( i = 0; i <= this._numberOfPoints; i += 1 ) {
					sum += this.points[i][j] * this._Np( percent, i, this._degree );
				}
				result[j] = sum;
			}

			return result;
		},

		getPercent: function ( start, interval ) {
			var step = this.step,
				current = this.getPosition( start = start || 0 ),
				last = current,
				targetLength = start + interval,
				length = 0,
				percent;

			for ( percent = start + step; percent <= 1; percent += step ) {
				current = this.getPosition( percent );
				length += arcLength3d( last, current );
				if ( length >= targetLength ) {
					return percent;
				}
				last = current;
			}
			return 1;
		},

		getAngle: function ( percent ) {
			var prev = this.getPosition( percent ),
				next = this.getPosition( percent + 0.001 ),
				dir = vec3.normalize( vec3.direction( prev, next ) ),
				cosValue = vec3.dot( dir, [1, 0, 0] );

			return Math.acos( cosValue ) + Math.PI;
		}
	} );

	$.motionpath = function ( type, data ) {
		var object = new MotionPath[type]();
		object.init( data );
		return object;
	};
} ( jQuery, window ) );



/****************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 *
 *	Author: Wongi Lee <wongi11.lee@samsung.com>
*/

/**
 *	Extendable List Widget for unlimited data.
 *	To support more then 1,000 items, special list widget developed.
 *	Fast initialize and append some element into the DOM tree repeatedly.
 *	DB connection and works like DB cursor.
 *
 * HTML Attributes:
 *
 *		data-role:	extendablelist
 *		data-template : jQuery.template ID that populate into extendable list. A button : a <DIV> element with "data-role : button" should be included on data-template.
 *		data-dbtable : DB Table name. It used as window[DB NAME]. Loaded data should be converted as window object.
 *		data-extenditems : Number of elements to extend at once.
 *		
 *		ID : <UL> element that has "data-role=extendablelist" must have ID attribute.
 *		Class : <UL> element that has "data-role=extendablelist" should have "vlLoadSuccess" class to guaranty DB loading is completed.
 *		tmp_load_more : Template ID for "load more" message and button.
 *
 *
 *APIs:
 *		create ( {
 *				itemData: function ( idx ) { return json_obj; },
 *				numItemData: number or function () { return number; },
 *				cacheItemData: function ( minIdx, maxIdx ) {}
 *				} )
 *			: Create a extendable list widget. At this moment, _create method is called.
 *			args : A collection of options
 *				itemData: A function that returns JSON object for given index. Mandatory.
 *				numItemData: Total number of itemData. Mandatory.
 *				cacheItemData: Extendable list will ask itemData between minIdx and maxIdx.
 *				    Developers can implement this function for preparing data.
 *				    Optional.
 *
 *Examples:
 *
 *		<script id="tmp-3-1-1" type="text/x-jquery-tmpl">
 *			<li class="ui-li-3-1-1"><span class="ui-li-text-main">${NAME}</span></li>
 *		</script>
 *
 *		<script id="tmp_load_more" type="text/x-jquery-tmpl"> 
 *			<li class="ui-li-3-1-1" style="text-align:center; margin:0 auto">
 *				<div data-role="button">Load ${NUM_MORE_ITEMS} more items</div>
 *			</li>
 *		</script>
 *	
 *		<ul id = "extendable_list_main" data-role="extendablelist" data-extenditems="50" data-template="tmp-3-1-1">
 *		</ul>
 *
 */

/**
	@class Extendablelist
	In the Web environment, it is challenging to display a large amount of data in a list, such as displaying a contact list of over 1000 list items. It takes time to display the entire list in HTML and the DOM manipulation is complex.
	The extendable list widget is used to display a list of unlimited data elements on the screen for better performance. The list is extended if you click the button at the bottom of the list to load more data elements. Extendable lists are based on the jQuery.template plugin as described in the jQuery documentation for jQuery.template plugin.<br/>
	To add a extendable list widget to the application, use the following code:

			<script id="tmp-3-1-1" type="text/x-jquery-tmpl">
				<li class="ui-li-3-1-1"><span class="ui-li-text-main">${NAME}</span></li>
			</script>
			<script id="tmp_load_more" type="text/x-jquery-tmpl">
				<li class="ui-li-3-1-1" style="text-align:center; margin:0 auto">
				<div data-role="button">Load ${NUM_MORE_ITEMS} more items</div>
				</li>
			</script>
			<ul id="extendable_list_main" data-role="extendablelist" data-extenditems="50" data-template="tmp-3-1-1">
			</ul>
*/
/**
	@property {String} data-role
	Creates the extendable list view. The value must be set to extendablelist. Only the &lt;ul&gt; element, which a id attribute defined, supports this option. Also, the elLoadSuccess class attribute must be defined in the &lt;ul&gt; element to ensure that loading data from the database is complete.
*/
/**
	@property {String} data-template
	Specifies the jQuery.template element ID. The jQuery.template must be defined. The template style can use rem units to support scalability. For using the button at the bottom of the list to load more data elements, there must be list view template with the button. The attribute ID must be tmp_load_more.
*/
/**
	@property {Integer} data-extenditems
	Defines the number of data elements to be extended at a time.
*/
( function ( $, undefined ) {

	//Keeps track of the number of lists per page UID
	//This allows support for multiple nested list in the same page
	//https://github.com/jquery/jquery-mobile/issues/1617
	var listCountPerPage = {};

	$.widget( "tizen.extendablelist", $.mobile.widget, {
		options: {
			theme: "s",
			countTheme: "c",
			headerTheme: "b",
			dividerTheme: "b",
			splitIcon: "arrow-r",
			splitTheme: "b",
			inset: false,
			id:	"",						/* Extendable list UL elemet's ID */
			extenditems: 50,			/* Number of append items */
			childSelector: " li",		/* To support swipe list */
			dbtable: "",
			template : "",				/* Template for each list item */
			loadmore : "tmp_load_more",	/* Template for "Load more" message */
			scrollview: false,
			initSelector: ":jqmData(role='extendablelist')"
		},

		_stylerMouseUp: function () {
			$( this ).addClass( "ui-btn-up-s" );
			$( this ).removeClass( "ui-btn-down-s" );
		},

		_stylerMouseDown: function () {
			$( this ).addClass( "ui-btn-down-s" );
			$( this ).removeClass( "ui-btn-up-s" );
		},

		_stylerMouseOver: function () {
			$( this ).toggleClass( "ui-btn-hover-s" );
		},

		_stylerMouseOut: function () {
			$( this ).toggleClass( "ui-btn-hover-s" );
			$( this ).addClass( "ui-btn-up-s" );
			$( this ).removeClass( "ui-btn-down-s" );
		},

		_pushData: function ( template ) {
			var o = this.options,
				t = this,
				i = 0,
				myTemplate = $( "#" + template ),
				loadMoreItems = ( o.extenditems > t._numItemData - t._lastIndex ? t._numItemData - t.lastIndex : o.extenditems ),
				htmlData;

			for (i = 0; i < loadMoreItems; i++ ) {
				htmlData = myTemplate.tmpl( t._itemData( i ) );
				$( o.id ).append( $( htmlData ).attr( 'id', 'li_' + i ) );

				/* Add style */
				$( o.id + ">" + o.childSelector )
					.addClass( "ui-btn-up-s" )
					.bind( "mouseup", t._stylerMouseUp )
					.bind( "mousedown", t._stylerMouseDown )
					.bind( "mouseover", t._stylerMouseOver )
					.bind( "mouseout", t._stylerMouseOut );

				t._lastIndex += 1;
			}

			/* After push data, re-style extendable list widget */
			$( o.id ).trigger( "create" );
		},

		_loadmore: function ( event ) {
			var t = event.data,	// <li> element
				o = t.options,
				i = 0,
				myTemplate = $( "#" + o.template ),
				loadMoreItems = ( o.extenditems > t._numItemData - t._lastIndex ? t._numItemData - t._lastIndex : o.extenditems ),
				htmlData,
				more_items_to_load,
				num_next_load_items;

			/* Remove load more message */
			$( "#load_more_message" ).remove();

			/* Append More Items */
			for ( i = 0; i < loadMoreItems; i++ ) {
				htmlData = myTemplate.tmpl( t._itemData( t._lastIndex ) );
				$( o.id ).append( $( htmlData ).attr( 'id', 'li_' + t._lastIndex ) );
				t._lastIndex += 1;
			}

			/* Append "Load more" message on the last of list */
			if ( t._numItemData > t._lastIndex ) {
				myTemplate = $( "#" + o.loadmore );
				more_items_to_load = t._numItemData - t._lastIndex;
				num_next_load_items = ( o.extenditems <= more_items_to_load ) ? o.extenditems : more_items_to_load;
				htmlData = myTemplate.tmpl( { NUM_MORE_ITEMS : num_next_load_items } );
				// Button minimum height(37px)
				$( o.id ).append( $( htmlData ).attr( 'id', "load_more_message" ).css( 'min-height' , "37px") );
			}

			$( o.id ).trigger( "create" );
			$( o.id ).extendablelist( "refresh" );
		},

		recreate: function ( newArray ) {
			this._create( {
				itemData: function ( idx ) { return newArray[ idx ]; },
				numItemData: newArray.length
			} );
		},

		_initList: function (args ) {
			var t = this,
				o = this.options,
				myTemplate,
				more_items_to_load,
				num_next_load_items,
				htmlData;

			/* Make Gen list by template */
			if ( t._lastIndex <= 0 ) {
				t._pushData( o.template );

				/* Append "Load more" message on the last of list */
				if ( t._numItemData > t._lastIndex ) {
					myTemplate = $( "#" + o.loadmore );
					more_items_to_load = t._numItemData - t._lastIndex;
					num_next_load_items = ( o.extenditems <= more_items_to_load) ? o.extenditems : more_items_to_load;
					htmlData = myTemplate.tmpl( { NUM_MORE_ITEMS : num_next_load_items } );
					// Button minimum height(37px)
					$( o.id ).append( $( htmlData ).attr( 'id', "load_more_message" ).css( 'min-height' , "37px") );

					$( "#load_more_message" ).live( "click", t, t._loadmore );
				} else {
					/* No more items to load */
					$( "#load_more_message" ).die();
					$( "#load_more_message" ).remove();
				}
			}

			if ( o.childSelector == " ul" ) {
				$( o.id + " ul" ).swipelist();
			}

			$( o.id ).trigger( "create" );

			t.refresh( true );
		},

		create: function () {
			var o = this.options;

			/* external API for AJAX callback */
			this._create.apply( this, arguments );
		},

		_create: function ( args ) {
			var t = this,
				o = this.options,
				$el = this.element,
				dbtable_name;


			t.destroy();

			$.extend(this, {
				_itemData: function ( idx ) { return null; },
				_numItemData: 0,
				_cacheItemData: function ( minIdx, maxIdx ) { },
				_lastIndex: 0
			});


			// create listview markup
			t.element.addClass( function ( i, orig ) {
				return orig + " ui-listview ui-extendable-list-container" + ( t.options.inset ? " ui-listview-inset ui-corner-all ui-shadow " : "" );
			});

			o.id = "#" + $el.attr( "id" );

			if ( $el.data( "extenditems" ) ) {
				o.extenditems = parseInt( $el.data( "extenditems" ), 10 );
			}

			$( o.id ).bind( "pagehide", function (e) {
				$( o.id ).empty();
			});

			/* Scroll view */
			if ( $( ".ui-scrollview-clip" ).size() > 0) {
				o.scrollview = true;
			} else {
				o.scrollview = false;
			}

			if ( args ) {
				if ( !t._loadData( args ) ) {
					return;
				}
			} else {
				// Legacy support: dbtable
				console.warn("WARNING: The data interface of extendable list is changed. \nOld data interface(data-dbtable) is still supported, but will be removed in next version. \nPlease fix your code soon!");

				if ( $( o.id ).hasClass( "elLoadSuccess" ) ) {
					dbtable_name = $el.jqmData('dbtable');
					o.dbtable = window[ dbtable_name ];
					if ( !(o.dbtable) ) {
						o.dbtable = { };
					}
					t._itemData = function ( idx ) {
						return o.dbtable[ idx ];
					};
					t._numItemData = o.dbtable.length;

				} else {
					console.warn("No elLoadSuccess class");
					return;
				}
			}

			if ( $el.data( "template" ) ) {
				o.template = $el.data( "template" );

				/* to support swipe list, <li> or <ul> can be main node of extendable list. */
				if ( $el.data( "swipelist" ) == true ) {
					o.childSelector = " ul";
				} else {
					o.shildSelector = " li";
				}
			}
			t._initList( args );
		},

		_loadData : function ( args ) {
			var self = this;

			if ( args.itemData && typeof args.itemData == 'function'  ) {
				self._itemData = args.itemData;
			} else {
				return false;
			}
			if ( args.numItemData ) {
				if ( typeof args.numItemData == 'function' ) {
					self._numItemData = args.numItemData( );
				} else if ( typeof args.numItemData == 'number' ) {
					self._numItemData = args.numItemData;
				} else {
					return false;
				}
			} else {
				return false;
			}
			return true;
		},


		destroy : function () {
			var o = this.options,
				eOTAL_ITEMS = 0,
				last_index = 0;

			$( o.id ).empty();

			$( "#load_more_message" ).die();
		},

		_itemApply: function ( $list, item ) {
			var $countli = item.find( ".ui-li-count" );

			if ( $countli.length ) {
				item.addClass( "ui-li-has-count" );
			}

			$countli.addClass( "ui-btn-up-" + ( $list.jqmData( "counttheme" ) || this.options.countTheme ) + " ui-btn-corner-all" );

			// TODO class has to be defined in markup
			item.find( "h1, h2, h3, h4, h5, h6" ).addClass( "ui-li-heading" ).end()
				.find( "p, dl" ).addClass( "ui-li-desc" ).end()
				.find( ">img:eq(0), .ui-link-inherit>img:eq(0)" ).addClass( "ui-li-thumb" ).each(function () {
					item.addClass( $( this ).is( ".ui-li-icon" ) ? "ui-li-has-icon" : "ui-li-has-thumb" );
				}).end()
				.find( ".ui-li-aside" ).each(function () {
					var $this = $( this );
					$this.prependTo( $this.parent() ); //shift aside to front for css float
				});
		},

		_removeCorners: function ( li, which ) {
			var top = "ui-corner-top ui-corner-tr ui-corner-tl",
				bot = "ui-corner-bottom ui-corner-br ui-corner-bl";

			li = li.add( li.find( ".ui-btn-inner, .ui-li-link-alt, .ui-li-thumb" ) );

			if ( which === "top" ) {
				li.removeClass( top );
			} else if ( which === "bottom" ) {
				li.removeClass( bot );
			} else {
				li.removeClass( top + " " + bot );
			}
		},

		_refreshCorners: function ( create ) {
			var $li,
				$visibleli,
				$topli,
				$bottomli;

			if ( this.options.inset ) {
				$li = this.element.children( "li" );
				// at create time the li are not visible yet so we need to rely on .ui-screen-hidden
				$visibleli = create ? $li.not( ".ui-screen-hidden" ) : $li.filter( ":visible" );

				this._removeCorners( $li );

				// Select the first visible li element
				$topli = $visibleli.first()
					.addClass( "ui-corner-top" );

				$topli.add( $topli.find( ".ui-btn-inner" ) )
					.find( ".ui-li-link-alt" )
						.addClass( "ui-corner-tr" )
					.end()
					.find( ".ui-li-thumb" )
						.not( ".ui-li-icon" )
						.addClass( "ui-corner-tl" );

				// Select the last visible li element
				$bottomli = $visibleli.last()
					.addClass( "ui-corner-bottom" );

				$bottomli.add( $bottomli.find( ".ui-btn-inner" ) )
					.find( ".ui-li-link-alt" )
						.addClass( "ui-corner-br" )
					.end()
					.find( ".ui-li-thumb" )
						.not( ".ui-li-icon" )
						.addClass( "ui-corner-bl" );
			}
			this.element.trigger( "updatelayout" );
		},

		refresh: function ( create ) {
			this.parentPage = this.element.closest( ".ui-page" );
			this._createSubPages();

			var o = this.options,
				$list = this.element,
				self = this,
				dividertheme = $list.jqmData( "dividertheme" ) || o.dividerTheme,
				listsplittheme = $list.jqmData( "splittheme" ),
				listspliticon = $list.jqmData( "spliticon" ),
				li = $list.children( "li" ),
				counter = $.support.cssPseudoElement || !$.nodeName( $list[ 0 ], "ol" ) ? 0 : 1,
				item,
				itemClass,
				itemTheme,
				a,
				last,
				splittheme,
				countParent,
				icon,
				pos,
				numli;

			if ( counter ) {
				$list.find( ".ui-li-dec" ).remove();
			}

			for ( pos = 0, numli = li.length; pos < numli; pos++ ) {
				item = li.eq( pos );
				itemClass = "ui-li";

				// If we're creating the element, we update it regardless
				if ( create || !item.hasClass( "ui-li" ) ) {
					itemTheme = item.jqmData( "theme" ) || o.theme;
					a = item.children( "a" );

					if ( a.length ) {
						icon = item.jqmData( "icon" );

						item.buttonMarkup({
							wrapperEls: "div",
							shadow: false,
							corners: false,
							iconpos: "right",
							/* icon: a.length > 1 || icon === false ? false : icon || "arrow-r",*/
							icon: false,	/* Remove unnecessary arrow icon */
							theme: itemTheme
						});

						if ( ( icon != false ) && ( a.length == 1 ) ) {
							item.addClass( "ui-li-has-arrow" );
						}

						a.first().addClass( "ui-link-inherit" );

						if ( a.length > 1 ) {
							itemClass += " ui-li-has-alt";

							last = a.last();
							splittheme = listsplittheme || last.jqmData( "theme" ) || o.splitTheme;

							last.appendTo(item)
								.attr( "title", last.getEncodedText() )
								.addClass( "ui-li-link-alt" )
								.empty()
								.buttonMarkup({
									shadow: false,
									corners: false,
									theme: itemTheme,
									icon: false,
									iconpos: false
								})
								.find( ".ui-btn-inner" )
								.append(
									$( "<span />" ).buttonMarkup( {
										shadow : true,
										corners : true,
										theme : splittheme,
										iconpos : "notext",
										icon : listspliticon || last.jqmData( "icon" ) || o.splitIcon
									})
								);
						}
					} else if ( item.jqmData( "role" ) === "list-divider" ) {

						itemClass += " ui-li-divider ui-btn ui-bar-" + dividertheme;
						item.attr( "role", "heading" );

						//reset counter when a divider heading is encountered
						if ( counter ) {
							counter = 1;
						}

					} else {
						itemClass += " ui-li-static ui-body-" + itemTheme;
					}
				}

				if ( counter && itemClass.indexOf( "ui-li-divider" ) < 0 ) {
					countParent = item.is( ".ui-li-static:first" ) ? item : item.find( ".ui-link-inherit" );

					countParent.addClass( "ui-li-jsnumbering" )
						.prepend( "<span class='ui-li-dec'>" + (counter++) + ". </span>" );
				}

				item.add( item.children( ".ui-btn-inner" ) ).addClass( itemClass );

				self._itemApply( $list, item );
			}

			this._refreshCorners( create );
		},

		//create a string for ID/subpage url creation
		_idStringEscape: function ( str ) {
			return str.replace(/\W/g , "-");

		},

		_createSubPages: function () {
			var parentList = this.element,
				parentPage = parentList.closest( ".ui-page" ),
				parentUrl = parentPage.jqmData( "url" ),
				parentId = parentUrl || parentPage[ 0 ][ $.expando ],
				parentListId = parentList.attr( "id" ),
				o = this.options,
				dns = "data-" + $.mobile.ns,
				self = this,
				persistentFooterID = parentPage.find( ":jqmData(role='footer')" ).jqmData( "id" ),
				hasSubPages,
				newRemove;

			if ( typeof listCountPerPage[ parentId ] === "undefined" ) {
				listCountPerPage[ parentId ] = -1;
			}

			parentListId = parentListId || ++listCountPerPage[ parentId ];

			$( parentList.find( "li>ul, li>ol" ).toArray().reverse() ).each(function ( i ) {
				var self = this,
					list = $( this ),
					listId = list.attr( "id" ) || parentListId + "-" + i,
					parent = list.parent(),
					nodeEls,
					title = nodeEls.first().getEncodedText(),//url limits to first 30 chars of text
					id = ( parentUrl || "" ) + "&" + $.mobile.subPageUrlKey + "=" + listId,
					theme = list.jqmData( "theme" ) || o.theme,
					countTheme = list.jqmData( "counttheme" ) || parentList.jqmData( "counttheme" ) || o.countTheme,
					newPage,
					anchor;

				nodeEls = $( list.prevAll().toArray().reverse() );
				nodeEls = nodeEls.length ? nodeEls : $( "<span>" + $.trim(parent.contents()[ 0 ].nodeValue) + "</span>" );

				//define hasSubPages for use in later removal
				hasSubPages = true;

				newPage = list.detach()
							.wrap( "<div " + dns + "role='page' " +	dns + "url='" + id + "' " + dns + "theme='" + theme + "' " + dns + "count-theme='" + countTheme + "'><div " + dns + "role='content'></div></div>" )
							.parent()
								.before( "<div " + dns + "role='header' " + dns + "theme='" + o.headerTheme + "'><div class='ui-title'>" + title + "</div></div>" )
								.after( persistentFooterID ? $( "<div " + dns + "role='footer' " + dns + "id='" + persistentFooterID + "'>" ) : "" )
								.parent()
									.appendTo( $.mobile.pageContainer );

				newPage.page();

				anchor = parent.find('a:first');

				if ( !anchor.length ) {
					anchor = $( "<a/>" ).html( nodeEls || title ).prependTo( parent.empty() );
				}

				anchor.attr( "href", "#" + id );

			}).extendablelist();

			// on pagehide, remove any nested pages along with the parent page, as long as they aren't active
			// and aren't embedded
			if ( hasSubPages &&
					parentPage.is( ":jqmData(external-page='true')" ) &&
					parentPage.data( "page" ).options.domCache === false ) {

				newRemove = function ( e, ui ) {
					var nextPage = ui.nextPage, npURL;

					if ( ui.nextPage ) {
						npURL = nextPage.jqmData( "url" );
						if ( npURL.indexOf( parentUrl + "&" + $.mobile.subPageUrlKey ) !== 0 ) {
							self.childPages().remove();
							parentPage.remove();
						}
					}
				};

				// unbind the original page remove and replace with our specialized version
				parentPage
					.unbind( "pagehide.remove" )
					.bind( "pagehide.remove", newRemove);
			}
		},

		// TODO sort out a better way to track sub pages of the extendable listview this is brittle
		childPages: function () {
			var parentUrl = this.parentPage.jqmData( "url" );

			return $( ":jqmData(url^='" +  parentUrl + "&" + $.mobile.subPageUrlKey + "')" );
		}
	});

	//auto self-init widgets
	$( document ).bind( "pagecreate create", function ( e ) {
		$( $.tizen.extendablelist.prototype.options.initSelector, e.target ).extendablelist();
	});

}( jQuery ));



ensureNS("jQuery.mobile.tizen.clrlib");

jQuery.extend( jQuery.mobile.tizen.clrlib, 
{
    nearestInt: function(val) { 
        var theFloor = Math.floor(val);

        return (((val - theFloor) > 0.5) ? (theFloor + 1) : theFloor);
    },

    /*
     * Converts html color string to rgb array.
     *
     * Input: string clr_str, where
     * clr_str is of the form "#aabbcc"
     *
     * Returns: [ r, g, b ], where
     * r is in [0, 1]
     * g is in [0, 1]
     * b is in [0, 1]
     */
    HTMLToRGB: function(clr_str) {
        clr_str = (('#' == clr_str.charAt(0)) ? clr_str.substring(1) : clr_str);

        return ([
            clr_str.substring(0, 2),
            clr_str.substring(2, 4),
            clr_str.substring(4, 6)
            ].map(function(val) {
                return parseInt(val, 16) / 255.0;
            }));
    },

    /*
     * Converts rgb array to html color string.
     *
     * Input: [ r, g, b ], where
     * r is in [0, 1]
     * g is in [0, 1]
     * b is in [0, 1]
     *
     * Returns: string of the form "#aabbcc"
     */
    RGBToHTML: function(rgb) {
        return ("#" + 
            rgb.map(function(val) {
                      var ret = val * 255,
                          theFloor = Math.floor(ret);

                      ret = ((ret - theFloor > 0.5) ? (theFloor + 1) : theFloor);
                      ret = (((ret < 16) ? "0" : "") + (ret & 0xff).toString(16));
                      return ret;
                  })
               .join(""));
    },

    /*
     * Converts hsl to rgb.
     *
     * From http://130.113.54.154/~monger/hsl-rgb.html
     *
     * Input: [ h, s, l ], where
     * h is in [0, 360]
     * s is in [0,   1]
     * l is in [0,   1]
     *
     * Returns: [ r, g, b ], where
     * r is in [0, 1]
     * g is in [0, 1]
     * b is in [0, 1]
     */
    HSLToRGB: function(hsl) {
        var h = hsl[0] / 360.0, s = hsl[1], l = hsl[2];

        if (0 === s)
            return [ l, l, l ];

        var temp2 = ((l < 0.5)
                ? l * (1.0 + s)
                : l + s - l * s),
            temp1 = 2.0 * l - temp2,
            temp3 = {
                r: h + 1.0 / 3.0,
                g: h,
                b: h - 1.0 / 3.0
            };

        temp3.r = ((temp3.r < 0) ? (temp3.r + 1.0) : ((temp3.r > 1) ? (temp3.r - 1.0) : temp3.r));
        temp3.g = ((temp3.g < 0) ? (temp3.g + 1.0) : ((temp3.g > 1) ? (temp3.g - 1.0) : temp3.g));
        temp3.b = ((temp3.b < 0) ? (temp3.b + 1.0) : ((temp3.b > 1) ? (temp3.b - 1.0) : temp3.b));

        ret = [
            (((6.0 * temp3.r) < 1) ? (temp1 + (temp2 - temp1) * 6.0 * temp3.r) :
            (((2.0 * temp3.r) < 1) ? temp2 :
            (((3.0 * temp3.r) < 2) ? (temp1 + (temp2 - temp1) * ((2.0 / 3.0) - temp3.r) * 6.0) :
             temp1))),
            (((6.0 * temp3.g) < 1) ? (temp1 + (temp2 - temp1) * 6.0 * temp3.g) :
            (((2.0 * temp3.g) < 1) ? temp2 :
            (((3.0 * temp3.g) < 2) ? (temp1 + (temp2 - temp1) * ((2.0 / 3.0) - temp3.g) * 6.0) :
             temp1))),
            (((6.0 * temp3.b) < 1) ? (temp1 + (temp2 - temp1) * 6.0 * temp3.b) :
            (((2.0 * temp3.b) < 1) ? temp2 :
            (((3.0 * temp3.b) < 2) ? (temp1 + (temp2 - temp1) * ((2.0 / 3.0) - temp3.b) * 6.0) :
             temp1)))]; 

        return ret;
    },

    /*
     * Converts hsv to rgb.
     *
     * Input: [ h, s, v ], where
     * h is in [0, 360]
     * s is in [0,   1]
     * v is in [0,   1]
     *
     * Returns: [ r, g, b ], where
     * r is in [0, 1]
     * g is in [0, 1]
     * b is in [0, 1]
     */
    HSVToRGB: function(hsv) {
        return $.mobile.tizen.clrlib.HSLToRGB($.mobile.tizen.clrlib.HSVToHSL(hsv));
    },

    /*
     * Converts rgb to hsv.
     *
     * from http://coecsl.ece.illinois.edu/ge423/spring05/group8/FinalProject/HSV_writeup.pdf
     *
     * Input: [ r, g, b ], where
     * r is in [0,   1]
     * g is in [0,   1]
     * b is in [0,   1]
     *
     * Returns: [ h, s, v ], where
     * h is in [0, 360]
     * s is in [0,   1]
     * v is in [0,   1]
     */
    RGBToHSV: function(rgb) {
        var min, max, delta, h, s, v, r = rgb[0], g = rgb[1], b = rgb[2];

        min = Math.min(r, Math.min(g, b));
        max = Math.max(r, Math.max(g, b));
        delta = max - min;

        h = 0;
        s = 0;
        v = max;

        if (delta > 0.00001) {
            s = delta / max;

            if (r === max)
                h = (g - b) / delta ;
            else
            if (g === max)
                h = 2 + (b - r) / delta ;
            else
                h = 4 + (r - g) / delta ;

            h *= 60 ;

            if (h < 0)
                h += 360 ;
        }

        return [h, s, v];
    },

    /*
     * Converts hsv to hsl.
     *
     * Input: [ h, s, v ], where
     * h is in [0, 360]
     * s is in [0,   1]
     * v is in [0,   1]
     *
     * Returns: [ h, s, l ], where
     * h is in [0, 360]
     * s is in [0,   1]
     * l is in [0,   1]
     */
    HSVToHSL: function(hsv) {
        var max = hsv[2],
            delta = hsv[1] * max,
            min = max - delta,
            sum = max + min,
            half_sum = sum / 2,
            s_divisor = ((half_sum < 0.5) ? sum : (2 - max - min));

        return [ hsv[0], ((0 == s_divisor) ? 0 : (delta / s_divisor)), half_sum ];
    },

    /*
     * Converts rgb to hsl
     *
     * Input: [ r, g, b ], where
     * r is in [0,   1]
     * g is in [0,   1]
     * b is in [0,   1]
     *
     * Returns: [ h, s, l ], where
     * h is in [0, 360]
     * s is in [0,   1]
     * l is in [0,   1]
     */
    RGBToHSL: function(rgb) {
        return $.mobile.tizen.clrlib.HSVToHSL($.mobile.tizen.clrlib.RGBToHSV(rgb));
    }
});



/*
 * set TIZEN specific configures
 */

( function( $, window, undefined ) {

	/* set default transition */
	$.mobile.defaultPageTransition = "none";

	/* depth transition */
	$.mobile.transitionHandlers.depth = $.mobile.transitionHandlers.simultaneous;
	$.mobile.transitionFallbacks.depth = "fade";

	/* Button data-corners default value */
	$.fn.buttonMarkup.defaults.corners = false;

	/* button hover delay */
	$.mobile.buttonMarkup.hoverDelay = 0;

})( jQuery, this );




/* ***************************************************************************
	Flora License

	Version 1.1, April, 2013

	http://floralicense.org/license/

	TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

	1. Definitions.

	"License" shall mean the terms and conditions for use, reproduction,
	and distribution as defined by Sections 1 through 9 of this document.

	"Licensor" shall mean the copyright owner or entity authorized by
	the copyright owner that is granting the License.

	"Legal Entity" shall mean the union of the acting entity and
	all other entities that control, are controlled by, or are
	under common control with that entity. For the purposes of
	this definition, "control" means (i) the power, direct or indirect,
	to cause the direction or management of such entity,
	whether by contract or otherwise, or (ii) ownership of fifty percent (50%)
	or more of the outstanding shares, or (iii) beneficial ownership of
	such entity.

	"You" (or "Your") shall mean an individual or Legal Entity
	exercising permissions granted by this License.

	"Source" form shall mean the preferred form for making modifications,
	including but not limited to software source code, documentation source,
	and configuration files.

	"Object" form shall mean any form resulting from mechanical
	transformation or translation of a Source form, including but
	not limited to compiled object code, generated documentation,
	and conversions to other media types.

	"Work" shall mean the work of authorship, whether in Source or Object form,
	made available under the License, as indicated by a copyright notice
	that is included in or attached to the work (an example is provided
	in the Appendix below).

	"Derivative Works" shall mean any work, whether in Source or Object form,
	that is based on (or derived from) the Work and for which the editorial
	revisions, annotations, elaborations, or other modifications represent,
	as a whole, an original work of authorship. For the purposes of this License,
	Derivative Works shall not include works that remain separable from,
	or merely link (or bind by name) to the interfaces of, the Work and
	Derivative Works thereof.

	"Contribution" shall mean any work of authorship, including the original
	version of the Work and any modifications or additions to that Work or
	Derivative Works thereof, that is intentionally submitted to Licensor
	for inclusion in the Work by the copyright owner or by an individual or
	Legal Entity authorized to submit on behalf of the copyright owner.
	For the purposes of this definition, "submitted" means any form of
	electronic, verbal, or written communication sent to the Licensor or
	its representatives, including but not limited to communication on
	electronic mailing lists, source code control systems, and issue
	tracking systems that are managed by, or on behalf of, the Licensor
	for the purpose of discussing and improving the Work, but excluding
	communication that is conspicuously marked or otherwise designated
	in writing by the copyright owner as "Not a Contribution."

	"Contributor" shall mean Licensor and any individual or Legal Entity
	on behalf of whom a Contribution has been received by Licensor and
	subsequently incorporated within the Work.

	"Tizen Certified Platform" shall mean a software platform that complies
	with the standards set forth in the Tizen Compliance Specification
	and passes the Tizen Compliance Tests as defined from time to time
	by the Tizen Technical Steering Group and certified by the Tizen
	Association or its designated agent.

	2. Grant of Copyright License.  Subject to the terms and conditions of
	this License, each Contributor hereby grants to You a perpetual,
	worldwide, non-exclusive, no-charge, royalty-free, irrevocable
	copyright license to reproduce, prepare Derivative Works of,
	publicly display, publicly perform, sublicense, and distribute the
	Work and such Derivative Works in Source or Object form.

	3. Grant of Patent License.  Subject to the terms and conditions of
	this License, each Contributor hereby grants to You a perpetual,
	worldwide, non-exclusive, no-charge, royalty-free, irrevocable
	(except as stated in this section) patent license to make, have made,
	use, offer to sell, sell, import, and otherwise transfer the Work
	solely as incorporated into a Tizen Certified Platform, where such
	license applies only to those patent claims licensable by such
	Contributor that are necessarily infringed by their Contribution(s)
	alone or by combination of their Contribution(s) with the Work solely
	as incorporated into a Tizen Certified Platform to which such
	Contribution(s) was submitted. If You institute patent litigation
	against any entity (including a cross-claim or counterclaim
	in a lawsuit) alleging that the Work or a Contribution incorporated
	within the Work constitutes direct or contributory patent infringement,
	then any patent licenses granted to You under this License for that
	Work shall terminate as of the date such litigation is filed.

	4. Redistribution.  You may reproduce and distribute copies of the
	Work or Derivative Works thereof pursuant to the copyright license
	above, in any medium, with or without modifications, and in Source or
	Object form, provided that You meet the following conditions:

	  1. You must give any other recipients of the Work or Derivative Works
		 a copy of this License; and
	  2. You must cause any modified files to carry prominent notices stating
		 that You changed the files; and
	  3. You must retain, in the Source form of any Derivative Works that
		 You distribute, all copyright, patent, trademark, and attribution
		 notices from the Source form of the Work, excluding those notices
		 that do not pertain to any part of the Derivative Works; and
	  4. If the Work includes a "NOTICE" text file as part of its distribution,
		 then any Derivative Works that You distribute must include a readable
		 copy of the attribution notices contained within such NOTICE file,
		 excluding those notices that do not pertain to any part of
		 the Derivative Works, in at least one of the following places:
		 within a NOTICE text file distributed as part of the Derivative Works;
		 within the Source form or documentation, if provided along with the
		 Derivative Works; or, within a display generated by the Derivative Works,
		 if and wherever such third-party notices normally appear.
		 The contents of the NOTICE file are for informational purposes only
		 and do not modify the License.

	You may add Your own attribution notices within Derivative Works
	that You distribute, alongside or as an addendum to the NOTICE text
	from the Work, provided that such additional attribution notices
	cannot be construed as modifying the License. You may add Your own
	copyright statement to Your modifications and may provide additional or
	different license terms and conditions for use, reproduction, or
	distribution of Your modifications, or for any such Derivative Works
	as a whole, provided Your use, reproduction, and distribution of
	the Work otherwise complies with the conditions stated in this License.

	5. Submission of Contributions. Unless You explicitly state otherwise,
	any Contribution intentionally submitted for inclusion in the Work
	by You to the Licensor shall be under the terms and conditions of
	this License, without any additional terms or conditions.
	Notwithstanding the above, nothing herein shall supersede or modify
	the terms of any separate license agreement you may have executed
	with Licensor regarding such Contributions.

	6. Trademarks.  This License does not grant permission to use the trade
	names, trademarks, service marks, or product names of the Licensor,
	except as required for reasonable and customary use in describing the
	origin of the Work and reproducing the content of the NOTICE file.

	7. Disclaimer of Warranty. Unless required by applicable law or
	agreed to in writing, Licensor provides the Work (and each
	Contributor provides its Contributions) on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
	implied, including, without limitation, any warranties or conditions
	of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
	PARTICULAR PURPOSE. You are solely responsible for determining the
	appropriateness of using or redistributing the Work and assume any
	risks associated with Your exercise of permissions under this License.

	8. Limitation of Liability. In no event and under no legal theory,
	whether in tort (including negligence), contract, or otherwise,
	unless required by applicable law (such as deliberate and grossly
	negligent acts) or agreed to in writing, shall any Contributor be
	liable to You for damages, including any direct, indirect, special,
	incidental, or consequential damages of any character arising as a
	result of this License or out of the use or inability to use the
	Work (including but not limited to damages for loss of goodwill,
	work stoppage, computer failure or malfunction, or any and all
	other commercial damages or losses), even if such Contributor
	has been advised of the possibility of such damages.

	9. Accepting Warranty or Additional Liability. While redistributing
	the Work or Derivative Works thereof, You may choose to offer,
	and charge a fee for, acceptance of support, warranty, indemnity,
	or other liability obligations and/or rights consistent with this
	License. However, in accepting such obligations, You may act only
	on Your own behalf and on Your sole responsibility, not on behalf
	of any other Contributor, and only if You agree to indemnify,
	defend, and hold each Contributor harmless for any liability
	incurred by, or claims asserted against, such Contributor by reason
	of your accepting any such warranty or additional liability.

	END OF TERMS AND CONDITIONS

	APPENDIX: How to apply the Flora License to your work

	To apply the Flora License to your work, attach the following
	boilerplate notice, with the fields enclosed by brackets "[]"
	replaced with your own identifying information. (Don't include
	the brackets!) The text should be enclosed in the appropriate
	comment syntax for the file format. We also recommend that a
	file or class name and description of purpose be included on the
	same "printed page" as the copyright notice for easier
	identification within third-party archives.

	   Copyright [yyyy] [name of copyright owner]

	   Licensed under the Flora License, Version 1.1 (the "License");
	   you may not use this file except in compliance with the License.
	   You may obtain a copy of the License at

		   http://floralicense.org/license/

	   Unless required by applicable law or agreed to in writing, software
	   distributed under the License is distributed on an "AS IS" BASIS,
	   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	   See the License for the specific language governing permissions and
	   limitations under the License.


 * Authors: Hyunsook Park <hyunsook.park@samsung.com>
 *			Wonseop Kim <wonseop.kim@samsung.com>
 */

/**
 *	The gallery3d widget displays images along a curved path on a 3-dimensional coordinate system.
 *	To improve performance, the size of image(s) displayed on the screen should be a square(under
 *	128X128 pixel) as possible. But if a user can't resize the images, this widget supports an image
 *	resizing feature and he/she can use it with "data-thumbnail-cache" option. ("data-thumbnail-cache"
 *	option resizes the gallery images under 128x128 pixels and stores the images on a local storage.
 *	So when a gallery3D widget is re-launched, the widget reuse the storage and a user can improve
 *	launching time. A browser or web runtime engine should support "Web Storage" feature to use that
 *	option.)
 *
 *	HTML Attributes:
 *
 *		data-thumbnail-cache : Determines whether to cache and resize images.
 *
 *	APIs:
 *
 *		next ( void )
 *			: This method moves each image forward one by one.
 *		prev ( void )
 *			: This method moves each image backward one by one.
 *		select ( [number] )
 *			: When the "select" method is called with an argument, the method selects the image of given index.
 *			If the method is called with no argument, it will return the Javascript object having "src"
 *			attribute having the selected image's URL.
 *		add ( object or string [, number] )
 *			This method adds an image to Gallery3D widget.
 *			If the second argument isn't inputted, the image is added at the 0th position.
 *		remove ( [number] )
 *			: This method deletes an image from Gallery3d widget.
 *			The argument defines the index of the image to be deleted.
 *			If an argument isn't inputted, it removes current image.
 *		clearThumbnailCache ( void )
 *			: This method clears the cache data of all images when thumbnailCache option is set as 'true'.
 *		refresh ( void )
 *			: This method updates and redraws current widget.
 *		empty ( void )
 *			: This method removes all of images from Gallery3D widget.
 *		length ( void )
 *			: This method gets the number of images.
 *
 *	Events:
 *
 *		select : Triggered when an image is selected.
 *
 *	Examples:
 *
 *		<script>
 *			$( "#gallery3d" ).on( "gallery3dcreate", function () {
 *				$( "#gallery3d" ).gallery3d( "add", "01.jpg" );
 *			});
 *		</script>
 *		<div id="gallery3d" data-role="gallery3d"></div>
 */

/**
	@class Gallery3D
	The gallery3d widget displays images along a curved path on a 3-dimensional coordinate system.
	<br/><br/>To add an gallery3d widget to the application, use the following code:

		<script>
			$( "#gallery3d" ).on( "gallery3dcreate", function () {
				$( "#gallery3d" ).gallery3d( "add", "01.jpg" );
			});
		</script>
		<div id="gallery3d" data-role="gallery3d"></div>
*/
/**
	@property {Boolean} data-thumbnail-cache
	Determines whether to cache and resize images.
	To improve performance, the size of image(s) displayed on the screen should be a square (under 128X128 pixels).
	"data-thumbnail-cache" option resizes the gallery images under 128x128 pixels and stores the images on a local storage.
	So when a gallery3D widget is re-launched, the widget reuses the storage and the launching time can be improved.
	A browser or web runtime engine must support "Web Storage" feature to use this option.
*/
/**
	@event select
	Triggered when an image is selected.

		<script>
			$( "#gallery3d" ).on( "gallery3dcreate", function () {
				$( "#gallery3d" ).gallery3d( "add", { src: "1.jpg" } )
					.gallery3d( "add", { src: "2.jpg" } )
					.gallery3d( "add", { src: "3.jpg" } );
			}).on( "select", function ( event, data, index ) {
				// Handle the select event
				var urlOfImage = data.src, indexOfImage = index;
			});
		</script>
		<div id="gallery3d" data-role="gallery3d"></div>
*/
/**
	@method next
	This method moves each image forward one by one.

		<script>
			$( "#gallery3d" ).on( "gallery3dcreate", function () {
				$( "#gallery3d" ).gallery3d( "add", { src: "1.jpg" } )
					.gallery3d( "add", { src: "2.jpg" } )
					.gallery3d( "add", { src: "3.jpg" } )
					.gallery3d( "next" );
			});
		</script>
		<div id="gallery3d" data-role="gallery3d"></div>
*/
/**
	@method prev
	This method moves each image backward one by one.

		<script>
			$( "#gallery3d" ).on( "gallery3dcreate", function () {
				$( "#gallery3d" ).gallery3d( "add", { src: "1.jpg" } )
					.gallery3d( "add", { src: "2.jpg" } )
					.gallery3d( "add", { src: "3.jpg" } )
					.gallery3d( "prev" );
			});
		</script>
		<div id="gallery3d" data-role="gallery3d"></div>
*/
/**
	@method select
	When the "select" method is called with an argument, the method selects the image of given index.
	If the method is called with no argument, it will return the Javascript object having "src" attribute having the selected image's URL.

		<script>
			$( "#gallery3d" ).on( "gallery3dcreate", function () {
				$( "#gallery3d" ).gallery3d( "add", { src: "1.jpg" } )
					.gallery3d( "add", { src: "2.jpg" } )
					.gallery3d( "add", { src: "3.jpg" } );
				var selectedImage = $("#gallery3d"). gallery3d( "select" );
				// selectedImage = { src: "3.jpg" };
			});
		</script>
		<div id="gallery3d" data-role="gallery3d"></div>
*/
/**
	@method add
	This method adds an image to Gallery3D widget.
	The first argument is a Javascript object having a "src" attribute or a string of image's path.
	The second argument is an index of images.
	If second argument isn't inputted, the image is added at the 0th position.

		<script>
			$( "#gallery3d" ).on( "gallery3dcreate", function () {
				$( "#gallery3d" ).gallery3d( "add", { src: "1.jpg" } )
					.gallery3d( "add", "2.jpg", 1 );
			});
		</script>
		<div id="gallery3d" data-role="gallery3d"></div>
*/
/**
	@method remove
	This method deletes an image from Gallery3d widget.
	The argument defines the index of the image to be deleted.
	If an argument isn't inputted, it removes current image.

		<script>
			$( "#gallery3d" ).on( "gallery3dcreate", function () {
				$( "#gallery3d" ).gallery3d( "add", { src: "1.jpg" } )
					.gallery3d( "add", { src: "2.jpg" } )
					.gallery3d( "add", { src: "3.jpg" } );

				$( "#gallery3d" ).gallery3d( "remove" );
				$( "#gallery3d" ).gallery3d( "remove", 1 );
			});
		</script>
		<div id="gallery3d" data-role="gallery3d"></div>
*/
/**
	@method clearThumbnailCache
	This method clears the cache data of all images when thumbnailCache option is set as 'true'

		<script>
			$( "#gallery3d" ).on( "gallery3dcreate", function () {
				$( "#gallery3d" ).gallery3d( "add", { src: "1.jpg" } )
					.gallery3d( "add", { src: "2.jpg" } )
					.gallery3d( "add", { src: "3.jpg" } );

				$( "#gallery3d" ).gallery3d( "clearThumbnailCache" );
			});
		</script>
		<div id="gallery3d" data-role="gallery3d" data-thumbnail-cache="true"></div>
*/
/**
	@method refresh
	This method updates and redraws current widget.

		<script>
			$( "#gallery3d" ).on( "gallery3dcreate", function () {
				$( "#gallery3d" ).gallery3d( "add", { src: "1.jpg" } )
					.gallery3d( "add", { src: "2.jpg" } )
					.gallery3d( "add", { src: "3.jpg" } );

				$( "#gallery3d" ).gallery3d( "refresh" );
			});
		</script>
		<div id="gallery3d" data-role="gallery3d"></div>
*/
/**
	@method empty
	This method removes all of images from Gallery3D widget.

		<script>
			$( "#gallery3d" ).on( "gallery3dcreate", function () {
				$( "#gallery3d" ).gallery3d( "add", { src: "1.jpg" } )
					.gallery3d( "add", { src: "2.jpg" } )
					.gallery3d( "add", { src: "3.jpg" } );

				$( "#gallery3d" ).gallery3d( "empty" );
			});
		</script>
		<div id="gallery3d" data-role="gallery3d"></div>
*/
/**
	@method length
	This method gets the number of images.

		<script>
			$( "#gallery3d" ).on( "gallery3dcreate", function () {
				$( "#gallery3d" ).gallery3d( "add", { src: "1.jpg" } )
					.gallery3d( "add", { src: "2.jpg" } )
					.gallery3d( "add", { src: "3.jpg" } );

				var imagesLength = $( "#gallery3d" ).gallery3d( "length" );
				// imagesLength = 3;
			});
		</script>
		<div id="gallery3d" data-role="gallery3d"></div>
*/

( function ( $, document, window, undefined ) {
	function Node() {
		this.vertices = [
			-1.0, -1.0, 0.0,
			1.0, -1.0, 0.0,
			1.0,  1.0, 0.0,
			-1.0,  1.0, 0.0
		];
		this.textureCoords = [
			1.0, 0.0,
			0.0, 0.0,
			0.0, 1.0,
			1.0, 1.0
		];
		this.normalVectors = [
			0.0, 0.0, 1.0,
			0.0, 0.0, 1.0,
			0.0, 0.0, 1.0,
			0.0, 0.0, 1.0
		];
		this.texture = null;
		this.textureBuffer = null;
		this.textureBufferItemSize = 0;
		this.mashOrder = [];
		this.mvMatrix = null;
		this.level = -1;
		this.targetLevel = 0;
		this.drawable = false;
		this.image = null;
		this.imageID = 0;
	}

	var isPreInitailization  = false,
		glMatrix = {},
		VERTEX_SHADER,
		FRAGMENT_SHADER,
		GlArray32,
		GlArray16,
		preInitialize = function () {
			if ( isPreInitailization ) {
				return;
			}

			window.initGlMatrix( glMatrix );

			VERTEX_SHADER = [
				"attribute vec3 aVertexPosition;",
				"attribute vec2 aTextureCoord;",
				"attribute vec3 aVertexNormal;",
				"uniform mat4 uMoveMatrix;",
				"uniform mat4 uPerspectiveMatrix;",
				"uniform mat3 nNormalMatrix;",
				"uniform vec3 uAmbientColor;",
				"uniform vec3 uLightDirection;",
				"uniform vec3 uDirectionColor;",
				"uniform vec3 uLightDirection_first;",
				"uniform vec3 uLightDirection_second;",
				"varying vec2 vTextureCoord;",
				"varying vec3 vLightWeight;",
				"varying vec4 vFogWeight;",

				"void main(void) {",
				"	vec4 v_Position = uMoveMatrix * vec4(aVertexPosition, 1.0);",
				"	gl_Position = uPerspectiveMatrix * v_Position;",
				"	vTextureCoord = aTextureCoord;",
				"	float fog = 1.0 - ((gl_Position.z + 1.5) / 60.0);",
				"	vFogWeight = clamp( vec4( fog, fog, fog, 1.0), 0.6, 1.0);",
				"	vec3 transNormalVector = nNormalMatrix * aVertexNormal;",

				"	float vLightWeightFirst = 0.0;",
				"	float vLightWeightSecond = max( dot(transNormalVector, uLightDirection_second), 0.0 );",

				"	vLightWeight = uAmbientColor + uDirectionColor * vLightWeightSecond;",
				"}"
			].join( "\n" );

			FRAGMENT_SHADER = [
				"precision mediump float;",
				"varying vec2 vTextureCoord;",
				"varying vec3 vLightWeight;",
				"uniform sampler2D uSampler;",
				"varying vec4 vFogWeight;",

				"void main(void) {",
				"	vec4 TextureColor;",
				"	if ( vTextureCoord.s <= 0.01 || vTextureCoord.s >= 0.99 || vTextureCoord.t <= 0.01 || vTextureCoord.t >= 0.99 ) {",
				"		TextureColor = vec4(1.0, 1.0, 1.0, 0.5);",
				"	} else {",
				"		TextureColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));",
				"	}",
				"	TextureColor *= vFogWeight;",
				"	gl_FragColor = vec4(TextureColor.rgb * vLightWeight, TextureColor.a);",
				"}"
			].join( "\n" );

			GlArray32 = ( typeof window.Float32Array !== "undefined" ?
					window.Float32Array :
						( typeof window.WebGLFloatArray !== "undefined" ? window.WebGLFloatArray : Array ) );

			GlArray16 = ( typeof window.Uint16Array !== "undefined" ? window.Uint16Array : Array );

			isPreInitailization = true;
		},
		degreeToRadian = function ( degree ) {
			return degree * Math.PI / 180;
		},
		getContext3D = function ( canvas ) {
			var gl, i,
				contextNames = [ "experimental-webgl", "webkit-3d", "webgl", "moz-webgl" ];

			for ( i = 0; i < contextNames.length; i += 1 ) {
				try {
					gl = canvas.getContext( contextNames[i] );
					if ( gl ) {
						break;
					}
				} catch ( e ) {
					$( canvas ).html( "Unfortunately, there's a WebGL compatibility problem. </br> You may want to check your system settings." );
					return;
				}
			}
			return gl;
		},
		requestAnimationFrame = function ( callback ) {
			var id = window.setTimeout( callback, 1000 / 60 );
			return id;
		},
		cancelAnimationFrame = function ( id ) {
			window.clearTimeout( id );
		};

	$.widget( "tizen.gallery3d", $.mobile.widget, {
		options: {
			thumbnailCache:	false
		},

		_MAX_ITEM_COUNT: 28,
		_ANIMATION_END: 999,
		_DURATION_DEFAULT: 300,
		_DURATION_FIRST: 1600,
		_VIEWPORT_WIDTH: 1024,
		_VIEWPORT_HEIGHT: 456,
		_DIRECTION_LEFT: -1,
		_DIRECTION_RIGHT: +1,

		_gl: null,
		_shaderProgram : null,
		_positionBuffer : null,
		_textureCoordBuffer : null,
		_normalVectorBuffer : null,
		_nodes: null,
		_pMatrix : null,
		_animationID: 0,
		_dragInterval : 0,
		_startTime : 0,
		_sumTime : 0,
		_lightsPositionStack : [
			[0.0, 0.0, -1.0],	// back
			[-0.2, 0.0, 0.7]	// front
		],
		_path: null,
		_swipeThresholdOfBasetimeGap: ( $.support.touch ? 30 : 70 ),
		_swipeThresholdOfSensitivity: ( $.support.touch ? 2.0 : 10.0 ),
		_canvas: null,
		_imageList: [],
		_maxDrawLength: 0,
		_firstImageNumber: 0,
		_lastImageNumber: 0,
		_operationQueue: [],

		_create: function () {
			var self = this,
				view = self.element,
				option = self.options;

			preInitialize();

			self._canvas = $( "<canvas class='ui-gallery3d-canvas'></canvas>" );

			view.addClass( "ui-gallery3d" ).append( self._canvas );
			self._addBehavier();

			self._dragInterval = 1000 / 30;	// 30fps

			$.each( self.options, function ( key, value ) {
				self.options[ key ] = undefined;
				self._setOption( key, value );
			});
		},

		destroy: function () {
			this._final();
			$.mobile.widget.prototype.destroy.call( this );
		},

		_setOption: function ( key, value ) {
			switch ( key ) {
			case "thumbnailCache" :
				if ( typeof value === "string" ) {
					value = ( value === "true" ) ? true : false;
				} else {
					value = !!value;
				}
				this._reset();
				break;
			}

			$.mobile.widget.prototype._setOption.call( this, key, value );
		},

		_init: function ( canvas ) {
			var self = this,
				pathPoints = [
					[40, 0, -48],
					[-12, 0, -40],	// contorl Point of Point1
					[24, 0, -9],		// contorl Point of Point2
					[-5, 0, -5]
				],
				i;

			canvas = canvas || self._canvas;

			if ( !canvas ) {
				return;
			}

			self._gl = self._gl || self._initGL( canvas[0] );
			if ( !self._gl ) {
				return;
			}

			if ( !self._imageList ) {
				return;
			}

			self._shaderProgram = self._shaderProgram || self._initShader( self._gl );
			if ( !self._shaderProgram ) {
				return;
			}

			if ( self._imageList.length > self._MAX_ITEM_COUNT ) {
				self._firstImageNumber = self._imageList.length - 1;
				self._lastImageNumber = self._MAX_ITEM_COUNT - 1;
			}

			self._nodes = self._initBuffers( self._gl, self._shaderProgram );

			self._initTextures( self._gl, self._nodes );

			self._path = $.motionpath( "bezier2d", {
				points: pathPoints,
				maxLevel: self._MAX_ITEM_COUNT
			} );

			for ( i = 0; i < self._nodes.length; i += 1 ) {
				self._path.levels[i] = self._path.levels[i + 1] || 0;
				self._nodes[i].level = i;
			}

			this._setPosition( self._ANIMATION_END, this._DIRECTION_RIGHT );

			while ( this._operationQueue.length ) {
				this._setPosition( self._ANIMATION_END, this._operationQueue.shift() );
			}
		},

		_final: function ( canvas ) {
			var self = this,
				gl = self._gl;

			if ( !gl ) {
				return;
			}

			self._stop();

			canvas = canvas || self._canvas;

			$( self._nodes ).each( function ( i ) {
				var node = self._nodes[i];
				gl.deleteTexture( node.texture );
				node.texture = null;
			});
			self._nodes = null;

			gl.deleteBuffer( self._positionBuffer );
			self._positionBuffer = null;
			gl.deleteBuffer( self._textureCoordBuffer );
			self._textureCoordBuffer = null;
			gl.deleteBuffer( self._normalVectorBuffer );
			self._normalVectorBuffer = null;

			$.webgl.shader.deleteShaders( gl );
			gl.deleteProgram( self._shaderProgram );
			self._shaderProgram = null;

			self._gl = gl = null;
		},

		_addBehavier : function () {
			var self = this,
				view = self.element,
				canvas = self._canvas,
				touchStartEvt = ( $.support.touch ? "touchstart" : "mousedown" ),
				touchMoveEvt = ( $.support.touch ? "touchmove" : "mousemove" ) + ".gallery3d",
				touchEndEvt = ( $.support.touch ? "touchend" : "mouseup" ) + ".gallery3d",
				$document = $( document );

			canvas.on( "webglcontextlost", function ( e ) {
				e.preventDefault();
			}).on( "webglcontextrestored", function ( e ) {
				self._init();
			}).on( touchStartEvt, function ( e ) {
				var i = 0,
					startX = 0,
					deltaMaxSteps = 20,
					deltas = [ deltaMaxSteps ],
					deltaTimes = [ deltaMaxSteps ],
					deltaIndex = 0,
					dragValue = 0,
					dragDirection = false,
					prevTime = 0;

				e.preventDefault();
				e.stopPropagation();

				if ( self._imageList.length <= 1 ) {
					return;
				}

				self._stop();

				startX =  $.support.touch ? e.originalEvent.changedTouches[0].pageX : e.pageX;
				prevTime = $.now();

				for ( i = 0; i < deltaMaxSteps; i += 1 ) {
					deltas[i] = startX;
					deltaTimes[i] = $.now();
				}

				deltaIndex += 1;

				view.on( touchMoveEvt, function ( e ) {
					var x, dx, interval;

					e.preventDefault();
					e.stopPropagation();

					x =  $.support.touch ? e.originalEvent.changedTouches[0].pageX : e.pageX;
					dx = startX - x;

					deltas[deltaIndex] = x;
					deltaTimes[deltaIndex] = $.now();
					interval = deltaTimes[deltaIndex] - prevTime;

					deltaIndex = ( deltaIndex + 1 ) % deltaMaxSteps;

					// Validation of drag
					if ( Math.abs( dx ) >= 10 && interval >= self._dragInterval ) {
						if ( dragDirection !== ( ( dx < 0 ) ? self._DIRECTION_RIGHT : self._DIRECTION_LEFT ) ) {
							dragValue = 0;
							dragDirection = ( dx < 0 ) ? self._DIRECTION_RIGHT : self._DIRECTION_LEFT;
						}

						dragValue += Math.abs( dx ) / 100;
						if ( dragValue >= 1 ) {
							self._setPosition( self._ANIMATION_END, dragDirection );
							dragValue = 0;
						} else {
							self._setPosition( dragValue, dragDirection );
						}
						self._drawScene();
						startX = x;
						prevTime = $.now();
					}
				}).on( touchEndEvt, function ( e ) {
					var baseTime = 0,
						recent = -1,
						index = 0,
						previous = 0,
						baseTimeRatio = 0,
						fx = 0,
						lastX = 0,
						velocityX = 0,
						dx = 0,
						isSwipe = true,
						direction;

					e.preventDefault();
					e.stopPropagation();

					// Validation of swipe
					baseTime = $.now() - self._swipeThresholdOfBasetimeGap;
					lastX = $.support.touch ? e.originalEvent.changedTouches[0].pageX : e.pageX;
					dx = startX - lastX;
					startX = 0;
					for ( i = 0; i < deltaMaxSteps; i += 1 ) {
						index = ( deltaIndex + i ) % deltaMaxSteps;
						if ( deltaTimes[index] > baseTime ) {
							recent = index;
							break;
						}
					}
					if ( recent < 0 ) {
						isSwipe = false;
					}

					if ( isSwipe ) {
						previous = recent;
						for ( i = 0; i < deltaMaxSteps; i += 1 ) {
							previous = ( previous - 1 + deltaMaxSteps ) % deltaMaxSteps;
							if ( deltaTimes[previous] < deltaTimes[recent] ) {
								break;
							}
						}
						// too slow or too fast
						if ( i === deltaMaxSteps || baseTime < deltaTimes[previous] ) {
							isSwipe = false;
						}
					}

					if ( isSwipe ) {
						baseTimeRatio = ( baseTime - deltaTimes[previous] ) / ( deltaTimes[recent] - deltaTimes[previous] );
						fx = ( 1.0 - baseTimeRatio ) * deltas[previous] + baseTimeRatio * deltas[recent];
						if ( Math.abs( fx - lastX ) < self._swipeThresholdOfSensitivity ) {
							fx = lastX;
						}
						velocityX = parseInt( ( lastX - fx ) / ( $.now() - baseTime ), 10 );
					}

					if ( isSwipe && velocityX ) {
						direction = ( velocityX < 0 ) ? self._DIRECTION_LEFT : self._DIRECTION_RIGHT;
						self._run( direction, Math.abs( velocityX ), dragValue );
					} else if ( dragDirection !== 0 && dragValue ) {
						self._animate( null, self._DURATION_DEFAULT * ( 1 - dragValue ), dragDirection, 0, dragValue );
					}

					view.off( ".gallery3d" );
					$document.off( ".gallery3d" );
				});

				$document.on( touchMoveEvt + " " + touchEndEvt, function () {
					view.trigger( touchEndEvt );
				});
			});
		},

		// ----------------------------------------------------------
		// WebGL
		// ----------------------------------------------------------
		_initGL: function ( canvas ) {
			var self = this,
				mat4 = glMatrix.mat4,
				gl;

			gl = getContext3D( canvas );
			if ( !gl ) {
				return null;
			}

			gl.enable( gl.BLEND );
			gl.blendFunc( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA );

			gl.enable( gl.DEPTH_TEST );
			gl.depthFunc( gl.LEQUAL );

			canvas.width = self._VIEWPORT_WIDTH;
			canvas.height = self._VIEWPORT_HEIGHT;
			gl.viewportWidth = canvas.width;
			gl.viewportHeight = canvas.height;
			gl.viewport( 0, 0, gl.viewportWidth, gl.viewportHeight );
			self._pMatrix = mat4.create();
			mat4.perspective( 40, gl.viewportWidth / gl.viewportHeight, 0.1, 10000.0, self._pMatrix );

			gl.clearColor( 0.15, 0.15, 0.15, 1.0 );
			gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );

			return gl;
		},

		_initShader : function ( gl ) {
			var self = this,
				shaderProgram;

			shaderProgram = $.webgl.shader.addShaderProgram( self._gl, VERTEX_SHADER, FRAGMENT_SHADER );
			gl.useProgram( shaderProgram );

			shaderProgram.vertexPositionAttr = gl.getAttribLocation( shaderProgram, "aVertexPosition" );
			gl.enableVertexAttribArray( shaderProgram.vertexPositionAttr );

			shaderProgram.textureCoordAttr = gl.getAttribLocation( shaderProgram, "aTextureCoord" );
			gl.enableVertexAttribArray( shaderProgram.textureCoordAttr );

			// Set light normal vectors for lighting~
			shaderProgram.vertexNormalAttr = gl.getAttribLocation( shaderProgram, "aVertexNormal" );
			gl.enableVertexAttribArray( shaderProgram.vertexNormalAttr );

			shaderProgram.perspectiveMU = gl.getUniformLocation( shaderProgram, "uPerspectiveMatrix");
			shaderProgram.transformMU = gl.getUniformLocation( shaderProgram, "uMoveMatrix");
			shaderProgram.sampleUniform = gl.getUniformLocation( shaderProgram, "uSampler");

			// Set light variables~
			shaderProgram.normalMU = gl.getUniformLocation( shaderProgram, "nNormalMatrix");
			shaderProgram.ambientColorU = gl.getUniformLocation( shaderProgram, "uAmbientColor");
			shaderProgram.lightDirU_first = gl.getUniformLocation( shaderProgram, "uLightDirection_first");
			shaderProgram.lightDirU_second = gl.getUniformLocation( shaderProgram, "uLightDirection_second");
			shaderProgram.directionColorU = gl.getUniformLocation( shaderProgram, "uDirectionColor");

			return shaderProgram;
		},

		_initBuffers: function ( gl, shaderProgram ) {
			var self = this,
				i = 0,
				mashBase = 0,
				vertices = [],
				textureCoords = [],
				normalVectors = [],
				nodes = [],
				maxDrawLength = self._MAX_ITEM_COUNT;

			for ( i = 0; i < self._imageList.length + 1; i += 1 ) {
				nodes[i] = new Node();
				$.merge( vertices, nodes[i].vertices );
				$.merge( textureCoords, nodes[i].textureCoords );
				$.merge( normalVectors, nodes[i].normalVectors );

				nodes[i].textureBuffer = gl.createBuffer();
				gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, nodes[i].textureBuffer );
				mashBase = i * 4;
				nodes[i].meshOrder = [
					mashBase, mashBase + 1, mashBase + 2,
					mashBase + 2, mashBase + 3, mashBase
				];
				gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, new GlArray16( nodes[i].meshOrder ), gl.STATIC_DRAW );
				gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, null ); // release buffer memory
				nodes[i].textureBufferItemSize = 6;
			}

			self._positionBuffer = $.webgl.buffer.attribBufferData( gl, new GlArray32( vertices ) );
			self._positionBuffer.itemSize = 3;

			self._textureCoordBuffer = $.webgl.buffer.attribBufferData( gl, new GlArray32( textureCoords ) );
			self._textureCoordBuffer.itemSize = 2;

			self._normalVectorBuffer = $.webgl.buffer.attribBufferData( gl, new GlArray32( normalVectors ) ); // Vertex's normal vector for Direction light
			self._normalVectorBuffer.itemSize = 3;

			// Ambient light
			gl.uniform3f( shaderProgram.ambientColorU, 0.1, 0.1, 0.1 );
			// Direcntion light
			gl.uniform3f( shaderProgram.directionColorU, 1.0, 1.0, 1.0 );

			return nodes;
		},

		// ----------------------------------------------------------
		// Texture
		// ----------------------------------------------------------
		_initTextures: function ( gl, nodes ) {
			var self = this;

			$( nodes ).each( function ( i ) {
				var node = nodes[i],
					url;

				if ( !self._imageList[i] ) {
					return false;
				}

				url = self._imageList[i].src;
				node.texture = gl.createTexture();
				self._loadImage( url, i, i, gl, nodes );
			});
		},

		_loadImage: function ( url, i, imageID, gl, nodes ) {
			var self = this,
				isMipmap = false,
				image,
				node;

			gl = gl || self._gl;
			nodes = nodes || self._nodes;
			isMipmap = isMipmap || false;
			node = nodes[i];
			node.image = node.image || new Image();
			node.imageID = imageID;

			$( node.image ).one( "load", function ( e ) {
				self._bindTexture( gl, node, this, isMipmap );

				if ( !self._animationID ) {
					self._setPosition( 0, 0 );
				}
			});

			if ( self.options.thumbnailCache ) {
				$.imageloader.getThumbnail( url, function ( result ) {
					if ( result === "NOT_FOUND_ERR" ) {
						$.imageloader.setThumbnail( url, function ( result ) {
							if ( result && result.length > 30 ) {
								node.image.src = result;
								isMipmap = true;
							} else {
								node.image.src = url;
							}
						});
					} else if ( result && result.length > 30 ) {
						node.image.src = result;
						isMipmap = true;
					} else {
						node.image.src = url;
					}
				});
			} else {
				node.image.src = url;
			}
		},

		_bindTexture: function ( gl, node, image, isMipmap ) {
			if ( !node || !node.texture ) {
				return;
			}

			gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, true );

			gl.bindTexture( gl.TEXTURE_2D, node.texture );
			gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image );

			if ( isMipmap ) {
				gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR );
				gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_NEAREST );
				gl.generateMipmap( gl.TEXTURE_2D );
			} else {
				gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR );
				gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR );
			}

			gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE );
			gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE );

			node.texture.loaded = true;

			// release texture memory
			gl.bindTexture( gl.TEXTURE_2D, null );
		},

		// ----------------------------------------------------------
		// rendering
		// ----------------------------------------------------------
		_setPosition: function ( progress, direction ) {
			var self = this,
				mat4 = glMatrix.mat4,
				nodes = self._nodes,
				imageList = self._imageList,
				imageListLength = imageList.length,
				itemCount = self._MAX_ITEM_COUNT,
				displayLength = ( imageListLength > itemCount ) ? itemCount : imageListLength,
				nextLevelLenth = 0,
				i = 0,
				t = 0,
				position = 0,
				angle = 0,
				current = 0,
				next = 0,
				nextLevel = 0,
				path = self._path,
				nextImageID = 0;

			nextLevelLenth = ( direction >= 0 ) ? displayLength + 1 : displayLength;

			if ( !nodes[i].level ) {
				nodes[i].level = displayLength;
			}

			for ( i = 0; i < displayLength; i += 1 ) {
				if ( !nodes[i].mvMatrix ) {
					nodes[i].mvMatrix = mat4.create();
				}

				if ( direction > 0 && nodes[i].level >= displayLength ) {
					nodes[i].level = 0;
				}

				current = path.levels[nodes[i].level];
				nextLevel = ( nodes[i].level + nextLevelLenth + direction ) % nextLevelLenth;
				next = path.levels[nextLevel];

				if ( imageListLength > itemCount ) {
					if ( direction > 0 && nextLevel === 1
							&& self._firstImageNumber !== nodes[i].imageID ) {
						self._loadImage( imageList[self._firstImageNumber].src, i, self._firstImageNumber );
					} else if ( direction < 0 && nextLevel === nextLevelLenth - 1
							&& self._lastImageNumber !== nodes[i].imageID ) {
						self._loadImage( imageList[self._lastImageNumber].src, i, self._lastImageNumber );
					}
				}

				mat4.identity( nodes[i].mvMatrix );
				mat4.translate( nodes[i].mvMatrix, [-2.0, -2.0, 1.0] );
				mat4.rotate( nodes[i].mvMatrix, degreeToRadian( 19 ), [1, 0, 0] );

				t = ( current + ( next - current ) * ( ( progress > 1 ) ? 1 : progress ) );

				if ( progress >= self._ANIMATION_END ) {
					nodes[i].level = nextLevel || displayLength;
					t = path.levels[nodes[i].level];
				}

				if ( ( progress < self._ANIMATION_END )
						&& ( direction <= 0 && nodes[i].level < 1 ) ) {
					nodes[i].drawable = false;
				} else {
					nodes[i].drawable = true;
				}

				if ( progress === self._ANIMATION_END && nodes[i].level === 1 ) {
					self.element.trigger( "select", [imageList[nodes[i].imageID], nodes[i].imageID] );
				}

				position = path.getPosition( t );
				angle = path.getAngle( t );

				mat4.translate( nodes[i].mvMatrix, position );
				mat4.rotate( nodes[i].mvMatrix, angle, [0, 1, 0] );
			}

			if ( imageListLength > itemCount && progress >= self._ANIMATION_END ) {
				self._firstImageNumber = ( self._firstImageNumber - direction ) % imageListLength;
				if ( self._firstImageNumber < 0 ) {
					self._firstImageNumber = imageListLength - 1;
				}

				self._lastImageNumber = ( self._lastImageNumber - direction ) % imageListLength;
				if ( self._lastImageNumber < 0 ) {
					self._lastImageNumber = imageListLength - 1;
				}
			}
			self._drawScene();
		},

		_drawScene: function () {
			if ( !this._gl || !this._shaderProgram ) {
				return;
			}

			var self = this,
				gl = self._gl,
				shaderProgram = self._shaderProgram,
				nodes = self._nodes,
				nodesLength = nodes.length,
				i;

			gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );

			gl.bindBuffer( gl.ARRAY_BUFFER, self._positionBuffer );
			gl.vertexAttribPointer( shaderProgram.vertexPositionAttr, self._positionBuffer.itemSize, gl.FLOAT, false, 0, 0 );

			gl.bindBuffer( gl.ARRAY_BUFFER, self._textureCoordBuffer );
			gl.vertexAttribPointer( shaderProgram.textureCoordAttr, self._textureCoordBuffer.itemSize, gl.FLOAT, false, 0, 0 );

			gl.bindBuffer( gl.ARRAY_BUFFER, self._normalVectorBuffer );
			gl.vertexAttribPointer( shaderProgram.vertexNormalAttr, self._normalVectorBuffer.itemSize, gl.FLOAT, false, 0, 0 );

			for ( i = 0; i < nodesLength; i += 1 ) {
				if ( nodes[i].drawable ) {
					self._drawElement( self._pMatrix, nodes[i] );
				}
			}
		},

		_drawElement: function ( perspectiveMatrix, targetNode ) {
			var self = this,
				gl = self._gl,
				vec3 = glMatrix.vec3,
				mat3 = glMatrix.mat3,
				mat4 = glMatrix.mat4,
				shaderProgram = self._shaderProgram,
				moveMatrix = targetNode.mvMatrix,
				texture = targetNode.texture,
				meshIndexBuffer = targetNode.textureBuffer,
				meshIndexBufferItemSize = targetNode.textureBufferItemSize,
				lightPositions = self._lightsPositionStack,
				LightDir,
				normalMatrix;

			if ( !moveMatrix ) {
				return;
			}

			gl.activeTexture( gl.TEXTURE0 );
			if ( texture && texture.loaded ) {
				gl.bindTexture( gl.TEXTURE_2D, texture );
			}
			gl.uniform1i( shaderProgram.sampleUniform, 0 );

			LightDir = vec3.create();
			vec3.normalize( lightPositions[0], LightDir );
			vec3.scale( LightDir, -8 );
			gl.uniform3fv( shaderProgram.lightDirU_first, LightDir );

			vec3.normalize( lightPositions[1], LightDir );
			vec3.scale( LightDir, -1 );
			gl.uniform3fv( shaderProgram.lightDirU_second, LightDir );
			gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, meshIndexBuffer );

			gl.uniformMatrix4fv( shaderProgram.perspectiveMU, false, perspectiveMatrix );
			gl.uniformMatrix4fv( shaderProgram.transformMU, false, moveMatrix );

			normalMatrix = mat3.create();
			mat4.toInverseMat3( moveMatrix, normalMatrix );
			mat3.transpose( normalMatrix );
			gl.uniformMatrix3fv( shaderProgram.normalMU, false, normalMatrix );

			gl.drawElements( gl.TRIANGLES, meshIndexBufferItemSize, gl.UNSIGNED_SHORT, 0 );

			// release buffer memory
			gl.bindBuffer( gl.ARRAY_BUFFER, null );
			gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, null );

			// release texture memory
			gl.bindTexture( gl.TEXTURE_2D, null );
		},

		// ----------------------------------------------------------
		// Animation
		// ----------------------------------------------------------
		_animate: function ( easingType, duration, direction, repeatCount, startValue, _removeCount ) {
			var self = this,
				timeNow = $.now(),
				progress,
				removeCount = 0;

			easingType = easingType || "linear";
			startValue = startValue || 0;
			_removeCount = _removeCount || 0;

			if ( self._sumTime >= duration ) {
				self._setPosition( self._ANIMATION_END, direction );
				self._stop();
				return;
			}

			if ( self._startTime === 0 ) {
				self._startTime = timeNow;
			} else {
				self._sumTime = timeNow - self._startTime;
				progress = $.easing[ easingType ]( self._sumTime / duration, self._sumTime, startValue, repeatCount + 1, duration );
				removeCount = parseInt( Math.abs( progress ), 10 );

				if ( _removeCount !== removeCount ) {
					self._setPosition( self._ANIMATION_END, direction );
					_removeCount = removeCount;

					if ( ( repeatCount - _removeCount ) >= 0 ) {
						self._animate( easingType, duration, direction, repeatCount, startValue, _removeCount );
					} else {
						self._stop();
					}
					return;
				}

				self._setPosition( progress - _removeCount, direction );
			}

			self._animationID = requestAnimationFrame( function () {
				self._animate( easingType, duration, direction, repeatCount, startValue, _removeCount );
			});
		},

		_run: function ( direction, repeatCount, startValue ) {
			var self = this,
				repeat = repeatCount || 0,
				duration = self._DURATION_DEFAULT * ( repeat + 1 );

			if ( !self._gl ) {
				self._operationQueue.push( direction );
				return;
			}

			if ( self._imageList.length <= 1 ) {
				return;
			}

			startValue = startValue || 0;
			duration = ( duration >= 0 ) ? duration : 0;

			if ( self._animationID ) {
				self._setPosition( self._ANIMATION_END, direction );
				self._stop();
			}

			self._animate( "easeOutExpo", duration, direction, repeat, startValue );
		},

		_reset: function () {
			if ( !this._canvas || !this._gl ) {
				return;
			}

			this._final();
			this._init();
			this.refresh();
		},

		_stop: function () {
			if ( this._animationID ) {
				cancelAnimationFrame( this._animationID );
			}
			this._animationID = 0;

			this._startTime = 0;
			this._sumTime = 0;
		},

		next: function () {
			this._run( this._DIRECTION_LEFT , 0 );
		},

		prev: function () {
			this._run( this._DIRECTION_RIGHT, 0 );
		},

		refresh: function () {
			var view = this.element,
				canvas = view.find( "canvas.ui-gallery3d-canvas" );

			if ( canvas.width() !== view.width() ) {
				canvas.width( view.width() );
			}

			if ( !this._animationID ) {
				this._setPosition( 0, 0 );
			}
		},

		select: function ( index ) {
			var nodes = this._nodes,
				repeat,
				i,
				imageID,
				object = null,
				target = 0,
				direction = 0;

			if ( index && this._animationID ) {
				this._stop();
			}

			for ( i in nodes ) {
				if ( nodes[i].level === 1 ) {
					object = this._imageList[ nodes[i].imageID ];
					imageID = nodes[i].imageID;
					break;
				}
			}

			if ( !index ) {
				return object;
			}

			if ( index < 0 && index >= this._imageList.length ) {
				return;
			}

			target = index - imageID;
			direction = ( target > 0 ) ? this._DIRECTION_LEFT
				: ( ( target < 0 ) ? this._DIRECTION_RIGHT : 0 );
			if ( direction ) {
				this._run( direction, Math.abs( target ) - 1  );
			}
		},

		add: function ( item, index ) {
			if ( !item ) {
				return;
			}

			if ( typeof item === "string" ) {
				item = { "src" : item };
			}

			index = index || 0;
			if ( typeof index !== "number" && index < 0
					&& index >= this._imageList.length ) {
				return;
			}

			this._imageList.splice( index, 0, item );
			if ( this._gl ) {
				this._reset();
			}
		},

		remove: function ( index ) {
			index = index || 0;
			if ( typeof index !== "number" && index < 0
					&& index >= this._imageList.length ) {
				return;
			}

			this._imageList.splice( index, 1 );
			if ( this._gl ) {
				this._reset();
			}
		},

		clearThumbnailCache: function () {
			if ( !this._nodes || ( this._nodes.length <= 0 ) ) {
				return;
			}

			var i, url;
			for ( i = 0; i < this._imageList.length; i += 1 ) {
				url = this._imageList[i].src;
				$.imageloader.removeThumbnail( url );
			}
		},

		empty: function () {
			this._imageList = [];
			this._reset();
		},

		length: function () {
			return this._imageList.length;
		}
	});

	$( document ).on( "pagecreate create", function ( e ) {
		$( ":jqmData(role='gallery3d')" ).gallery3d();
	}).on( "pagechange", function ( e ) {
		$( e.target ).find( ".ui-gallery3d" ).gallery3d( "refresh" );
	});

	$( window ).on( "resize orientationchange", function ( e ) {
		$( ".ui-page-active" ).find( ".ui-gallery3d" ).gallery3d( "refresh" );
	});

} ( jQuery, document, window ) );



/**
	@class Button
	The button widget shows a control on the screen that you can use to generate an action event when it is pressed and released. This widget is coded with standard HTML anchor and input elements and then enhanced by jQueryMobile to make it more attractive and usable on a mobile device. Buttons can be used in Tizen as described in the jQueryMobile documentation for buttons.

	To add a button widget to the application, use the following code

		<div data-role="button" data-inline="true">Text Button Test</div>
		<div data-role="button" data-inline="true" data-icon="plus" data-style="circle"></div>
		<div data-role="button" data-inline="true" data-icon="plus" data-style="nobg"></div>

	The button can define callbacks for events as described in the jQueryMobile documentation for button events.<br/>
	You can use methods with the button as described in the jQueryMobile documentation for button methods.
*/

/**
	@property {String} data-style
	Defines the button style. <br/> The default value is box. If the value is set to circle, a circle-shaped button is created. If the value is set to nobg, a button is created without a background.

*/
/**
	@property {String} data-icon
	Defines an icon for a button. Tizen supports 12 icon styles: reveal, closed, opened, info, rename, call, warning, plus, minus, cancel, send, and favorite.

*/



/*
 * jQuery Mobile Widget @VERSION
 *
 * TODO: remove unnecessary codes....
 *
 * This software is licensed under the MIT licence (as defined by the OSI at
 * http://www.opensource.org/licenses/mit-license.php)
 * 
 * ***************************************************************************
 * Copyright (C) 2011 by Intel Corporation Ltd.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 *
 * Authors: Kalyan Kondapally <kalyan.kondapally@intel.com>
 */

ensureNS("jQuery.mobile.tizen");

(function () {
jQuery.extend(jQuery.mobile.tizen, {
	disableSelection: function (element) {
		this.enableSelection(
			$(element).find('*').not( 'input, [type="text"], textarea' ),
			'none'
		);
		return true;
	},

	enableSelection: function (element, value) {
		var val;
		switch ( value ) {
			case 'text' :
			case 'auto' :
			case 'none' :
				val = value;
			break;
			default :
				val = 'auto';
			break;
		}
		return $(element).css( {
			'user-select': val,
			'-moz-user-select': val,
			'-webkit-user-select': val,
			'-o-user-select': val,
			'-ms-transform': val
		} );
    },

    disableContextMenu: function(element) {
	var self = this;
	$(element).find('*').each( function() {
		if( ( $(this).get(0).tagName !== 'INPUT' &&
			$(this).attr("type") !== 'text' ) &&
			$(this).get(0).tagName !== 'TEXTAREA' ) {
			self._disableContextMenu( this );
		}
	} );
    },

    _disableContextMenu: function(element) {

	$(element).each( function() {
		$(this).bind("contextmenu", function( event ) {
			return false;
		} );
	} );
    },

    enableContextMenu: function(element) {
	$(element).each( function() {
		$(this).unbind( "contextmenu" );
	} );
    },

    // Get document-relative mouse coordinates from a given event
    // From: http://www.quirksmode.org/js/events_properties.html#position
    documentRelativeCoordsFromEvent: function(ev) {
        var e = ev ? ev : window.event,
            client = { x: e.clientX, y: e.clientY },
            page   = { x: e.pageX,   y: e.pageY   },
            posx = 0,
            posy = 0;

        // Grab useful coordinates from touch events
        if (e.type.match(/^touch/)) {
            page = {
                x: e.originalEvent.targetTouches[0].pageX,
                y: e.originalEvent.targetTouches[0].pageY
            };
            client = {
                x: e.originalEvent.targetTouches[0].clientX,
                y: e.originalEvent.targetTouches[0].clientY
            };
        }

        if (page.x || page.y) {
            posx = page.x;
            posy = page.y;
        }
        else
        if (client.x || client.y) {
            posx = client.x + document.body.scrollLeft + document.documentElement.scrollLeft;
            posy = client.y + document.body.scrollTop  + document.documentElement.scrollTop;
        }

        return { x: posx, y: posy };
    },

	// TODO : offsetX, offsetY. touch events don't have offsetX and offsetY. support for touch devices.
    // check algorithm...
    targetRelativeCoordsFromEvent: function(e) {
        var coords = { x: e.offsetX, y: e.offsetY };

        if (coords.x === undefined || isNaN(coords.x) ||
            coords.y === undefined || isNaN(coords.y)) {
            var offset = $(e.target).offset();
            //coords = documentRelativeCoordsFromEvent(e);	// Old code. Must be checked again.
            coords = $.mobile.tizen.documentRelativeCoordsFromEvent(e);
            coords.x -= offset.left;
            coords.y -= offset.top;
        }

        return coords;
    }
});

})();



/* ***************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 *
 *	Author: Jinhyuk Jun <jinhyuk.jun@samsung.com>
 */

(function ( $, undefined ) {

	$.widget( "mobile.pagelayout", $.mobile.widget, {
		options: {
			visibleOnPageShow: true,
			disablePageZoom: true,
			transition: "slide", //can be none, fade, slide (slide maps to slideup or slidedown)
			fullscreen: false,
			tapToggle: true,
			tapToggleBlacklist: "a, input, select, textarea, .ui-header-fixed, .ui-footer-fixed",
			hideDuringFocus: "input, textarea, select",
			updatePagePadding: true,
			// Browser detection! Weeee, here we go...
			// Unfortunately, position:fixed is costly, not to mention probably impossible, to feature-detect accurately.
			// Some tests exist, but they currently return false results in critical devices and browsers, which could lead to a broken experience.
			// Testing fixed positioning is also pretty obtrusive to page load, requiring injected elements and scrolling the window
			// The following function serves to rule out some popular browsers with known fixed-positioning issues
			// This is a plugin option like any other, so feel free to improve or overwrite it
			supportBlacklist: function () {
				var w = window,
					ua = navigator.userAgent,
					platform = navigator.platform,
					// Rendering engine is Webkit, and capture major version
					wkmatch = ua.match( /AppleWebKit\/([0-9]+)/ ),
					wkversion = !!wkmatch && wkmatch[ 1 ],
					ffmatch = ua.match( /Fennec\/([0-9]+)/ ),
					ffversion = !!ffmatch && ffmatch[ 1 ],
					operammobilematch = ua.match( /Opera Mobi\/([0-9]+)/ ),
					omversion = !!operammobilematch && operammobilematch[ 1 ];

				if (
					// iOS 4.3 and older : Platform is iPhone/Pad/Touch and Webkit version is less than 534 (ios5)
					( ( platform.indexOf( "iPhone" ) > -1 || platform.indexOf( "iPad" ) > -1  || platform.indexOf( "iPod" ) > -1 ) && wkversion && wkversion < 534 ) ||
						// Opera Mini
						( w.operamini && ({}).toString.call( w.operamini ) === "[object OperaMini]" ) ||
						( operammobilematch && omversion < 7458 ) ||
						//Android lte 2.1: Platform is Android and Webkit version is less than 533 (Android 2.2)
						( ua.indexOf( "Android" ) > -1 && wkversion && wkversion < 533 ) ||
						// Firefox Mobile before 6.0 -
						( ffversion && ffversion < 6 ) ||
						// WebOS less than 3
						( window.palmGetResource !== undefined && wkversion && wkversion < 534 ) ||
						// MeeGo
						( ua.indexOf( "MeeGo" ) > -1 && ua.indexOf( "NokiaBrowser/8.5.0" ) > -1 )
				) {
					return true;
				}

				return false;
			},
			initSelector: ":jqmData(role='content')"
		},

		_create: function () {

			var self = this,
				o = self.options,
				$el = self.element;

			// Feature detecting support for
			if ( o.supportBlacklist() ) {
				self.destroy();
				return;
			}

			self._addFixedClass();
			self._addTransitionClass();
			self._bindPageEvents();

			// only content
			self._bindContentControlEvents();

			// Store back-button, to show again
			self._backBtnQueue = [];
		},

		/* add minimum fixed css style to bar(header/footer) and content
		*  it need to update when core source modified(jquery.mobile.page.section.js)
		*  modified from core source cuz initSelector different */
		_addFixedClass: function () {
			var self = this,
				o = self.options,
				$el = self.element,
				$elHeader = $el.siblings( ":jqmData(role='header')" ),
				$elFooter = $el.siblings( ":jqmData(role='footer')" ),
				$elPage = $el.closest(".ui-page");

			$elHeader.addClass( "ui-header-fixed" );
			$elFooter.addClass( "ui-footer-fixed" );

			// "fullscreen" overlay positioning
			if ( o.fullscreen ) {
				$elHeader.addClass( "ui-header-fullscreen" );
				$elFooter.addClass( "ui-footer-fullscreen" );
				$elPage
					.addClass( "ui-page-header-fullscreen" )
					.addClass( "ui-page-footer-fullscreen" );
			} else {
			// If not fullscreen, add class to page to set top or bottom padding
				$elPage.addClass( "ui-page-header-fixed" )
					.addClass( "ui-page-footer-fixed" );
			}
		},

		/* original core source(jquery.mobile.fixedToolbar.js)
		* never changed */
		_addTransitionClass: function () {
			var tclass = this.options.transition;

			if ( tclass && tclass !== "none" ) {
				// use appropriate slide for header or footer
				if ( tclass === "slide" ) {
					tclass = this.element.is( ".ui-header" ) ? "slidedown" : "slideup";
				}

				this.element.addClass( tclass );
			}
		},


		/* Set default page positon
		* 1. add title style to header
		* 2. Set default header/footer position */
		setHeaderFooter: function ( thisPage ) {
			var $elPage = $( thisPage ),
				$elHeader = $elPage.find( ":jqmData(role='header')" ).length ? $elPage.find( ":jqmData(role='header')") : $elPage.siblings( ":jqmData(role='header')"),
				$elContent = $elPage.find( ".ui-content" ),
				$elFooter = $elPage.find( ":jqmData(role='footer')" ),
				$elFooterGroup = $elFooter.find( ":jqmData(role='fieldcontain')" ),
				$elFooterControlGroup = $elFooter.find( ".ui-controlgroup" );

			// divide content mode scrollview and non-scrollview
			if ( !$elPage.is( ".ui-dialog" ) ) {
				if ( $elHeader.jqmData("position") == "fixed" || ( $.support.scrollview && $.tizen.frameworkData.theme.match(/tizen/) ) ) {
					$elHeader
						.css( "position", "fixed" )
						.css( "top", "0px" );
				} else if ( !$.support.scrollview && $elHeader.jqmData("position") != "fixed" ) {
					$elHeader.css( "position", "relative" );
				}
			}

			/* set Title style */
			if ( $elHeader.find("span.ui-title-text-sub").length ) {
				$elHeader.addClass( "ui-title-multiline");
			}

			if ( $elFooterGroup.find( "div" ).is( ".ui-controlgroup-label" ) ) {
				$elFooterGroup.find( "div.ui-controlgroup-label" ).remove();
			}

			if ( $elFooterControlGroup.length ) {
				var anchorPer = 100 / $elFooterControlGroup.find( "a" ).length;
				$elFooterControlGroup.find( "a" ).each( function ( i ) {
					$elFooterControlGroup.find( "a" ).eq( i ).width( anchorPer + "%" );
				});
			}
		},

		_bindPageEvents: function () {
			var self = this,
				o = self.options,
				$el = self.element,
				$elCurrentFooter;

			//page event bindings
			// Fixed toolbars require page zoom to be disabled, otherwise usability issues crop up
			// This method is meant to disable zoom while a fixed-positioned toolbar page is visible
			$el.closest( ".ui-page" )
				.bind( "pagebeforeshow", function ( event ) {
					var thisPage = this;
					if ( o.disablePageZoom ) {
						$.mobile.zoom.disable( true );
					}
					if ( !o.visibleOnPageShow ) {
						self.hide( true );
					}
					self.setHeaderFooter( thisPage );
					self._setContentMinHeight( thisPage );
					self._updateHeaderArea( thisPage );
					self._updateFooterArea( thisPage );
				} )
				.bind( "webkitAnimationStart animationstart updatelayout", function ( e, data ) {
					var thisPage = this;
					if ( o.updatePagePadding ) {
						self.updatePagePadding(thisPage);
						self.updatePageLayout( thisPage, data);
					}
				})

				.bind( "pageshow", function ( event ) {
					var thisPage = this;
					self._setContentMinHeight( thisPage );
					self.updatePagePadding( thisPage );
					self._updateHeaderArea( thisPage );
					self._updateFooterArea( thisPage );

					// check device api : HW key existance
					// TODO: remove these functions, because the HW key is mandatory.
					if ( false ) {
						self._bindHWkeyOnSWBtn();
						self._setHWKeyLayout( thisPage );
					}
					self._setHWKeySupport( thisPage );
					//self._setMenuPopupLayout( thisPage );

					if ( o.updatePagePadding ) {
						$( window ).bind( "throttledresize." + self.widgetName, function () {
							self.updatePagePadding(thisPage);
							self.updatePageLayout( thisPage, true);
							self._updateHeaderArea( thisPage );
							self._updateFooterArea( thisPage );
							self._setContentMinHeight( thisPage );
						});
					}
				})

				.bind( "pagebeforehide", function ( e, ui ) {
					self._unsetHWKeySupport( );
					if ( o.disablePageZoom ) {
						$.mobile.zoom.enable( true );
					}
					if ( o.updatePagePadding ) {
						$( window ).unbind( "throttledresize." + self.widgetName );
					}
				});

			window.addEventListener( "softkeyboardchange", function ( e ) {
				var $elDownBtn = $( "<div class='ui-btn-footer-down'></div>" ),
					$elPage = $( ".ui-page-active" ),
					backBtn,
					backBtnPosition = "footer";
				// N_SE-42987 : If self._backBtnQueue.length has value is not 0, this means .ui-btn-back button is still hidden.
				//		So, condition that check self._backBtnQueue value add.
				if ( $elPage.data( "addBackBtn" ) || self._backBtnQueue.length ) {
					$elPage.data( "addBackBtn" ) == "header" ? backBtnPosition = "header" : backBtnPosition = "footer";

					if ( e.state == "on" ) {
						if ( !$elPage.find( ".ui-" + backBtnPosition + " .ui-btn-footer-down" ).length ) {
							$elDownBtn.buttonMarkup( { icon: "down" } ).appendTo( $elPage.find( ".ui-" + backBtnPosition ) );
						}

						// N_SE-32900: If an app moves a page when the pop is shown, the .ui-page-active page
						//             is changed.
						//             In this case, the '.ui-page-active .ui-btn-back' selector indicates a
						//             new page's one, and the old page's .ui-btn-back button is still hidden.
						//             So, the current back button is remembered to be shown at the
						//             softkeyboardchange.off event.
						if ( true ) {
							backBtn = $( ".ui-page-active .ui-btn-back" );
							backBtn.hide();
							self._backBtnQueue.push( backBtn );	// Store hidden backBtn
						}
					} else if ( e.state == "off" ) {
						if ( true ) {
							self._backBtnQueue.forEach( function ( b ) {
								b.show();	// Show each backBtn,
							} );
							self._backBtnQueue.length = 0;	// and clear queue.
						}
						$( ".ui-btn-footer-down" ).remove();
					}
				}
			});
		},

		_bindContentControlEvents: function () {
			var self = this,
				o = self.options,
				$el = self.element;

			$el.closest( ".ui-page" )
				.bind( "pagebeforeshow", function ( event ) {

				});
		},

		_HWKeyHandler: function ( ev ) {
			var $openedpopup = $.mobile.popup.active,
				$page,
				$focused;
			// NOTE: The 'tizenhwkey' event is passed only document -> window objects.
			//       Other DOM elements does not receive 'tizenhwkey' event.

			// menu key
			if( ev.originalEvent.keyName == "menu" ) {
				// Blur focused element to turn off SIP(IME)
				$page = $( ev.data ); 	// page object, passed by _setHWKeySupport()
				$focused = $page.find( ".ui-focus" );
				if( $focused[0] ) {	// Focused element is found
					$focused.blur();
					// NOTE: If a popup is opened and focused element exists in it,
					//       do not close that popup.
					//       'false' is returned here, hence popup close routine is not run.
					return false;
				}
				// Close opened popup
				if( $openedpopup ) {
					$openedpopup.close();
					return false;
				}
			}
			// back key
			else if( ev.originalEvent.keyName == "back" ) {
				// Close opened popup
				if( $openedpopup ) {
					$openedpopup.close();
					return false;
				}
			}
			return true;	// Otherwise, propagate tizenhwkey event to window object
		},

		_setHWKeySupport: function( thisPage ) {
			$( document ).on( "tizenhwkey", thisPage, this._HWKeyHandler );
		},

		_unsetHWKeySupport: function () {
			$( document ).off( "tizenhwkey", this._HWKeyHandler );
		},

		_bindHWkeyOnSWBtn: function () {
			// if HW key not exist
			// return true
			// else
			$( document ).on( "tizenhwkey", function( e ) {
				var openedpopup = $.mobile.popup.active,
					$elPage = $( ".ui-page-active" ),
					$elFooter = $elPage.find( ":jqmData(role='footer')" ),
					$elMoreKey = $elFooter.children(":jqmData(icon='naviframe-more')"),
					morePopup;

				if ( $( ".ui-page-active .ui-footer" ).hasClass( "ui-footer-force-btn-show" ) ) {
					return true;
				}

				if ( e.originalEvent.keyName === "back" ) {
					// need to change back button
					if( openedpopup ) {
						openedpopup.close();
						return false;
					}
					//Click trigger
					 $( ".ui-page-active .ui-footer .ui-btn-back" ).trigger( "click" );
					return false;
				} else if ( e.originalEvent.keyName === "menu" ) {
					// if more button was clicked, all kinds of popups will be closed
					if ( openedpopup ) {
						openedpopup.close();
						return false;
					}

					// need to change more key trigger
					if ( $elMoreKey.get(0) ) {
						$elMoreKey.trigger( "click" );
					}
					return false;
				}
			} );

		},

		_setContentMinHeight : function ( thisPage ) {
			var $elPage = $( thisPage ),
				$elHeader = $elPage.find( ":jqmData(role='header')" ),
				$elFooter = $elPage.find( ":jqmData(role='footer')" ),
				$elContent = $elPage.find( ":jqmData(role='content')" ),
				footerHeight,
				resultMinHeight,
				dpr = 1,
				layoutInnerHeight = window.innerHeight;

			if ( !$.support.scrollview || ($.support.scrollview && $elContent.jqmData("scroll") === "none") ) {
					dpr = window.outerWidth / window.innerWidth;
					layoutInnerHeight = Math.floor( window.outerHeight / dpr );
			} else {
				layoutInnerHeight = window.innerHeight;
			}

			if ( $elFooter.css( "display" ) === "none" ) {
				footerHeight = 0;
			} else {
				footerHeight = $elFooter.height();
			}
			resultMinHeight = layoutInnerHeight - $elHeader.height() - footerHeight;

			if ( $.support.scrollview && $elContent.jqmData("scroll") !== "none" ) {
				$elContent.css( "min-height", resultMinHeight - parseFloat( $elContent.css("padding-top") ) - parseFloat( $elContent.css("padding-bottom") ) + "px" );
				$elContent.children( ".ui-scrollview-view" ).css( "min-height", $elContent.css( "min-height" ) );
			}
		},

		_updateHeaderArea : function ( thisPage ) {
			var $elPage = $( thisPage ),
				$elHeader = $elPage.find( ":jqmData(role='header')" ).length ? $elPage.find( ":jqmData(role='header')") : $elPage.siblings( ":jqmData(role='header')"),
				$headerBtn = $elHeader.children("a,[data-"+$.mobile.ns+"role=button]"),
				headerBtnWidth = $headerBtn.width() + parseInt( $headerBtn.css("padding-left") ) + parseInt( $headerBtn.css("padding-right") ),
				headerBtnNum = $headerBtn.length,
				$headerSrc = $elHeader.children("img"),
				headerSrcNum = $headerSrc.length,
				headerSrcWidth = $headerSrc.width() + parseInt( $headerSrc.css("margin-left") ),
				h1width;

			if ( !$elPage.is( ".ui-dialog" ) ) {
				h1width = window.innerWidth - parseInt( $elHeader.find( "h1" ).css( "margin-left" ), 10 ) * 2 - headerBtnWidth * headerBtnNum - headerSrcWidth * headerSrcNum;
				$elHeader.find( "h1" ).css( "width", h1width );
				$elHeader.find( '.ui-title-text-sub' ).css( "width", h1width );
			}
			/* add half width for default space between text and button, and img tag area is too narrow, so multiply three for img width*/
		},

		_updateFooterArea : function ( thisPage ) {
			var $elPage = $( thisPage ),
				$elFooter = $elPage.find( ".ui-footer" ),
				$elMoreKey = $elFooter.children( ":jqmData(icon='naviframe-more')" ),
				$elBackKey = $elFooter.children( ".ui-btn-back, .ui-btn-footer-down" ),
				footerBtn = $elFooter.children( "div.ui-btn, a.ui-btn" ),
				btnLength = footerBtn.length,
				btnWidth = window.innerWidth,
				realBtnIndex = 0,
				idx, moreWidth = 0;

			if ( !btnLength ) {
				return;
			}

			if ( $elMoreKey.length ) {
				moreWidth = $elMoreKey.width();
				btnWidth -= moreWidth;
			}

			if ( $elBackKey.length ) {
				btnWidth -= $elBackKey.width();
				$elBackKey.addClass( "ui-footer-btn-border" );
			}

			btnWidth /= btnLength - $elMoreKey.length - $elBackKey.length;

			for ( idx = 0; idx < btnLength; idx++ ) {
				if ( footerBtn.eq( idx ).hasClass( "ui-btn-back" ) ) {
					continue;
				}
				if ( footerBtn.eq( idx ).is( ":jqmData(icon='naviframe-more')" ) ){
					continue;
				}
				footerBtn.eq( idx )
					.addClass( "ui-footer-btn-border" )
					.width( btnWidth )
					.css( "position", "absolute" )
					.css( "left", realBtnIndex * btnWidth + moreWidth );
				realBtnIndex++;
			}
			$elFooter.find( ".ui-footer-btn-border" ).eq( 0 ).removeClass( "ui-footer-btn-border" );
		},

		_setHWKeyLayout : function ( thisPage ) {
			var $elPage = $( thisPage ),
				$elFooter = $elPage.find( ":jqmData(role='footer')" ),
				$elBackKey = $elFooter.children( ".ui-btn-back" ),
				$elMoreKey = $elFooter.children(":jqmData(icon='naviframe-more')"),
				$elTabBar = $elFooter.children( ".ui-tabbar" ),
				$elControlGroup = $elFooter.children( ".ui-controlgroup" );
				//cntMore = 0,
			
				// Check HW Key option
			if ( $elFooter.hasClass("ui-footer-force-btn-show") ) {
				return true;
			}

			/*
			if ( $elMoreKey.length ) {
				cntMore = $elMoreKey.length + 1;
			} else {
				cntMore = 0;
			}

			// need to add device api to check HW key exist
			// Case 1 : footer - BackKey/MoreKey/Button - hide BackKey/MoreKey
			if ( $elFooter.children().length - $elBackKey.length - cntMore > 0 ) {
				$elBackKey.hide();
				$elMoreKey.hide();
			// Case 2 : footer - BackKey/MoreKey - more, back hide depend on OSP
			} else {
				$elBackKey.hide();
				$elMoreKey.hide();
			}
			*/

			if( $elMoreKey ) {
				$elMoreKey.hide();
			}
			if( $elBackKey ) {
				$elBackKey.hide();
			}
			if( $elTabBar ) {
				$elTabBar.removeClass( "ui-tabbar-margin-more ui-tabbar-margin-back" );
			}
			if ( $elControlGroup ) {
				$elControlGroup.removeClass( "ui-controlgroup-padding-more ui-controlgroup-padding-back" );
			}
			// Case 3 : no footer - do nothing

			return true;
		},
		_setMenuPopupLayout: function ( thisPage ) {
			var $page = $( thisPage ),
				$footer = $page.find( ":jqmData(role='footer')" ),
				moreKey = $page.find( ":jqmData(icon='naviframe-more')" )[0],
				//cntMore = 0,
				$morePopup;

			if( moreKey && moreKey.hash ) {	// moreKey.hash = #morePopupID (from <a href="">)
				$morePopup =  $( moreKey.hash );
				$morePopup.addClass ( "ui-ctxpopup-optionmenu" );
			}
		 },

		_visible: true,

		// This will set the content element's top or bottom padding equal to the toolbar's height
		updatePagePadding: function ( tbPage ) {
			var $el = this.element,
				header = $el.siblings( ".ui-header" ).length,
				footer = $el.siblings( ".ui-footer" ).length;

			// This behavior only applies to "fixed", not "fullscreen"
			if ( this.options.fullscreen ) {
				return;
			}

			tbPage = tbPage || $el.closest( ".ui-page" );

			if ( $el.siblings( ".ui-header" ).jqmData("position") == "fixed" || ($.support.scrollview && $el.jqmData("scroll") !== "none" )) {
				$( tbPage ).css( "padding-top", ( header ? $el.siblings( ".ui-header" ).outerHeight() : 0 ) );
			}
			$( tbPage ).css( "padding-bottom", (( footer && $el.siblings( ".ui-footer" ).css( "display" ) !== "none" ) ? $el.siblings( ".ui-footer" ).outerHeight() : 0 ) );
		},

		/* 1. Calculate and update content height   */
		updatePageLayout: function ( thisPage, receiveType ) {
			var $elFooter,
				$elPage = $( thisPage ),
				$elHeader = $elPage.find( ":jqmData(role='header')" ),
				$elContent = $elPage.find( ":jqmData(role='content')" ),
				resultContentHeight = 0,
				resultFooterHeight = 0,
				resultHeaderHeight = 0,
				layoutInnerHeight = window.innerHeight,
				dpr = 1;

			if ( $elPage.length ) {
				$elFooter = $elPage.find( ":jqmData(role='footer')" );
			} else {
				$elFooter = $( document ).find( ":jqmData(role='footer')" ).eq( 0 );
			}

			// calculate footer height
			resultFooterHeight = ( $elFooter.css( "display" ) == "none" || $elFooter.length == 0 ) ? 0 : $elFooter.height();
			resultHeaderHeight = ( $elHeader.css( "display" ) == "none" || $elHeader.length == 0 ) ? 0 : $elHeader.height();

			if (resultFooterHeight != 0 ) {
				$elFooter.css( "bottom", 0 );
			}

			if ( !$.support.scrollview || ($.support.scrollview && $elContent.jqmData("scroll") === "none") ) {
				dpr = window.outerWidth / window.innerWidth;
				layoutInnerHeight = Math.floor( window.outerHeight / dpr );
			} else {
				//#N_SE-43092: window.innerHeight returns incorrect size
				layoutInnerHeight = $.mobile.$window.height();
			}

			resultContentHeight = layoutInnerHeight - resultFooterHeight - resultHeaderHeight;

			if ( $.support.scrollview && $elContent.jqmData("scroll") !== "none" ) {
				$elContent.height( resultContentHeight -
						parseFloat( $elContent.css("padding-top") ) -
						parseFloat( $elContent.css("padding-bottom") ) );
			}

			// External call page( "refresh") - in case title changed
			if ( receiveType ) {
				$elPage
					.css( "min-height", resultContentHeight )
					.css( "padding-top", resultHeaderHeight )
					.css( "padding-bottom", resultFooterHeight );
			}
		},

		show: function ( notransition ) {
			/* blank function: deprecated */
		},

		hide: function ( notransition ) {
			/* blank function: deprecated */
		},

		toggle: function () {
			this[ this._visible ? "hide" : "show" ]();
		},

		destroy: function () {
			this.element.removeClass( "ui-header-fixed ui-footer-fixed ui-header-fullscreen ui-footer-fullscreen in out fade slidedown slideup ui-fixed-hidden" );
			this.element.closest( ".ui-page" ).removeClass( "ui-page-header-fixed ui-page-footer-fixed ui-page-header-fullscreen ui-page-footer-fullscreen" );
		},

		refresh: function () {
			var $elPage = $( ".ui-page-active" );
			this.setHeaderFooter( $elPage );
			this._updateHeaderArea( $elPage );
		}
	});

	//auto self-init widgets
	$( document )
		.bind( "pagecreate create", function ( e ) {
			// DEPRECATED in 1.1: support for data-fullscreen=true|false on the page element.
			// This line ensures it still works, but we recommend moving the attribute to the toolbars themselves.
			if ( $( e.target ).jqmData( "fullscreen" ) ) {
				$( $.mobile.pagelayout.prototype.options.initSelector, e.target ).not( ":jqmData(fullscreen)" ).jqmData( "fullscreen", true );
			}
			$.mobile.pagelayout.prototype.enhanceWithin( e.target );
		})
		.bind( "pagebeforeshow", function ( event, ui ) {
			var footer_filter = $( event.target ).find( ":jqmData(role='footer')" ),
				controlgroup_filter = footer_filter.find( ":jqmData(role='controlgroup')" ),
				$elFooterMore = controlgroup_filter.siblings( ":jqmData(icon='naviframe-more')" ),
				$elFooterBack = controlgroup_filter.siblings( ".ui-btn-back" );

			if ( $elFooterMore.length ) {
				controlgroup_filter.addClass( "ui-controlgroup-padding-more" );
			}
			if ( $elFooterBack.length ) {
				controlgroup_filter.addClass( "ui-controlgroup-padding-back" );
			}
		});

}( jQuery ));



/* ***************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 *
 *	Author: Wongi Lee <wongi11.lee@samsung.com>
 *	        Youmin Ha <youmin.ha@samsung.com>
 */

/**
 * Virtual List Widget for unlimited data.
 * To support more then 1,000 items, special list widget developed. 
 * Fast initialize and light DOM tree.
 * DB connection and works like DB cursor.
 * 
 * HTML Attributes:
 *
 *		data-role:	virtuallistview
 *		data-template : jQuery.template ID that populate into virtual list 
 *		data-row : Optional. Set number of <li> elements that are used for data handling. 
 *		
 *		ID : <UL> element that has "data-role=virtuallist" must have ID attribute.
 *
 * * APIs:
 *
 *		create ( {
 *				itemData: function ( idx ) { return json_obj; },
 *				numItemData: number or function () { return number; },
 *				cacheItemData: function ( minIdx, maxIdx ) {}
 *				} )
 *			: Create a virtuallist widget. At this moment, _create method is called.
 *			args : A collection of options
 *				itemData: A function that returns JSON object for given index. Mandatory.
 *				numItemData: Total number of itemData. Mandatory.
 *				cacheItemData: Virtuallist will ask itemData between minIdx and maxIdx.
 *				               Developers can implement this function for preparing data.
 *				               Optional.
 *
 * Events:
 *
 *		touchstart : Temporary preventDefault applied on touchstart event to avoid broken screen.
 *
 * Examples:
 *
 *		<script id="tmp-3-2-7" type="text/x-jquery-tmpl">
 *			<li class="ui-li-3-2-7">
 *				<span class="ui-li-text-main">${NAME}</span>
 *				<img src="00_winset_icon_favorite_on.png" class="ui-li-icon-sub">
 *				<span class="ui-li-text-sub">${ACTIVE}</span>
 *				<span class="ui-li-text-sub2">${FROM}</span>
 *			</li>
 *		</script>
 *
 *		<ul id="virtuallist-normal_3_2_7_ul" data-role="virtuallistview" data-template="tmp-3-2-7" data-dbtable="JSON_DATA" data-row="100">
 *		</ul>
 *
 */

/**
	@class VirtualList
	In the Web environment, it is challenging to display a large amount of data in a list, such as displaying a contact list of over 1000 list items. It takes time to display the entire list in HTML and the DOM manipulation is complex.

	The virtual list widget is used to display a list of unlimited data elements on the screen for better performance. This widget provides easy access to databases to retrieve and display data. Virtual lists are based on the jQuery.template plugin as described in the jQuery documentation for jQuery.template plugin.

	To add a virtual list widget to the application, use the following code:

		<script id="tmp-3-2-7" type="text/x-jquery-tmpl">
			<li class="ui-li-3-2-7">
				<span class="ui-li-text-main">${NAME}</span>
				<img src="00_winset_icon_favorite_on.png" class="ui-li-icon-sub"/>
				<span class="ui-li-text-sub">${ACTIVE}</span>
				<span class="ui-li-text-sub2">${FROM}</span>
			</li>
		</script>
		<ul id="vlist" data-role="virtuallistview" data-template="tmp-3-2-7" data-dbtable="JSON_DATA" data-row="100"></ul>
*/
/**
	@property {String} data-role
	Creates the virtual list view. The value must be set to virtuallistview.
	Only the &gt;ul&lt; element, which a id attribute defined, supports this option. Also, the vlLoadSuccess class attribute must be defined in the &gt;ul&lt; element to ensure that loading data from the database is complete.
*/
/**
	@property {String} data-template
	Defines the jQuery.template element ID.
	The jQuery.template must be defined. The template style can use rem units to support scalability.
*/
/**
	@property {Number} data-row
	Defines the number of virtual list child elements.
	The minimum value is 20 and the default value is 100. As the value gets higher, the loading time increases while the system performance improves. So you need to pick a value that provides the best performance without excessive loading time.
*/
/**
	@method create
	@param {function} itemData(index)
	: function itemData(index) returns the JSON object matched with the given index. The index value is between 0 and numItemData-1.
	@param {Number} numItemData
	: number numItemData or function numItemData() defines or returns a static number of items.
	@param {function} cacheItemData(minIndex, maxIndex)
	: function cacheItemData(minIndex, maxIndex) prepares the JSON data. This method is called before calling the itemData() method with index values between minIndex and maxIndex.
*/

(function ( $, undefined ) {

	/* Code for Virtual List Demo */
	var listCountPerPage = {},	/* Keeps track of the number of lists per page UID. This allows support for multiple nested list in the same page. https://github.com/jquery/jquery-mobile/issues/1617 */
		_NO_SCROLL = 0,					/* ENUM */
		_SCROLL_DOWN = 1,				/* ENUM */
		_SCROLL_UP = -1;					/* ENUM */

	$.widget( "tizen.virtuallistview", $.mobile.widget, {
		options: {
			theme: "s",
			countTheme: "s",
			headerTheme: "s",
			dividerTheme: "s",
			splitIcon: "arrow-r",
			splitTheme: "s",
			inset: false,
			id:	"",					/* Virtual list UL elemet's ID */
			childSelector: " li",	/* To support swipe list */
			dbtable: "",
			template : "",
			dbkey: false,			/* Data's unique Key */
			scrollview: false,
			row: 100,
			page_buf: 30,
			initSelector: ":jqmData(role='virtuallistview')"
		},

		_stylerMouseUp: function () {
			$( this ).addClass( "ui-btn-up-s" );
			$( this ).removeClass( "ui-btn-down-s" );
		},

		_stylerMouseDown: function () {
			$( this ).addClass( "ui-btn-down-s" );
			$( this ).removeClass( "ui-btn-up-s" );
		},

		_stylerMouseOver: function () {
			$( this ).toggleClass( "ui-btn-hover-s" );
		},

		_stylerMouseOut: function () {
			$( this ).toggleClass( "ui-btn-hover-s" );
			$( this ).addClass( "ui-btn-up-s" );
			$( this ).removeClass( "ui-btn-down-s" );
		},

		// ?
		// this		virtuallistview object
		// @param[in]	template	template name(string)
		_pushData: function ( template ) {
			var o = this.options,
				i,
				myTemplate = $( "#" + template ),	// Get template object
				// NOTE: o.row = # of rows handled at once. Default value is 100.
				lastIndex = ( o.row > this._numItemData ? this._numItemData : o.row ),	// last index of handled data
				htmlData;

			for ( i = 0; i < lastIndex; i++ ) {
				htmlData = myTemplate.tmpl( this._itemData( i ) );	// Make rows with template,
				$( o.id ).append( $( htmlData ).attr( 'id', o.itemIDPrefix + i ) );	// and append it to the vlist object
			}

			// After pushing data re-style virtuallist widget
			$( o.id ).trigger( "create" );
		},

		// Set children <li> elements' position
		//
		// this: virtuallist element
		// event: virtuallistview.options
		//		TODO: Why this arg name is 'event'? Not resonable.
		//		(this function is not called with event element as args!)
		_reposition: function ( event ) {
			var o,
				t = this,
				padding,
				margin;

			if ( event.data ) {
				o = event.data;
			} else {
				o = event;
			}
			if ( $( o.id + o.childSelector ).size() > 0 ) { // $("#vlistid li")
				// first child's top position
				// NOTE: the first element may not be '0'!!!
				t._title_h = $( o.id + o.childSelector + ':first' ).position().top;
				// first child's outer height (TODO: reuse selected items)
				t._line_h = $( o.id + o.childSelector + ':first' ).outerHeight();

				// container(vlist element)'s innerwidth
				t._container_w = $( o.id ).innerWidth();

				// get sum of container's left/right padding
				padding = parseInt( $( o.id + o.childSelector ).css( "padding-left" ), 10 )
					+ parseInt( $( o.id + o.childSelector ).css( "padding-right" ), 10 );

				// Add CSS to all <li> elements
				//	* absolute position
				//	* btn-up
				//	* mouse up/down/over/out styles
				$( o.id + ">" + o.childSelector )
					.addClass( "position_absolute" )
					.addClass( "ui-btn-up-s" )
					.bind( "mouseup", t._stylerMouseUp )
					.bind( "mousedown", t._stylerMouseDown )
					.bind( "mouseover", t._stylerMouseOver )
					.bind( "mouseout", t._stylerMouseOut );
			}

			// Set absolute top/left position of each <li>
			$( o.id + ">" + o.childSelector ).each( function ( index ) {
				margin = parseInt( $( this ).css( "margin-left" ), 10 )
					+ parseInt( $( this ).css( "margin-right" ), 10 );

				$( this ).css( "top", t._title_h + t._line_h * index + 'px' )
					.css( "width", t._container_w - padding - margin );
			} );

			// Set Max Listview Height
			$( o.id ).height( t._numItemData * t._line_h );
		},

		// Resize each listitem's width
		_resize: function ( event ) {
			var o,	// 'ul'
				t = this,
				li,
				padding,
				margin;

			if ( event.data ) {
				o = event.data;
			} else {
				o = event;
			}
			li = $( o ).children( o.childSelector )

			t._container_w = $( o ).width();

			padding = parseInt( li.css( "padding-left" ), 10 )
				+ parseInt( li.css( "padding-right" ), 10 );

			li.each( function ( index, obj ) {
				margin = parseInt( $( this ).css( "margin-left" ), 10 )
					+ parseInt( $( this ).css( "margin-right" ), 10 );
				$( this ).css( "width", t._container_w - padding - margin );
			} );
		},

		// New scrollmove function supporting scrollTo
		_scrollmove: function ( ev ) {
			var t = ev.data,	// vlist (JQM object)
				o = t.options,	// options
				prevTopBufLen = t._num_top_items,	// Previous(remembered) top buf length
				timerInterval = 100,
				i,
				_scrollView,
				_normalScroll;

			_scrollView = {
				viewTop: function ( ) {
					var sv = $( o.id ).parentsUntil( ".ui-page" ).find( ".ui-scrollview-view" ),
						svTrans = sv.css( "-webkit-transform" ),
						svTransVal = "0,0,0,0,0,0";
					if ( svTrans ) {
						svTransVal = svTrans.replace( /matrix\s*\((.*)\)/, "$1" );	// matrix(a,c,b,d,tx,ty)
					}
					return - parseInt( svTransVal.split(',')[5], 10 );
				}
			};
			_normalScroll = {
				viewTop: function ( ) {
					return $( window ).scrollTop( );	// TODO: - _line_h?
				}
			};
			// Get current view top position
			function viewTop ( ) {
				return o.scrollview ? _scrollView.viewTop() : _normalScroll.viewTop();
			}
			// log function for debug
			function log ( msg ) {
				var debug = false;
				if ( debug ) {
					console.log( ">>virtualllist: " + msg );
				}
			}

			// Timer interval function
			// @param[in]	vl	virtuallist object (JQM object)
			function timerMove ( vl, undefined ) {
				var cy,				// current y position
					cti,		// current top idx
					cbi,		// current bottom idx
					oti = vl._first_index,	// old top idx
					obi = vl._last_index,	// old botton idx
					dti,			// delta of top idx
					fromIdx,
					toIdx,	// index range to be moved
					delta,			// moveItem delta
					rowLen = vl.options.row,	// max. # of items handled at once
					bufSize,		// top/bottom buffer size. unit: # of items
					i;

				// subroutine: Move itemContents in i2 into i1
				function moveItemContents( vl, i1, i2 ) {
					// TODO: Find a efficient way to replace data!
					// Assumption: i1 and i2 has same children.
					var NODETYPE = { ELEMENT_NODE: 1, TEXT_NODE: 3 },
						c1,	// child item 1 (old)
						c2,	// child item 2 (new)
						newText,
						newImg,
						i;

					$( i1 ).find( ".ui-li-text-main", ".ui-li-text-sub", ".ui-li-text-sub2", "ui-btn-text" ).each( function ( index ) {
						c1 = $( this );
						newText = $( i2 ).find( ".ui-li-text-main", ".ui-li-text-sub", "ui-btn-text" ).eq( index ).text();

						$( c1 ).contents().filter( function () {
							return ( this.nodeType == NODETYPE.TEXT_NODE );
						} ).get( 0 ).data = newText;
					} );

					$( i1 ).find( "img" ).each( function ( imgIdx ) {
						var c1 = $( this );
						newImg = $( i2 ).find( "img" ).eq( imgIdx ).attr( "src" );

						$( c1 ).attr( "src", newImg );
					} );

					$( i1 ).removeData( );	// Clear old data
				}

				// subroutine: Move item
				function moveItem( vl, fromIdx, toIdx ) {
					var itemData,	// data from itemData()
						item,		// item element
						newItem,	// new item element
						tmpl;		// template

					log( ">> move item: " + fromIdx + " --> " + toIdx );

					// Find current item
					item = $( '#' + vl.options.itemIDPrefix + fromIdx );	// TODO: refactor ID generation!
					if ( ! item || ! item.length ) {
						return false;
					}

					// Get new item
					tmpl = $( "#" + vl.options.template );
					if ( tmpl ) {
						newItem = tmpl.tmpl( vl._itemData( toIdx ) );

						// TODO: Consider touch block while moving?

						// Move item contents
						moveItemContents( vl, item, newItem );

						// clean up temporary item
						newItem.remove();
					}

					// Move position, and set id
					item.css( 'top', toIdx * vl._line_h )
						.attr( 'id' , vl.options.itemIDPrefix + toIdx );	// TODO: refactor ID generation!

					// TODO: Apply jqmdata? check following old code;
					// $( oldItem ).removeData( );	// Clear old data
					// if (key) { $( oldItem ).data( key, $( newItem ).data( key ) ); }

					return true;
				}


				// Get current view position
				cy = viewTop();

				// Calculate bufSize: rowLen / 3
				// NOTE: Assumption: total row length = visible items * 3 (upper+visible+lower)
				bufSize = Math.ceil( rowLen / 3 );

				// Calculate current top/bottom index (to be applied)
				// top index = current position / line height
				cti = Math.floor( cy / vl._line_h ) - bufSize;	// TODO: consider buffer!
				cbi = cti + rowLen - 1;

				if ( cti < 0 ) {		// Top boundary check
					cbi += ( - cti );
					cti = 0;
				} else if ( cbi > ( vl._numItemData - 1 ) ) {		// Bottom boundary check
					cti -= ( cbi - ( vl._numItemData - 1 ) );
					cbi = ( vl._numItemData - 1 );
				}

				// Calculate dti
				dti = cti - oti;
				log( "cy=" + cy + ", oti=" + oti + ", obi=" + obi + ", cti=" + cti + ", cbi=" + cbi + ", dti=" + dti );

				// switch: dti = 0 --> timer stop condition: delta=0 or scrollstop event comes. END.
				if ( 0 == dti ) {
					// Check timer runtime
					vl.timerStillCount += 1;
					if ( vl.timerStillCount < 12 ) {	// check count ( TODO: test and adjust )
						log("dti=0 " + vl.timerStillCount + " times");
						vl.timerMoveID = setTimeout( timerMove, timerInterval, vl );	// run once more
						return;
					}

					log("dti=0 " + vl.timerStillCount + " times. End timer.");
					vl.timerStillCount = 0;
					// Stop timer
					if ( vl.timerMoveID ) {
						clearTimeout( vl.timerMoveID );
						vl.timerMoveID = null;
					}
				} else {
					// switch: dti >= # of max elements --> total replace.
					vl.timerStillCount = 0;		// Reset still counter

					if ( Math.abs( dti ) >= rowLen ) {
						fromIdx = oti;
						toIdx = obi;
						delta = dti;
						log( ">>> WHOLE CHANGE! delta=" + delta );
					} else {
						// switch: dti < # of max elements --> move t2b or b2t until new top/bottom idx is covered
						if ( dti > 0 ) {
							fromIdx = oti;
							toIdx = oti + dti - 1;
							delta = rowLen;
						} else {
							fromIdx = obi + dti + 1;	// dti < 0
							toIdx = obi;
							delta = -rowLen;
						}
						log( ">>> partial change. delta=" + delta );
					}

					// Move items
					for ( i = fromIdx; i <= toIdx; i++ ) {
						moveItem( vl, i, i + delta );		// Change data and position
					}

					// Store current top/bottom idx into vl
					vl._first_index = cti;
					vl._last_index = cbi;

					// Register timer to check again
					vl.timerMoveID = setTimeout( timerMove, timerInterval, vl );
				}
				return;	// End of function
			}

			// ==== function start ====

			t.timerStillCount = 0;	// Count do-nothing time.	For behavior tuning.

			// If a timer function is alive, clear it
			if ( t.timerMoveID ) {
				clearTimeout( t.timerMoveID );
				t.timerMoveID = null;
			}
			// run TimerMove()
			timerMove( t );
		},

		_recreate: function ( newArray ) {
			var t = this,
				o = this.options;

			$( o.id ).empty();

			t._numItemData = newArray.length;
			t._direction = _NO_SCROLL;
			t._first_index = 0;
			t._last_index = o.row - 1;

			t._pushData( o.template );

			if (o.childSelector == " ul" ) {
				$( o.id + " ul" ).swipelist();
			}

			$( o.id ).virtuallistview();

			t.refresh( true );

			t._reposition( o );
		},

		// Init virtuallistview
		// this		virtuallistview object
		_initList: function () {
			var t = this,
				o = this.options;

			/* After AJAX loading success */

			// Put initial <li> elements
			t._pushData( o.template );

			// find a parent page, and run _reposition() at 'pageshow' event
			// TODO: Consider replace parentsUntil().parent() to parent('.ui-page') ???
			$( o.id ).parentsUntil( ".ui-page" ).parent().one( "pageshow", function () {
				setTimeout( function () {
					t._reposition( o );
				}, 0);
			});

			// Bind _scrollmove() at 'scrollstart.virtuallist' event
			$( document ).bind( "scrollstart.virtuallist scrollstop.vrituallist", t, t._scrollmove );

			// Bind _resize()
			$( window ).on( "throttledresize", $( o.id ), t._resize );

			// when ul is a childselector, assume that this is also a swipelist,
			// and run swipelist constructor
			if ( o.childSelector == " ul" ) {
				$( o.id + " ul" ).swipelist();
			}

			t.refresh( true );
		},

		create: function () {
			var o = this.options;

			/* external API for AJAX callback */
			this._create.apply( this, arguments );

			// TODO: remove this line? _initList() calls reposition...
			this._reposition( o );
		},

		_create: function ( args ) {
			// Extend instance variables
			$.extend( this, {
				_itemData : function ( idx ) { return null; },
				_numItemData : 0,
				_cacheItemData : function ( minIdx, maxIdx ) { },
				_title_h : 0,
				_container_w : 0,
				_minimum_row : 100,
				_direction : _NO_SCROLL,
				_first_index : 0,
				_last_index : 0,
				_num_top_items : 0	// By scroll move, number of hidden elements.
			} );

			// local variables
			var t = this,
				o = this.options,
				$el = this.element,
				shortcutsContainer = $('<div class="ui-virtuallist"/>'),
				shortcutsList = $('<ul></ul>'),
				dividers = $el.find(':jqmData(role="virtuallistview" )'),
				lastListItem = null,
				shortcutscroll = this,
				dbtable_name,
				dbtable;


			// Add CSS classes to $el (=virtuallistview)
			$el.addClass( function ( i, orig ) {
				return orig + " ui-listview ui-virtual-list-container" + ( t.options.inset ? " ui-listview-inset ui-corner-all ui-shadow " : "" );
			});

			// keep the vlist's ID
			o.itemIDPrefix = $el.attr( "id" ) + '_';
			o.id = "#" + $el.attr( "id" );

			// when page hides, empty all child elements
			$( o.id ).bind( "pagehide", function ( e ) {
				$( o.id ).empty();
			});

			// Find if scrollview is used
			if ( $( ".ui-scrollview-clip" ).size() > 0 ) {
				o.scrollview = true;
			} else {
				o.scrollview = false;
			}

			// Calculate page buffer size
			if ( $el.data( "row" ) ) {
				o.row = $el.data( "row" );

				if ( o.row < t._minimum_row ) {
					o.row = t._minimum_row;
				}

				o.page_buf = parseInt( ( o.row / 2 ), 10 );
			}

			// Get arguments
			if ( args ) {
				if ( args.itemData && typeof args.itemData == 'function'  ) {
					t._itemData = args.itemData;
				} else {
					return;
				}
				if ( args.numItemData ) {
					if ( typeof args.numItemData == 'function' ) {
						t._numItemData = args.numItemData( );
					} else if ( typeof args.numItemData == 'number' ) {
						t._numItemData = args.numItemData;
					} else {
						return;
					}
				} else {
					return;
				}
			} else {	// No option is given
				// Legacy support: dbtable
				console.warn( "WARNING: The data interface of virtuallist is changed. \nOld data interface(data-dbtable) is still supported, but will be removed in next version. \nPlease fix your code soon!" );

				/* After DB Load complete, Init Vritual list */
				if ( $( o.id ).hasClass( "vlLoadSuccess" ) ) {
					dbtable_name = $el.jqmData('dbtable');
					dbtable = window[ dbtable_name ];

					$( o.id ).empty();

					if ( !dbtable ) {
						dbtable = { };
					}

					t._itemData = function ( idx ) {
						return dbtable[ idx ];
					};
					t._numItemData = dbtable.length;
				} else {
					return;	// Do nothing
				}
			}

			// Get template data
			if ( $el.data( "template" ) ) {
				o.template = $el.data( "template" );

				/* to support swipe list, <li> or <ul> can be main node of virtual list. */
				if ( $el.data( "swipelist" ) == true ) {
					o.childSelector = " ul";
				} else {
					o.childSelector = " li";
				}
			}

			// Set data's unique key
			// NOTE: Unnecessary?
			if ( $el.data( "dbkey" ) ) {
				o.dbkey = $el.data( "dbkey" );
			}

			t._first_index = 0;			// initial top idx of <li> element.
			t._last_index = o.row - 1;		// initial bottom idx of <li> element.
			t._initList();	// NOTE: Called at here only!
		},

		destroy : function () {
			var o = this.options;

			$( document ).unbind( "scrollstop" );

			$( window ).off( "throttledresize", this._resize );

			$( o.id ).empty();

			if ( this.timerMoveID ) {
				clearTimeout( this.timerMoveID );
				this.timerMoveID = null;
			}
		},

		_itemApply: function ( $list, item ) {
			var $countli = item.find( ".ui-li-count" );

			if ( $countli.length ) {
				item.addClass( "ui-li-has-count" );
			}

			$countli.addClass( "ui-btn-up-" + ( $list.jqmData( "counttheme" ) || this.options.countTheme ) + " ui-btn-corner-all" );

			// TODO class has to be defined in markup
			item.find( "h1, h2, h3, h4, h5, h6" ).addClass( "ui-li-heading" ).end()
				.find( "p, dl" ).addClass( "ui-li-desc" ).end()
				.find( ">img:eq(0), .ui-link-inherit>img:eq(0)" ).addClass( "ui-li-thumb" ).each( function () {
					item.addClass( $( this ).is( ".ui-li-icon" ) ? "ui-li-has-icon" : "ui-li-has-thumb" );
				}).end()
				.find( ".ui-li-aside" ).each(function () {
					var $this = $( this );
					$this.prependTo( $this.parent() ); //shift aside to front for css float
				} );
		},

		_removeCorners: function ( li, which ) {
			var top = "ui-corner-top ui-corner-tr ui-corner-tl",
				bot = "ui-corner-bottom ui-corner-br ui-corner-bl";

			li = li.add( li.find( ".ui-btn-inner, .ui-li-link-alt, .ui-li-thumb" ) );

			if ( which === "top" ) {
				li.removeClass( top );
			} else if ( which === "bottom" ) {
				li.removeClass( bot );
			} else {
				li.removeClass( top + " " + bot );
			}
		},

		_refreshCorners: function ( create ) {
			var $li,
				$visibleli,
				$topli,
				$bottomli;

			if ( this.options.inset ) {
				$li = this.element.children( "li" );
				// at create time the li are not visible yet so we need to rely on .ui-screen-hidden
				$visibleli = create ? $li.not( ".ui-screen-hidden" ) : $li.filter( ":visible" );

				this._removeCorners( $li );

				// Select the first visible li element
				$topli = $visibleli.first()
					.addClass( "ui-corner-top" );

				$topli.add( $topli.find( ".ui-btn-inner" ) )
					.find( ".ui-li-link-alt" )
						.addClass( "ui-corner-tr" )
					.end()
					.find( ".ui-li-thumb" )
						.not( ".ui-li-icon" )
						.addClass( "ui-corner-tl" );

				// Select the last visible li element
				$bottomli = $visibleli.last()
					.addClass( "ui-corner-bottom" );

				$bottomli.add( $bottomli.find( ".ui-btn-inner" ) )
					.find( ".ui-li-link-alt" )
						.addClass( "ui-corner-br" )
					.end()
					.find( ".ui-li-thumb" )
						.not( ".ui-li-icon" )
						.addClass( "ui-corner-bl" );
			}
			this.element.trigger( "updatelayout" );
		},

		// this		virtuallistview object
		refresh: function ( create ) {
			this.parentPage = this.element.closest( ".ui-page" );
			// Make sub page, and move the virtuallist into it...
			// NOTE: check this subroutine.
			this._createSubPages();

			var o = this.options,
				$list = this.element,
				self = this,
				dividertheme = $list.jqmData( "dividertheme" ) || o.dividerTheme,
				listsplittheme = $list.jqmData( "splittheme" ),
				listspliticon = $list.jqmData( "spliticon" ),
				li = $list.children( "li" ),
				counter = $.support.cssPseudoElement || !$.nodeName( $list[ 0 ], "ol" ) ? 0 : 1,
				item,
				itemClass,
				temTheme,
				a,
				last,
				splittheme,
				countParent,
				icon,
				pos,
				numli,
				itemTheme;

			// TODO: ?
			if ( counter ) {
				$list.find( ".ui-li-dec" ).remove();
			}

			for ( pos = 0, numli = li.length; pos < numli; pos++ ) {
				item = li.eq( pos );
				itemClass = "ui-li";

				// If we're creating the element, we update it regardless
				if ( create || !item.hasClass( "ui-li" ) ) {
					itemTheme = item.jqmData( "theme" ) || o.theme;
					a = item.children( "a" );

					if ( a.length ) {
						icon = item.jqmData( "icon" );

						item.buttonMarkup({
							wrapperEls: "div",
							shadow: false,
							corners: false,
							iconpos: "right",
							/* icon: a.length > 1 || icon === false ? false : icon || "arrow-r",*/
							icon: false,	/* Remove unnecessary arrow icon */
							theme: itemTheme
						});

						if ( ( icon != false ) && ( a.length == 1 ) ) {
							item.addClass( "ui-li-has-arrow" );
						}

						a.first().addClass( "ui-link-inherit" );

						if ( a.length > 1 ) {
							itemClass += " ui-li-has-alt";

							last = a.last();
							splittheme = listsplittheme || last.jqmData( "theme" ) || o.splitTheme;

							last.appendTo(item)
								.attr( "title", last.getEncodedText() )
								.addClass( "ui-li-link-alt" )
								.empty()
								.buttonMarkup({
									shadow: false,
									corners: false,
									theme: itemTheme,
									icon: false,
									iconpos: false
								})
								.find( ".ui-btn-inner" )
								.append(
									$( "<span />" ).buttonMarkup({
										shadow: true,
										corners: true,
										theme: splittheme,
										iconpos: "notext",
										icon: listspliticon || last.jqmData( "icon" ) || o.splitIcon
									})
								);
						}
					} else if ( item.jqmData( "role" ) === "list-divider" ) {

						itemClass += " ui-li-divider ui-btn ui-bar-" + dividertheme;
						item.attr( "role", "heading" );

						//reset counter when a divider heading is encountered
						if ( counter ) {
							counter = 1;
						}

					} else {
						itemClass += " ui-li-static ui-body-" + itemTheme;
					}
				}

				if ( counter && itemClass.indexOf( "ui-li-divider" ) < 0 ) {
					countParent = item.is( ".ui-li-static:first" ) ? item : item.find( ".ui-link-inherit" );

					countParent.addClass( "ui-li-jsnumbering" )
						.prepend( "<span class='ui-li-dec'>" + (counter++) + ". </span>" );
				}

				item.add( item.children( ".ui-btn-inner" ) ).addClass( itemClass );

				self._itemApply( $list, item );
			}

			this._refreshCorners( create );
		},

		//create a string for ID/subpage url creation
		_idStringEscape: function ( str ) {
			return str.replace(/\W/g , "-");
		},

		// ?
		// this		virtuallistview object
		_createSubPages: function () {
			var parentList = this.element,
				parentPage = parentList.closest( ".ui-page" ),
				parentUrl = parentPage.jqmData( "url" ),
				parentId = parentUrl || parentPage[ 0 ][ $.expando ],
				parentListId = parentList.attr( "id" ),
				o = this.options,
				dns = "data-" + $.mobile.ns,
				self = this,
				persistentFooterID = parentPage.find( ":jqmData(role='footer')" ).jqmData( "id" ),
				hasSubPages,
				newRemove;

			if ( typeof listCountPerPage[ parentId ] === "undefined" ) {
				listCountPerPage[ parentId ] = -1;
			}

			parentListId = parentListId || ++listCountPerPage[ parentId ];

			$( parentList.find( "li>ul, li>ol" ).toArray().reverse() ).each(function ( i ) {
				var self = this,
					list = $( this ),
					listId = list.attr( "id" ) || parentListId + "-" + i,
					parent = list.parent(),
					nodeEls,
					title = nodeEls.first().getEncodedText(),//url limits to first 30 chars of text
					id = ( parentUrl || "" ) + "&" + $.mobile.subPageUrlKey + "=" + listId,
					theme = list.jqmData( "theme" ) || o.theme,
					countTheme = list.jqmData( "counttheme" ) || parentList.jqmData( "counttheme" ) || o.countTheme,
					newPage,
					anchor;

				nodeEls = $( list.prevAll().toArray().reverse() );
				nodeEls = nodeEls.length ? nodeEls : $( "<span>" + $.trim( parent.contents()[ 0 ].nodeValue ) + "</span>" );

				//define hasSubPages for use in later removal
				hasSubPages = true;

				newPage = list.detach()
							.wrap( "<div " + dns + "role='page' " +	dns + "url='" + id + "' " + dns + "theme='" + theme + "' " + dns + "count-theme='" + countTheme + "'><div " + dns + "role='content'></div></div>" )
							.parent()
								.before( "<div " + dns + "role='header' " + dns + "theme='" + o.headerTheme + "'><div class='ui-title'>" + title + "</div></div>" )
								.after( persistentFooterID ? $( "<div " + dns + "role='footer' " + dns + "id='" + persistentFooterID + "'>" ) : "" )
								.parent()
								.appendTo( $.mobile.pageContainer );

				newPage.page();

				anchor = parent.find('a:first');

				if ( !anchor.length ) {
					anchor = $( "<a/>" ).html( nodeEls || title ).prependTo( parent.empty() );
				}

				anchor.attr( "href", "#" + id );

			}).virtuallistview();

			// on pagehide, remove any nested pages along with the parent page, as long as they aren't active
			// and aren't embedded
			if ( hasSubPages &&
						parentPage.is( ":jqmData(external-page='true')" ) &&
						parentPage.data( "page" ).options.domCache === false ) {

				newRemove = function ( e, ui ) {
					var nextPage = ui.nextPage, npURL;

					if ( ui.nextPage ) {
						npURL = nextPage.jqmData( "url" );
						if ( npURL.indexOf( parentUrl + "&" + $.mobile.subPageUrlKey ) !== 0 ) {
							self.childPages().remove();
							parentPage.remove();
						}
					}
				};

				// unbind the original page remove and replace with our specialized version
				parentPage
					.unbind( "pagehide.remove" )
					.bind( "pagehide.remove", newRemove );
			}
		},

		// TODO sort out a better way to track sub pages of the virtuallistview this is brittle
		childPages: function () {
			var parentUrl = this.parentPage.jqmData( "url" );

			return $( ":jqmData(url^='" +  parentUrl + "&" + $.mobile.subPageUrlKey + "')" );
		}
	});

	//auto self-init widgets
	$( document ).bind( "pagecreate create", function ( e ) {
		$( $.tizen.virtuallistview.prototype.options.initSelector, e.target ).virtuallistview();
	});

} ( jQuery ) );



/**
 * @class core
 * loader.js
 *
 * Youmin Ha <youmin.ha@samsung.com>
 *
 *
 */
/*
	Web UI scaling concept in Tizen Web UI

Generally, web applications must be designed to be showed acceptable on various size and resolution of screens, and web winsets have to be scaled well.  Tizen Web UI Framework supports various viewport settings, and Tizen Web UI widgets are designed to be scalable on various screen sizes.  In order to make web applications scalable on many devices which have different screen size, it is necessary to understand how mobile web browsers deal with screen resolution, and how Tizen Web UI Framework supports scaling for web applications.


* Viewport on mobile web browser

Viewport is an area showing web content on the browser.  Unlike desktop browsers, mobile browsers support logical viewport seting, which means that application can set viewport width/height and zoom level by itself.
The very important thing that to be remembered is that the viewport resolution in pixel is 'Logical', not physical.  For example, if the viewport width is set to 480 on a mobile device having 720px screen width, the viewport width is considered to 480px logically. All elements put on right side from 480px horizontal position will not be shown on the viewport.
Most mobile browsers set viewport with given content attribute with <meta name="viewport" content="..."> tag in <head> section in the application source html, whereas desktop browsers ignore the tag.
Detailed usage of viewport meta tag is found in here: http://www.w3.org/TR/mwabp/#bp-viewport


* Viewport setting by application developers

When developers write <meta name="viewport" content="..."> in the <head> section of the web application HTML file, Tizen Web UI Framework does not add another viewport meta tag, nor modify developer-defined viewport.


* Automatic viewport setting by Tizen Web UI Framework

If developers do not give a viewport meta tag, Tizen Web UI Framework automatically add a viewport meta tag with default viewport setting.


* Portrait/landscape mode


* Tizen Web UI widgets scaling


 */
( function ($, Globalize, window, undefined) {

	var tizen = {
		libFileName : "tizen-web-ui-fw(.custom|.full)?(.min)?.js",

		frameworkData : {
			rootDir: '/usr/share/tizen-web-ui-fw',
			version: '0.2',
			theme: "tizen-black",
			viewportWidth: "device-width",
			viewportScale: false,

			defaultFontSize: 22,
			minified: false,
			deviceCapa: { inputKeyBack: true, inputKeyMenu: true },
			debug: false
		},

		log : {
			debug : function ( msg ) {
				if ( tizen.frameworkData.debug ) {
					console.log( msg );
				}
			},
			warn : function ( msg ) {
				console.warn( msg );
			},
			error : function ( msg ) {
				console.error( msg );
			},
			alert : function ( msg ) {
				window.alert( msg );
			}
		},

		util : {

			loadScriptSync : function ( scriptPath, successCB, errorCB ) {
				$.ajax( {
					url: scriptPath,
					dataType: 'script',
					async: false,
					crossDomain: false,
					success: successCB,
					error: function ( jqXHR, textStatus, errorThrown ) {
						if ( errorCB ) {
							errorCB( jqXHR, textStatus, errorThrown );
						} else {
							var ignoreStatusList = [ 404 ],  // 404: not found
								errmsg = ( 'Error while loading ' + scriptPath + '\n' + jqXHR.status + ':' + jqXHR.statusText );
							if ( -1 == $.inArray( jqXHR.status, ignoreStatusList ) ) {
								tizen.log.alert( errmsg );
							} else {
								tizen.log.warn( errmsg );
							}
						}
					}
				} );
			},
			isMobileBrowser: function ( ) {
				var mobileIdx = window.navigator.appVersion.indexOf("Mobile"),
					isMobile = -1 < mobileIdx;
				return isMobile;
			}
		},

		css : {
			cacheBust: ( document.location.href.match( /debug=true/ ) ) ?
					'?cacheBust=' + ( new Date( ) ).getTime( ) :
					'',
			addElementToHead : function ( elem ) {
				var head = document.getElementsByTagName( 'head' )[0];
				if ( head ) {
					$( head ).prepend( elem );
				}
			},
			makeLink : function ( href ) {
				var cssLink = document.createElement( 'link' );
				cssLink.setAttribute( 'rel', 'stylesheet' );
				cssLink.setAttribute( 'href', href );
				cssLink.setAttribute( 'name', 'tizen-theme' );
				return cssLink;
			},
			load: function ( path ) {
				var head = document.getElementsByTagName( 'head' )[0],
					cssLinks = head.getElementsByTagName( 'link' ),
					idx,
					l = null;
				// Find css link element
				for ( idx = 0; idx < cssLinks.length; idx++ ) {
					if ( cssLinks[idx].getAttribute( 'rel' ) != "stylesheet" ) {
						continue;
					}
					if ( cssLinks[idx].getAttribute( 'name' ) == "tizen-theme"
							|| cssLinks[idx].getAttribute( 'href' ) == path ) {
						l = cssLinks[idx];
						break;
					}
				}
				if ( l ) {	// Found the link element!
					if ( l.getAttribute( 'href' ) == path ) {
						tizen.log.debug( "Theme is already loaded. Skip theme loading in the framework." );
					} else {
						l.setAttribute( 'href', path );
					}
				} else {
					this.addElementToHead( this.makeLink( path ) );
				}
			}
		},

		getParams: function ( ) {
			/* Get data-* params from <script> tag, and set tizen.frameworkData.* values
			 * Returns true if proper <script> tag is found, or false if not.
			 */
			// Find current <script> tag element
			var scriptElems = document.getElementsByTagName( 'script' ),
				val = null,
				foundScriptTag = false,
				idx,
				elem,
				src,
				tokens,
				version_idx;
/*
			function getTizenTheme( ) {
				var t = navigator.theme ? navigator.theme.split( ':' )[0] : null;
				if ( t ) {
					t = t.replace('-hd', '');
					if ( ! t.match( /^tizen-/ ) ) {
						t = 'tizen-' + t;
					}
				}
				return t;
			}
*/
			for ( idx in scriptElems ) {
				elem = scriptElems[idx];
				src = elem.src ? elem.getAttribute( 'src' ) : undefined;
				if (src && src.match( this.libFileName )) {
					// Set framework data, only when they are given.
					tokens = src.split(/[\/\\]/);
					version_idx = -3;
					this.frameworkData.rootDir = ( elem.getAttribute( 'data-framework-root' )
						|| tokens.slice( 0, tokens.length + version_idx ).join( '/' )
						|| this.frameworkData.rootDir ).replace( /^file:(\/\/)?/, '' );
					this.frameworkData.version = elem.getAttribute( 'data-framework-version' )
						|| tokens[ tokens.length + version_idx ]
						|| this.frameworkData.version;
					this.frameworkData.theme = elem.getAttribute( 'data-framework-theme' )
						//|| getTizenTheme( )
						|| this.frameworkData.theme;
					this.frameworkData.viewportWidth = elem.getAttribute( 'data-framework-viewport-width' )
						|| this.frameworkData.viewportWidth;
					this.frameworkData.viewportScale =
						"true" === elem.getAttribute( 'data-framework-viewport-scale' ) ? true
						: this.frameworkData.viewportScale;
					this.frameworkData.minified = src.search(/\.min\.js$/) > -1 ? true : false;
					this.frameworkData.debug = "true" === elem.getAttribute( 'data-framework-debug' ) ? true
						: this.frameworkData.debug;
					foundScriptTag = true;
					break;
				}
			}
			return foundScriptTag;
		},

		loadTheme: function ( theme ) {
			var themePath,
			cssPath,
			jsPath;

			if ( ! theme ) {
				theme = tizen.frameworkData.theme;
			}
			
			themePath = tizen.frameworkData.rootDir + '/' + tizen.frameworkData.version + '/themes/' + theme;
			
			jsPath = themePath + '/theme.js';
	
			if ( tizen.frameworkData.minified ) {
				cssPath = themePath + '/tizen-web-ui-fw-theme.min.css';
			} else {
				cssPath = themePath + '/tizen-web-ui-fw-theme.css';
			}
			tizen.css.load( cssPath );
			tizen.util.loadScriptSync( jsPath );
		},

		/** Load Globalize culture file, and set default culture.
		 *  @param[in]  language  (optional) Language code. ex) en-US, en, ko-KR, ko
		 *                        If language is not given, read language from html 'lang' attribute, 
		 *                        or from system setting.
		 *  @param[in]  cultureDic (optional) Dictionary having language code->
		 */
		loadGlobalizeCulture: function ( language, cultureDic ) {
			var self = this,
				cFPath,
				lang,
				mockJSXHR;

			function getLang ( language ) {
				var lang = language
						|| $( 'html' ).attr( 'lang' )
						|| window.navigator.language.split( '.' )[0]	// Webkit, Safari + workaround for Tizen
						|| window.navigator.userLanguage	// IE
						|| 'en',
					countryCode = null,
					countryCodeIdx = lang.lastIndexOf('-'),
					ignoreCodes = ['Cyrl', 'Latn', 'Mong'];	// Not country code!
				if ( countryCodeIdx != -1 ) {	// Found country code!
					countryCode = lang.substr( countryCodeIdx + 1 );
					if ( ignoreCodes.join( '-' ).indexOf( countryCode ) < 0 ) {
						// countryCode is not found from ignoreCodes.
						// Make countryCode to uppercase.
						lang = [ lang.substr( 0, countryCodeIdx ), countryCode.toUpperCase( ) ].join( '-' );
					}
				}
				// NOTE: 'en' to 'en-US', because globalize has no 'en' culture file.
				lang = lang == 'en' ? 'en-US' : lang;
				return lang;
			}

			function getNeutralLang ( lang ) {
				var neutralLangIdx = lang.lastIndexOf( '-' ),
					neutralLang;
				if ( neutralLangIdx != -1 ) {
					neutralLang = lang.substr( 0, neutralLangIdx );
				}
				return neutralLang;
			}

			function getCultureFilePath ( lang, cFDic ) {
				var cFPath = null;	// error value

				if ( "string" != typeof lang ) {
					return null;
				}
				if ( cFDic && cFDic[lang] ) {
					cFPath = cFDic[lang];
				} else {
					// Default Globalize culture file path
					cFPath = [
						self.frameworkData.rootDir,
						self.frameworkData.version,
						'js',
						'cultures',
						['globalize.culture.', lang, '.js'].join( '' )
					].join( '/' );
				}
				return cFPath;
			}

			function printLoadError( cFPath, jqXHR ) {
				tizen.log.error( "Error " + jqXHR.status + ": " + jqXHR.statusText
						+ "::Culture file (" + cFPath + ") is failed to load.");
			}

			function loadCultureFile ( cFPath, errCB ) {
				function _successCB ( ) {
					tizen.log.debug( "Culture file (" + cFPath + ") is loaded successfully." );
				}
				function _errCB ( jqXHR, textStatus, err ) {
					if ( errCB ) {
						errCB( jqXHR, textStatus, err );
					} else {
						printLoadError( cFPath, jqXHR );
					}
				}

				if ( ! cFPath ) {	// Invalid cFPath -> Regard it as '404 Not Found' error.
					mockJSXHR = {
						status: 404,
						statusText: "Not Found"
					};
					_errCB( mockJSXHR, null, null );
				} else {
					$.ajax( {
						url: cFPath,
						dataType: 'script',
						cache: true,
						async: false,
						success: _successCB,
						error: _errCB
					} );
				}
			}

			lang = getLang( language );
			cFPath = getCultureFilePath( lang, cultureDic );
			loadCultureFile( cFPath,
				function ( jqXHR, textStatus, err ) {
					if ( jqXHR.status == 404 ) {
						// If culture file is not found, try once more with neutral lang.
						var nLang = getNeutralLang( lang ),
							ncFPath = getCultureFilePath( nLang, cultureDic );
						loadCultureFile( ncFPath, null );
					} else {
						printLoadError( cFPath, jqXHR );
					}
				} );

			return lang;
		},
		setGlobalize: function ( ) {
			var lang = this.loadGlobalizeCulture( );

			// Set culture
			// NOTE: It is not needed to set with neutral lang.
			//       Globalize automatically deals with it.
			Globalize.culture( lang );
		},
		/**
		 * Load custom globalize culture file
		 * Find current system language, and load appropriate culture file from given colture file list.
		 *
		 * @param[in]	cultureDic	collection of 'language':'culture file path' key-val pair.
		 * @example
		 * var myCultures = {
		 *	"en"    : "culture/en.js",
		 *	"fr"    : "culture/fr.js",
		 *	"ko-KR" : "culture/ko-KR.js"
		 * };
		 * loadCultomGlobalizeCulture( myCultures );
		 *
		 * ex) culture/fr.js
		 * -------------------------------
		 * Globalize.addCultureInfo( "fr", {
		 *   messages: {
		 *     "hello" : "bonjour",
		 *     "translate" : "traduire"
		 *   }
		 * } );
		 * -------------------------------
		 */
		loadCustomGlobalizeCulture: function ( cultureDic ) {
			tizen.loadGlobalizeCulture( null, cultureDic );
		},

		/** Set viewport meta tag for mobile devices.
		 *
		 * @param[in]	viewportWidth	viewport width. "device-width" is OK.
		 */
		setViewport: function ( viewportWidth ) {
			var meta = null,
				head,
				content;

			// Do nothing if viewport setting code is already in the code.
			$( "meta[name=viewport]" ).each( function ( ) {
				meta = this;
				return;
			});
			if ( meta ) {	// Found custom viewport!
				content = $( meta ).prop( "content" );
				viewportWidth = content.replace( /.*width=(device-width|\d+)\s*,?.*$/gi, "$1" );
				tizen.log.debug( "Viewport is set to '" + viewportWidth + "' in a meta tag. Framework skips viewport setting." );
			} else {
				// Create a meta tag
				meta = document.createElement( "meta" );
				if ( meta ) {
					meta.name = "viewport";
					content = "width=" + viewportWidth + ", user-scalable=no";
					if ( ! isNaN( viewportWidth ) ) {
						// Fix scale to 1.0, if viewport width is set to fixed value.
						// NOTE: Works wrong in Tizen browser!
						//content = [ content, ", initial-scale=1.0, maximum-scale=1.0" ].join( "" );
					}
					meta.content = content;
					tizen.log.debug( content );
					head = document.getElementsByTagName( 'head' ).item( 0 );
					head.insertBefore( meta, head.firstChild );
				}
			}
			return viewportWidth;
		},

		/**	Read body's font-size, scale it, and reset it.
		 *  param[in]	desired font-size / base font-size.
		 */
		scaleBaseFontSize: function ( themeDefaultFontSize, ratio ) {
			tizen.log.debug( "themedefaultfont size: " + themeDefaultFontSize + ", ratio: " + ratio );
			var scaledFontSize = Math.max( Math.floor( themeDefaultFontSize * ratio ), 4 );

			$( 'html' ).css( { 'font-size': scaledFontSize + "px" } );
			tizen.log.debug( 'html:font size is set to ' + scaledFontSize );
			$( document ).ready( function ( ) {
				$( '.ui-mobile' ).children( 'body' ).css( { 'font-size': scaledFontSize + "px" } );
			} );
		},

		setScaling: function ( ) {
			var viewportWidth = this.frameworkData.viewportWidth,
				themeDefaultFontSize = this.frameworkData.defaultFontSize, // comes from theme.js
				ratio = 1;

			// Keep original font size
			$( 'body' ).attr( 'data-tizen-theme-default-font-size', themeDefaultFontSize );

			if ( !tizen.util.isMobileBrowser() ) {
				return;
			}

			// Legacy support: tizen.frameworkData.viewportScale
			if ( this.frameworkData.viewportScale == true ) {
				viewportWidth = "screen-width";
			}

			// screen-width support
			if ( "screen-width" == viewportWidth ) {
				if ( window.self == window.top ) {
					// Top frame: for target. Use window.outerWidth.
					viewportWidth = window.outerWidth;
				} else {
					// iframe: for web simulator. Use clientWidth.
					viewportWidth = document.documentElement.clientWidth;
				}
			}

			// set viewport meta tag
			viewportWidth = this.setViewport( viewportWidth );	// If custom viewport setting exists, get viewport width

			if ( viewportWidth == "device-width" ) {
				// Do nothing!
			} else {	// fixed width!
				ratio = parseFloat( viewportWidth / this.frameworkData.defaultViewportWidth );
				this.scaleBaseFontSize( themeDefaultFontSize, ratio );
			}
		}
	};

	function export2TizenNS ( $, tizen ) {
		if ( !$.tizen ) {
			$.tizen = { };
		}

		$.tizen.frameworkData = tizen.frameworkData;
		$.tizen.loadCustomGlobalizeCulture = tizen.loadCustomGlobalizeCulture;
		$.tizen.loadTheme = tizen.loadTheme;

		$.tizen.__tizen__ = tizen;	// for unit-test
	}

	export2TizenNS( $, tizen );

	tizen.getParams( );
	tizen.loadTheme( );
	tizen.setScaling( );	// Run after loadTheme(), for the default font size.
	tizen.setGlobalize( );
	// Turn off JQM's auto initialization option.
	// NOTE: This job must be done before domready.
	$.mobile.autoInitializePage = false;

	$(document).ready( function ( ) {
		$.mobile.initializePage( );
	});

} ( jQuery, Globalize, window ) );



/* ***************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 *
 *	Author: Minkyu Kang <mk7.kang@samsung.com>
 */

/*
 * Notification widget
 *
 * HTML Attributes
 *
 *  data-role: set to 'notification'.
 *  data-type: 'ticker' or 'popup'.
 *  data-interval: time to showing. If don't set, will show infinitely.
 *
 * APIs
 *
 *  open(): open the notification.
 *  close(): close the notification.
 *  text(text0, text1): set texts or get texts
 *  icon(src): set the icon (tickernoti only)
 *
 * Events
 *
 *  N/A
 *
 * Examples
 *
 * // tickernoti
 * <div data-role="notification" id="notification" data-type="ticker" data-interval="3000">
 *	<img src="icon01.png">
 *	<p>Hello World</p>
 *	<p>Denis</p>
 * </div>
 *
 * // smallpopup
 * <div data-role="notification" id="notification" data-type="popup" data-interval="3000">
 *	<p>Hello World</p>
 * </div>
 *
 */

/**
	@class Notification
	The notification widget shows a pop-up window on the screen to provide notifications.
	To add a notification widget to the application, use the following code:

		<div data-role="page">
			<div data-role="notification" data-type="smallpopup">
				<p>text1</p>
			</div>
			<div data-role="header"></div>
			<div data-role="content"></div>
			<div data-role="footer"></div>
		</div>
*/
/**
	@property {String} data-type
	Defines the notification type. The type options are tickernoti and smallpopup. <br/>The default value is smallpopup.

*/
/**
	@property {Integer} data-interval
	Defines the time to showing a notification widget. <br/>The default is infinitely.

*/
/**
	@method open
	The open method is used to open the notification widget:

		<div data-role="notification" data-type="smallpopup" data-interval="3000"></div>
		$('#notification').notification('open');
*/
/**
	@method close
	The close method is used to close the notification widget:

		<div data-role="notification" data-type="smallpopup" data-interval="3000"></div>
		$('#notification').notification('close');
*/
/**
	@method text
	The text method is used to set or get the notification text:

		<div data-role="notification" data-type="smallpopup" data-interval="3000"></div>
		// Set notification text
		$('#notification').notification('text', 'setThisText');
		// Get notification text
		texts = $('#notification').notification('text');
	@since Tizen2.0
*/
/**
	@method icon
	The setIcon method is used to set the ticker notification icon. The icon can be set only if the notification type is set to tickernoti.

		<div data-role="notification" data-type="ticker" data-interval="3000"></div>
		$('#notification').notification('icon', './test.png');
*/
(function ( $, window ) {
	$.widget( "tizen.notification", $.mobile.widget, {
		btn: null,
		text_bg: [],
		icon_img: [],
		interval: null,
		seconds: null,
		running: false,

		_get_text: function () {
			var text = new Array( 2 );

			if ( this.type === 'ticker' ) {
				text[0] = $( this.text_bg[0] ).text();
				text[1] = $( this.text_bg[1] ).text();
			} else {
				text[0] = $( this.text_bg[0] ).text();
			}

			return text;
		},

		_set_text: function ( text0, text1 ) {
			var _set = function ( elem, text ) {
				if ( !text ) {
					return;
				}
				elem.text( text );
			};

			if ( this.type === 'ticker' ) {
				_set( $( this.text_bg[0] ), text0 );
				_set( $( this.text_bg[1] ), text1 );
			} else {
				_set( $( this.text_bg[0] ), text0 );
			}
		},

		text: function ( text0, text1 ) {
			if ( text0 === undefined && text1 === undefined ) {
				return this._get_text();
			}

			this._set_text( text0, text1 );
		},

		icon: function ( src ) {
			if ( src === undefined ) {
				return;
			}

			this.icon_img.detach();
			this.icon_img = $( "<img src='" + src + "' class='ui-ticker-icon'>" );
			$( this.element ).find(".ui-ticker").append( this.icon_img );
		},

		_refresh: function () {
			var container = this._get_container();

			$( container ).addClass("fix")
					.removeClass("show")
					.removeClass("hide");

			this._set_interval();
		},

		open: function () {
			var container = this._get_container();

			if ( this.running ) {
				this._refresh();
				return;
			}

			$( container ).addClass("show")
					.removeClass("hide")
					.removeClass("fix");

			this.running = true;

			if ( this.type === 'popup' ) {
				this._set_position();
			}

			this._set_interval();
		},

		close: function () {
			var container = this._get_container();

			if ( !this.running ) {
				return;
			}

			$( container ).addClass("hide")
					.removeClass("show")
					.removeClass("fix");

			this.running = false;
			clearInterval( this.interval );
		},

		destroy: function () {
			var container = this._get_container();

			$( container ).removeClass("show")
					.removeClass("hide")
					.removeClass("fix");

			this._del_event();

			this.running = false;
		},

		_get_container: function () {
			if ( this.type === 'ticker' ) {
				return $( this.element ).find(".ui-ticker");
			}

			return $( this.element ).find(".ui-smallpopup");
		},

		_set_interval: function () {
			var self = this;

			clearInterval( this.interval );

			if ( this.seconds !== undefined && this.second !== 0 ) {
				this.interval = setInterval( function () {
					self.close();
				}, this.seconds );
			}
		},

		_add_event: function () {
			var self = this,
				container = this._get_container();

			if ( this.type === 'ticker' ) {
				container.find(".ui-ticker-btn").append( this.btn ).trigger("create");

				this.btn.bind( "vmouseup", function () {
					self.close();
				});
			}

			container.bind( 'vmouseup', function () {
				self.close();
			});
		},

		_del_event: function () {
			var container = this._get_container();

			if ( this.type === 'ticker' ) {
				this.btn.unbind("vmouseup");
			}
			container.unbind('vmouseup');
			clearInterval( this.interval );
		},

		_set_position: function () {
			var container = this._get_container(),
				$footer = $('.ui-page-active').children('.ui-footer'),
				footer_h = $footer.outerHeight() || 0;

			container.css( 'bottom', footer_h);
		},

		_create: function () {
			var self = this,
				elem = $( this.element ),
				i;

			this.btn = $('<div data-role="button" data-inline="true">Close</div>');

			this.seconds = elem.jqmData('interval');
			this.type = elem.jqmData('type') || 'popup';

			if ( this.type === 'ticker' ) {
				elem.wrapInner("<div class='ui-ticker'></div>");
				elem.find(".ui-ticker").append("<div class='ui-ticker-body'></div>" +
							"<div class='ui-ticker-btn'></div>");
				this.text_bg = elem.find("p");

				if ( this.text_bg.length < 2 ) {
					elem.find(".ui-ticker").append("<p></p><p></p>");
					this.text_bg = elem.find("p");
				} else if ( this.text_bg.length > 2 ) {
					for ( i = 2; i < this.text_bg.length; i++ ) {
						$( this.text_bg[i] ).css( "display", "none" );
					}
				}

				$( this.text_bg[0] ).addClass("ui-ticker-text1-bg");
				$( this.text_bg[1] ).addClass("ui-ticker-text2-bg");

				this.icon_img = elem.find("img");

				if ( this.icon_img.length ) {
					$( this.icon_img ).addClass("ui-ticker-icon");

					for ( i = 1; i < this.icon_img.length; i++ ) {
						$( this.icon_img[i] ).css( "display", "none" );
					}
				}
			} else {
				elem.wrapInner("<div class='ui-smallpopup'></div>");
				this.text_bg = elem.find("p").addClass("ui-smallpopup-text-bg");

				if ( this.text_bg.length < 1 ) {
					elem.find(".ui-smallpopup")
						.append("<p class='ui-smallpopup-text-bg'></p>");
					this.text_bg = elem.find("p");
				} else if ( this.text_bg.length > 1 ) {
					for ( i = 1; i < this.text_bg.length; i++ ) {
						$( this.text_bg[i] ).css( "display", "none" );
					}
				}

				this._set_position();
			}

			this._add_event();

			$( window ).bind( "resize", function () {
				if ( !self.running ) {
					return;
				}

				self._refresh();

				if ( self.type === 'popup' ) {
					self._set_position();
				}
			});
		}
	}); // End of widget

	// auto self-init widgets
	$( document ).bind( "pagecreate create", function ( e ) {
		$( e.target ).find(":jqmData(role='notification')").notification();
	});

	$( document ).bind( "pagebeforehide", function ( e ) {
		$( e.target ).find(":jqmData(role='notification')").notification('destroy');
	});
}( jQuery, this ));



/*
 * jQuery Mobile Widget @VERSION
 *
 * This software is licensed under the MIT licence (as defined by the OSI at
 * http://www.opensource.org/licenses/mit-license.php)
 *
 * ***************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 * Copyright (c) 2011 by Intel Corporation Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 *
 * Authors: Max Waterman <max.waterman@intel.com>
 * Authors: Minkyu Kang <mk7.kang@samsung.com>
 */

/**
 * tizenslider modifies the JQuery Mobile slider and is created in the same way.
 *
 * See the JQuery Mobile slider widget for more information :
 *     http://jquerymobile.com/demos/1.0a4.1/docs/forms/forms-slider.html
 *
 * The JQuery Mobile slider option:
 *     theme: specify the theme using the 'data-theme' attribute
 *
 * Options:
 *     theme: string; the theme to use if none is specified using the 'data-theme' attribute
 *            default: 'c'
 *     popup: boolean; controls whether the popup is displayed or not
 *                   specify if the popup is enabled using the 'data-popup' attribute
 *                   set from javascript using .tizenslider('option','popup',newValue)
 *
 * Events:
 *     changed: triggers when the value is changed (rather than when the handle is moved)
 *
 * Examples:
 *
 *     <a href="#" id="popupEnabler" data-role="button" data-inline="true">Enable popup</a>
 *     <a href="#" id="popupDisabler" data-role="button" data-inline="true">Disable popup</a>
 *     <div data-role="fieldcontain">
 *         <input id="mySlider" data-theme='a' data-popup='false' type="range" name="slider" value="7" min="0" max="9" />
 *     </div>
 *     <div data-role="fieldcontain">
 *         <input id="mySlider2" type="range" name="slider" value="77" min="0" max="777" />
 *     </div>
 *
 *     // disable popup from javascript
 *     $('#mySlider').tizenslider('option','popup',false);
 *
 *     // from buttons
 *     $('#popupEnabler').bind('vclick', function() {
 *         $('#mySlider').tizenslider('option','popup',true);
 *     });
 *     $('#popupDisabler').bind('vclick', function() {
 *         $('#mySlider').tizenslider('option','popup',false);
 *     });
 */

/**
	@class Slider
	The slider widget shows a control on the screen that you can use to change values by dragging a handle on a horizontal scale. Sliders can be used in Tizen as described in the jQueryMobile documentation for sliders.

	To add a slider widget to the application, use the following code:

		<input data-popup='false' type="range" name="slider" value="5" min="0" max="10" data-icon="text" data-text-left="Min" data-text-right="Max" />

	The slider can define callbacks for events as described in the jQueryMobile documentation for slider events.
	You can use methods with the slider as described in the jQueryMobile documentation for slider methods.
*/
/**
	@property {String} data-icon
	Defines the icon style for the slider ends. The icon options are bright, volume, and text.
	The default value is text.
*/
/**
	@property {Boolean} data-popup
	Enables or disables a pop-up showing the current value while the handle is dragged.
	The default value is true.
*/
/**
	@property {String} data-text-left
	Defines the text displayed on the left side of the slider.
	The data-icon option must be set to text.
*/
/**
	@property {String} data-text-right
	Defines the text displayed on the right side of the slider.
	The data-icon option must be set to text.
*/

(function ($, window, undefined) {
	$.widget("tizen.tizenslider", $.mobile.widget, {
		options: {
			popup: true
		},

		popup: null,
		handle: null,
		handleText: null,

		_create: function () {
			this.currentValue = null;
			this.popupVisible = false;

			var self = this,
				inputElement = $( this.element ),
				slider,
				popupEnabledAttr,
				icon,
				text_right,
				text_left,
				text_length,
				elem_left,
				elem_right,
				margin_left,
				margin_right,
				_closePopup;

			// apply jqm slider
			inputElement.slider();

			// hide the slider input element proper
			inputElement.hide();

			self.popup = $('<div class="ui-slider-popup"></div>');

			// set the popup according to the html attribute
			popupEnabledAttr = inputElement.jqmData('popup');
			if ( popupEnabledAttr !== undefined ) {
				self.options.popup = ( popupEnabledAttr == true );
			}

			// get the actual slider added by jqm
			slider = inputElement.next('.ui-slider');

			icon = inputElement.attr('data-icon');

			// wrap the background
			slider.wrap('<div class="ui-slider-container"></div>');

			// get the handle
			self.handle = slider.find('.ui-slider-handle');

			// remove the rounded corners from the slider and its children
			slider.removeClass('ui-btn-corner-all');
			slider.find('*').removeClass('ui-btn-corner-all');

			// add icon
			switch ( icon ) {
			case 'bright':
			case 'volume':
				elem_left = $('<div class="ui-slider-left-' + icon + '"></div>');
				elem_right = $('<div class="ui-slider-right-' + icon + '"></div>');

				slider.before( elem_left );
				slider.after( elem_right );

				margin_left = elem_left.width() + 16;
				margin_right = elem_right.width() + 16;
				break;

			case 'text':
				text_left = ( inputElement.attr('data-text-left') === undefined ) ? '' :
						inputElement.attr('data-text-left').substring( 0, 3 );
				text_right = ( inputElement.attr('data-text-right') === undefined ) ? '' :
						inputElement.attr('data-text-right').substring( 0, 3 );

				text_length = Math.max( text_left.length, text_right.length ) + 1;

				margin_left = text_length + "rem";
				margin_right = text_length + "rem";

				elem_left = $('<div class="ui-slider-left-text" style="left:' +
					-( text_length ) + 'rem; width:' + text_length + 'rem;">' +
					'<span style="position:relative;top:0.4em;">' +
					text_left +
					'</span></div>');
				elem_right = $('<div class="ui-slider-right-text" style="right:' +
					-( text_length ) + 'rem; width:' + text_length + 'rem;">' +
					'<span style="position:relative;top:0.4em;">' +
					text_right +
					'</span></div>');

				slider.before( elem_left );
				slider.after( elem_right );
				break;
			}

			if ( icon ) {
				slider.parent('.ui-slider-container').css({
					"margin-left": margin_left,
					"margin-right": margin_right
				});
			}

			// add a popup element (hidden initially)
			slider.parents(".ui-page").append( self.popup );
			self.popup.hide();

			// get the element where value can be displayed
			self.handleText = slider.find('.ui-btn-text');

			// set initial value
			self.updateSlider();

			_closePopup = function () {
				slider.trigger( 'vmouseup' );
			};

			// bind to changes in the slider's value to update handle text
			this.element.on('change', function () {
				// 2013.05.31 heeju.joo
				// for "refresh" method, (ex. $("input").val(5).slider("refresh"))
				// conditional statement has been added ( DCM-1735 )
				// if this function just call two functions like else statement,
				// popup and handle displayed in the wrong position because when the variable popupVisible is false, updateSlider() does not call popupPosition().
				if ( !self.popupVisible ) {
					// it is trick to cheat self.updateSlider()
					self.popupVisible = true;
					// updateSlider make the position of handle right
					self.updateSlider();
					// for other method, popupVisible variable need to have original value.
					self.popupVisible = false;
				} else {
					self.updateSlider();
					self.showPopup();
					$.mobile.$document.on( 'vmouseup.slider', _closePopup );
				}
			});

			this.element.on( 'slidestart', function ( event ) {
				self.updateSlider();
				self.showPopup();
				$.mobile.$document.on( 'vmouseup.slider', _closePopup );
			});

			// bind clicks on the handle to show the popup
			self.handle.on('vmousedown', function () {
				self.handle.addClass( "ui-slider-handle-press" );
				self.showPopup();
				$.mobile.$document.on( 'vmouseup.slider', _closePopup );
			});

			slider.on( 'vmousedown', function () {
				self.updateSlider();
				self.handle.addClass( "ui-slider-handle-press" );
				self.showPopup();
				$.mobile.$document.on( 'vmouseup.slider', _closePopup );
			}).on( 'vmouseup', function () {
				self.hidePopup();
				self.handle.removeClass( "ui-slider-handle-press" );
				$.mobile.$document.off('vmouseup.slider');
			});

			$.extend( this, {
				_globalHandler: [
					{
						src: $( window ),
						handler: {
							orientationchange: _closePopup,
						}
					}
				]
			});

			$.each( this._globalHandler, function ( idx, value ) {
				value.src.bind( value.handler );
			});

		},

		// position the popup
		positionPopup: function () {
			var dstOffset = this.handle.offset();

			this.popup.offset({
				left: dstOffset.left + ( this.handle.width() - this.popup.width() ) / 2,
				top: dstOffset.top - this.popup.height()
			});
		},

		// show value on the handle and in popup
		updateSlider: function () {
			var font_size,
				font_length,
				font_top,
				padding_size,
				newValue,
				get_value_length = function ( v ) {
					var val = Math.abs( v ),
						len;

					if ( val > 999 ) {
						len = 4;
					} else if ( val > 99 ) {
						len = 3;
					} else if ( val > 9 ) {
						len = 2;
					} else {
						len = 1;
					}

					if ( v < 0 ) {
						len++;
					}

					return len;
				};

			// remove the title attribute from the handle (which is
			// responsible for the annoying tooltip); NB we have
			// to do it here as the jqm slider sets it every time
			// the slider's value changes :(
			this.handle.removeAttr('title');

			newValue = parseInt(this.element.val(), 10);

			font_length = get_value_length( newValue );

			if ( this.popupVisible ) {
				this.positionPopup();

				switch ( font_length ) {
				case 1:
				case 2:
					font_size = '1.5rem';
					padding_size = '0.15rem';
					break;
				case 3:
					font_size = '1rem';
					padding_size = '0.5rem';
					break;
				default:
					font_size = '0.8rem';
					padding_size = '0.5rem';
					break;
				}

				this.popup.css({
					"font-size": font_size,
					"padding-top": padding_size
				});
			}

			if ( newValue === this.currentValue ) {
				return;
			}

			switch ( font_length ) {
			case 1:
				font_size = '0.95rem';
				font_top = '0';
				break;
			case 2:
				font_size = '0.85rem';
				font_top = '-0.01rem';
				break;
			case 3:
				font_size = '0.65rem';
				font_top = '-0.1rem';
				break;
			default:
				font_size = '0.45rem';
				font_top = '-0.15rem';
				break;
			}

			if ( font_size != this.handleText.css('font-size') ) {
				this.handleText.css({
					'font-size': font_size,
					'top': font_top,
					'position': 'relative'
				});
			}

			this.currentValue = newValue;
			this.handleText.text( newValue );
			this.popup.html( newValue );

			this.element.trigger( 'update', newValue );
		},

		// show the popup
		showPopup: function () {
			if ( !this.options.popup || this.popupVisible ) {
				return;
			}

			this.popup.show();
			this.popupVisible = true;
		},

		// hide the popup
		hidePopup: function () {
			if ( !this.options.popup || !this.popupVisible ) {
				return;
			}

			this.popup.hide();
			this.popupVisible = false;
		},

		_setOption: function (key, value) {
			var needToChange = ( value !== this.options[key] );

			if ( !needToChange ) {
				return;
			}

			switch ( key ) {
			case 'popup':
				this.options.popup = value;

				if ( this.options.popup) {
					this.updateSlider();
				} else {
					this.hidePopup();
				}

				break;
			}
		}
	});

	// stop jqm from initialising sliders
	$( document ).on( "pagebeforecreate", function ( e ) {
		if ( $.data( window, "jqmSliderInitSelector" ) === undefined ) {
			$.data( window, "jqmSliderInitSelector",
				$.mobile.slider.prototype.options.initSelector );
			$.mobile.slider.prototype.options.initSelector = null;
		}
	});

	// initialise sliders with our own slider
	$( document ).on( "pagecreate create", function ( e ) {
		var jqmSliderInitSelector = $.data( window, "jqmSliderInitSelector" );
		$( e.target ).find(jqmSliderInitSelector).each(function () {
			var $this = $( this );
			if ( $this.is("select") ) {
				$this.slider();
			} else {
				$this.tizenslider();
			}
		});
	});

}( jQuery, this ));



/* ***************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 *
 * Authors: Wonseop Kim ( wonseop.kim@samsung.com )
*/

/**
 * "Handler" is a widget helping a user to scroll a window or panel.
 * It is different from the scrollview feature in that the handler has a fixed size
 * and disappears when a scroll size is smaller than a parent window's size.
 * If the handler widget is activated, a scroll bar on the screen will be deactivated.
 * The handler widget supports scrolling up and down and indicates the position of the scrolled window.
 *
 * HTML Attributes:
 *
 *		data-handler : This attribute is indicating that whether enable.
 *						If you want to use, you will set 'true'.
 *		data-handler-theme : Set the widget theme ( optional )
 *
 * APIs:
 *
 *		enableHandler ( boolean )
 *			: Get or set the use of handler widget.
 *			If the value is "true", it will be run handler widget.
 *			If the value is "false", it will be not run handler widget.
 *			If no value is specified, will act as a getter.
 *
 * Events:
 *
 * Examples:
 *
 *		<div data-role="content" data-scroll="y" data-handler="true">
 *			<ul data-role="listview">
 *				<li data-role="list-divider">A</li>
 *				<li><a href="#">Adam Kinkaid</a></li>
 *					...
 *			</ul>
 *		</div>
 */

/**
	@class handler
	The handler widget enables the user to vertically scroll through a page or panel using a fixed-size handle. The widget indicates the position of the scrolled window, and only appears on the screen if the parent page or panel's scroll size is larger than the screen size. <br/> To add a handler widget to the application, use the following code:

		<div data-role="content" data-scroll="y" data-handler="true">
			<ul data-role="listview">
				<li data-role="list-divider">A</li>
				<li><a href="#">Adam Kinkaid</a></li>
					...
			</ul>
		</div>
	
	You can use the enableHandler method with the handler widget to get (if no value is defined) or set the handler usage status. If the [enable] value is true, the handler is enabled; otherwise the handler is not used.

		$("#.selector").scrollview("enableHandler", [enable]);
*/
/**
	@property {Boolean} data-handler
	Enables the handler widget. The value must be set to true.
*/
/**
	@property {String} data-handler-theme
	Sets the handler widget theme.
*/
( function ( $, document, undefined ) {
	// The options of handler in scrollview
	$.tizen.scrollview.prototype.options.handler = false;
	$.tizen.scrollview.prototype.options.handlerTheme = "s";

	var originSetOption = $.tizen.scrollview.prototype._setOption,
		createHandler = function ( target ) {
			var $view = target,
				prefix = "<div class=\"ui-handler ui-handler-direction-",
				suffix = "\"><div class=\"ui-handler-track\"><div class=\"ui-handler-handle\"><div class=\"ui-handler-thumb\"></div></div></div></div>",
				scrollview = $view.data( "scrollview" ),
				options = scrollview.options,
				direction = options.direction,
				parentTheme = $.mobile.getInheritedTheme( scrollview, "s" ),
				theme = options.theme || parentTheme,
				isHorizontal = ( scrollview.options.direction === "x" ),
				_$view = scrollview._$view,
				_$clip = scrollview._$clip,
				scrollbar = $view.find( ".ui-scrollbar" ),
				handler = null,
				handlerHandle = null,
				viewLength = 0,
				clipLength = 0,
				handlerHeight = 0,
				handlerMargin = 0,
				trackLength = 0,
				moveTimer,
				isTouchable = $.support.touch,
				dragStartEvt = ( isTouchable ? "touchstart" : "mousedown" ) + ".handler",
				dragMoveEvt = ( isTouchable ? "touchmove" : "mousemove" ) + ".handler",
				dragStopEvt = ( isTouchable ? "touchend" : "mouseup" ) + ".handler",
				dragLeaveEvt = ( isTouchable ? " touchleave" : " mouseleave" ) + ".handler",
				calculateLength = function () {
					clipLength = ( isHorizontal ? _$clip.width() : _$clip.height() );
					viewLength = ( isHorizontal ? _$view.width() : _$view.height() ) - clipLength;
					trackLength = clipLength - handlerHeight - handlerMargin * 2;
				},
				setHanderPostion = function ( scrollPos ) {
					var handlerPos = Math.round( ( isHorizontal ? scrollPos.x : scrollPos.y ) / viewLength * trackLength );
					handlerHandle[0].style[ ( isHorizontal ? "left" : "top" ) ] = handlerPos + "px";
				},
				stopHandlerScroll = function () {
					$( document ).unbind( ".handler" );
					$view.moveData = null;
					_$view.trigger( "scrollstop" );
				};

			if ( $view.find( ".ui-handler-handle" ).length !== 0 || typeof direction !== "string" ) {
				return;
			}

			handler = $( [ prefix, direction, suffix ].join( "" ) ).appendTo( $view.addClass( " ui-handler-" + theme ) );
			handlerHandle = $view.find( ".ui-handler-handle" ).attr( {
				"tabindex" : "0",
				"aria-label" : ( isHorizontal ? "Horizontal handler, double tap and move to scroll" : "Verticalhandler, double tap and move to scroll" )
			}).hide();
			handlerHeight = ( isHorizontal ? handlerHandle.width() : handlerHandle.height() );
			handlerMargin = ( isHorizontal ? parseInt( handler.css( "right" ), 10 ) : parseInt( handler.css( "bottom" ), 10 ) );

			$.extend( $view, {
				moveData : null
			});

			// handler drag
			handlerHandle.bind( dragStartEvt, {
				e : handlerHandle[0]
			}, function ( event ) {
				scrollview._stopMScroll();

				var target = event.data.e,
					t = ( isTouchable ? event.originalEvent.targetTouches[0] : event );

				target.style.opacity = 1.0;

				$view.moveData = {
					target : target,
					X : parseInt( target.style.left, 10 ) || 0,
					Y : parseInt( target.style.top, 10 ) || 0,
					pX : t.pageX,
					pY : t.pageY
				};
				calculateLength();

				_$view.trigger( "scrollstart" );

				if ( !isTouchable ) {
					event.preventDefault();
				}

				$( document ).bind( dragMoveEvt, function ( event ) {
					var moveData = $view.moveData,
						target = moveData.target,
						handlePos = 0,
						scrollPos = 0,
						t = ( isTouchable ? event.originalEvent.targetTouches[0] : event );

					handlePos = ( isHorizontal ? moveData.X + t.pageX - moveData.pX : moveData.Y + t.pageY - moveData.pY );

					if ( handlePos < 0 ) {
						handlePos = 0;
					}

					if ( handlePos > trackLength ) {
						handlePos = trackLength;
					}
					scrollPos = - Math.round( handlePos / trackLength * viewLength );

					if ( isHorizontal ) {
						scrollview._setScrollPosition( scrollPos, 0 );
						target.style.left = handlePos + "px";
					} else {
						scrollview._setScrollPosition( 0, scrollPos );
						target.style.top = handlePos + "px";
					}

					event.preventDefault();
				}).bind( dragStopEvt + dragLeaveEvt, function ( event ) {
					stopHandlerScroll();
				});
			});

			_$view.bind( dragStopEvt, function ( event ) {
				stopHandlerScroll();
			});

			$view.bind( "scrollstart", function ( event ) {
				if ( !scrollview.enableHandler() ) {
					return;
				}

				calculateLength();

				if ( viewLength < 0 || clipLength < handlerHeight ) {
					if ( scrollbar.is( ":hidden" ) ) {
						scrollbar.show();
					}
					return;
				}

				if ( scrollbar.is( ":visible" ) ) {
					scrollbar.hide();
				}

				if ( moveTimer ) {
					clearInterval( moveTimer );
					moveTimer = undefined;
				}

				handler.addClass( "ui-handler-visible" );
				handlerHandle.stop( true, true )
							.fadeIn();
			}).bind( "scrollupdate", function ( event, data ) {
				if ( !scrollview.enableHandler() || viewLength < 0 || clipLength < handlerHeight ) {
					return;
				}

				setHanderPostion( scrollview.getScrollPosition() );
			}).bind( "scrollstop", function ( event ) {
				if ( !scrollview.enableHandler() || viewLength < 0 || clipLength < handlerHeight ) {
					return;
				}

				moveTimer = setInterval( function () {
					setHanderPostion( scrollview.getScrollPosition() );
					if ( !scrollview._gesture_timer ) {
						clearInterval( moveTimer );
						moveTimer = undefined;
					}
				}, 10 );

				if ( scrollview._handlerTimer ) {
					clearTimeout( scrollview._handlerTimer );
					scrollview._handlerTimer = 0;
				}
				scrollview._handlerTimer = setTimeout( function () {
					if ( scrollview._timerID === 0 && $view.moveData === null ) {
						handlerHandle.stop( true, true )
							.css( "opacity", 1.0 )
							.fadeOut( function () {
								handler.removeClass( "ui-handler-visible" );
							});
						scrollview._handlerTimer = 0;
					}
				}, 1000 );
			}).bind( "mousewheel", function ( event ) {
				handler.removeClass( "ui-handler-visible" );
				setHanderPostion( scrollview.getScrollPosition() );
			});
		};

	$.extend( $.tizen.scrollview.prototype, {
		enableHandler: function ( enabled ) {
			if ( typeof enabled === 'undefined' ) {
				return this.options.handler;
			}

			this.options.handler = !!enabled;

			var $view = this.element;
			if ( this.options.handler ) {
				if ( $view.find( ".ui-handler" ).length === 0 ) {
					createHandler( $view );
				}

				$view.find( ".ui-scrollbar" ).hide();
				$view.find( ".ui-handler" ).show();
			} else {
				$view.find( ".ui-handler" ).removeClass( "ui-handler-visible" ).hide();
				$view.find( ".ui-scrollbar" ).show();
			}
		},

		_setHandlerTheme: function ( handlerTheme ) {
			if ( !handlerTheme ) {
				return;
			}

			var oldClass = "ui-handler-" + this.options.handlerTheme,
				newClass = "ui-handler-" + handlerTheme;

			this.element.removeClass( oldClass ).addClass( newClass );
			this.options.handlerTheme = handlerTheme;
		},

		_setOption: function ( key, value ) {
			switch ( key ) {
			case "handler":
				this.enableHandler( value );
				break;
			case "handlerTheme":
				this._setHandlerTheme( value );
				break;
			default:
				originSetOption.call( this, key, value );
			}
		},

		_handlerTimer : 0
	});

	$( document ).delegate( ":jqmData(scroll)", "scrollviewcreate", function () {
		var widget = $( this );
		if ( widget.attr( "data-" + $.mobile.ns + "scroll" ) === "none"
				|| widget.attr( "data-" + $.mobile.ns + "handler" ) !== "true" ) {
			return;
		}
		widget.scrollview( "enableHandler", "true" );
	});
} ( jQuery, document ) );



/* ***************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 *
 *	Author: Kangsik Kim <kangsik81.kim@samsung.com>
 *				Minkyeong Kim <minkyeong.kim@samsung.com>
*/

/**
 *	The TokenTextArea widget changes a text item to a button. It can be comprised of a number of button widgets. 
 *	When a user types text and the text gets a specific event to change from a text to a button, 
 *	the input text is changed to a TokenTextArea widget.
 *	A user can add the TokenTextArea widget to a contact list, email list, or another list.
 *	The typical use of this widget is composing a number of contacts or phone numbers in a specific area of the screen.
 *
 *	HTML Attributes:
 *
 *		data-link : Represents the id of the page or the URL of other HTML file.
 *				The page contains data for the user, for example, an address book.
 *				If the value is null, anchor button doesn't work. (Default : null)
 *		data-label:	Provide a label for a user-guide. (Default : 'To : ')
 *		data-description : This attribute is managing message format.
 *				This message is displayed when widget status was changed to 'focusout'. (Default : '+ {0}')
 *
 *	APIs:
 *
 *		inputtext (  [string]  )
 *			: If argument is not exist, will get a string from inputbox.
 *			If argument is exist, will set a string to inputbox.
 *		select (  [number]  )
 *			: If no argument exists, gets a string of the selected block.
 *			If any button isn't selected on a token text area widget, this method returns "null" value.
 *			When a user call this method with an argument which is a number type,
 *			this method selects the button which is matched with the argument.
 *		add ( text, [number] )
 *			:  If second argument does not exist, will insert to a new button at last position.
 *			Insert a new button at indexed position. The position is decided by the second argument.
 *			"index of position" means that the position of inserting a new button is decided by the second argument on "add" method.
 *			For example, if a user call the method like this "add("Tizen", 2)",
 *			new button labed "Tizen" will be inserted on the third position.
 *		remove ( [number] )
 *			: If no argument exists, all buttons are removed.
 *			Remove a button at indexed position.
 *			The position is decided by the second argument. (index: index of button)
 *		length ( void )
 *			: Get a number of buttons.
 *		foucsIn ( void )
 *			: This method change a status to 'focusin'.
 *			This status is able to manage a widget.
 *		focusOut ( void )
 *			: Changes the focus status to 'focus out'.
 *			The status is not able to manage a widget.
 *			All buttons that contained in the widget are removed and
 *			summarized message is displayed.
 *		destroy ( void )
 *			: Remove all of the new DOM elements for the current widget that you created.
 *
 *	Events:
 *
 *		select : Occur when a button is selected.
 *		add : Occur when new button is inserted. (@since Tizen 2.1 deprecated, You can still use this event. But not recommended.)
 *		remove : Occur when a button is removed. (@since Tizen 2.1 deprecated, You can still use this event. But not recommended.)
 *
 *	Examples:
 *
 *		<div data-role="tokentextarea" data-label="To : " data-link="#pageId" data-description="+ {0}">
 *		</div>
 *
 */


/**
	@class TokenTextArea
	The TokenTextArea widget enables the user to enter text and convert it to a button. Each button that is created from entered text as a result of a change event forms a token text area widget. This widget is useful in composing an e-mail or SMS message to a group of addresses, each of which is a clickable item for more actions, such as copying, editing, or removing the address.

	To add a token text area widget to the application, use the following code:

		<div data-role="tokentextarea" data-label="To : " data-link="#pageId">
		</div>
*/

/**
	@property {String} data-label
	Sets a label as a guide for the user.
	For example, while composing an e-mail message, the 'To : ' label is a guide for the user to enter e-mail addresses.

		<div data-role="tokentextarea" data-label="To : ">
		</div>
*/

/**
	@property {String} data-decription
	Manages the message format.
	The message is displayed when the widget status changes to focus out

		<div data-role="tokentextarea" data-description=" + {0}">
		</div>
 */
/**
	@property {String} data-link
	Sets the ID of the page or the URL of other HTML file to which the button links.
	If the data-link is set with the URL of other HTML file, the 'dom-cache' option of both page - a page containing a Tokentextarea and a page in the target HTML file - must be set as 'true'.

		<div data-role="tokentextarea" data-link="#pageId">
		</div>

		<div data-role="tokentextarea" data-link="fileName.html" data-dom-cache="true">
		</div>
*/
/**
	@event select
	The select event is fired when a token text area widget button is selected:

		<div data-role="tokentextarea">
		</div>
		$(".selector").on("select", function(event, ui)
		{
			// Handle the select event
		});	
*/
/**
	@event add (@since Tizen 2.1 deprecated, You can still use this event. But not recommended.)
	The add event is fired when a token text area widget button is created:

		<div data-role="tokentextarea">
		</div>
		$(".selector").on("add", function(event, ui)
		{
			// Handle the add event
		});
*/
/**
	@event remove (@since Tizen 2.1 deprecated, You can still use this event. But not recommended.)
	The remove event is fired when a token text area widget button is removed:
	Restriction : "remove" event works under only "bind" event handling.

		<div data-role="tokentextarea">
		</div>
		$(".selector").bind("remove", function(event, ui)
		{
			// Handle the remove event
		});
*/
/**
	@method destroy
	The destroy method is used to remove in the current widget all the new DOM elements that you have created.

		<div data-role="tokentextarea">
		</div>
		$(".selector").tokentextarea("destroy");

	@since Tizen2.0
*/
/**
	@method inputText
	The inputText method is used to manage the widget input box text. If no parameter is set, the method gets the input box text. If a parameter is set, the parameter text is set in the input box.
	
		<div data-role="tokentextarea">
		</div>
		$(".selector").tokentextarea("inputText", [text]);
*/
/**
	@method select
	The select method is used to select a token text area widget button based on its index value. If no index value is defined, the method returns the string of the selected block. If there are no buttons present in the widget, the method returns null.

		<div data-role="tokentextarea">
		</div>
		$(".selector").tokentextarea("select", [index]);
*/
/**
	@method add
	The add method is used to add a new token text area widget button with the specified label text at the specified index position. If the index parameter is not defined, the widget button is added at the bottom of the list. For example, the $(".selector").tokentextarea("add", "Tizen", 2) method call creates a new widget button labeled 'Tizen' at the third position in the widget.

		<div data-role="tokentextarea">
		</div>
		$(".selector").tokentextarea("add", [text], [index]);
*/
/**
	@method remove
	The remove method is used to remove a token text area widget button at the specified index position. If the parameter is not defined, all the widget buttons are removed.

		<div data-role="tokentextarea">
		</div>
		$(".selector").tokentextarea("remove", [index]);
*/
/**
	@method length
	The length method is used to retrieve the number of buttons in the token text area widget:
		<div data-role="tokentextarea">
		</div>
		$(".selector").tokentextarea("length");
*/
/**
	@method focusIn
	The focusIn method is used to set the focus status to "focus in". This focus state enables the user to add or remove buttons in the token text area widget.

		<div data-role="tokentextarea">
		</div>
		$(".selector").tokentextarea("focusIn");
*/
/**
	@method focusOut
	The focusOut method is used to set the focus status to "focus out". In this focus state, the user cannot manage the buttons in the widget, all the buttons are removed, and a message is displayed.

		<div data-role="tokentextarea">
		</div>
		$(".selector").tokentextarea("focusOut");
*/
( function ( $, window, document, undefined ) {
	$.widget( "tizen.tokentextarea", $.mobile.widget, {
		_focusStatus : null,
		_items : null,
		_viewWidth : 0,
		_reservedWidth : 0,
		_currentWidth : 0,
		_fontSize : 0,
		_anchorWidth : 0,
		_labelWidth : 0,
		_marginWidth : 0,
		options : {
			label : "To : ",
			link : null,
			description : "+ {0}"
		},

		_create : function () {
			var self = this,
				$view = this.element,
				role = $view.jqmData( "role" ),
				option = this.options,
				className = "ui-tokentextarea-link",
				inputbox = $( document.createElement( "input" ) ),
				labeltag = $( document.createElement( "span" ) ),
				moreBlock = $( document.createElement( "a" ) );

			$view.hide().empty().addClass( "ui-" + role );

			// create a label tag.
			$( labeltag ).text( option.label ).addClass( "ui-tokentextarea-label" ).attr( "tabindex", 0 );
			$view.append( labeltag );

			// create a input tag
			$( inputbox ).addClass( "ui-tokentextarea-input ui-tokentextarea-input-visible ui-input-text ui-body-s" ).attr( "role", "textbox" );
			$view.append( inputbox );

			// create a anchor tag.
			if ( option.link === null || $.trim( option.link ).length < 1 || $( option.link ).length === 0 ) {
				className += "-dim";
			}
			$( moreBlock ).attr( "data-role", "button" )
				.buttonMarkup( {
					inline: true,
					icon: "plus",
					style: "circle"
				})
				.attr( { "href" : $.trim( option.link ), "tabindex" : 0 } )
				.addClass( "ui-tokentextarea-link-base" )
				.addClass( className )
				.find( "span.ui-btn-text" )
				.text( "Add recipient" );

			// append default htmlelements to main widget.
			$view.append( moreBlock );

			// bind a event
			this._bindEvents();
			self._focusStatus = "init";
			// display widget
			$view.show();

			// assign global variables
			self._viewWidth = $view.innerWidth();
			self._reservedWidth += self._calcBlockWidth( moreBlock );
			self._reservedWidth += self._calcBlockWidth( labeltag );
			self._fontSize = parseInt( $( moreBlock ).css( "font-size" ), 10 );
			self._currentWidth = self._reservedWidth;
			self._modifyInputBoxWidth();
		},

		// bind events
		_bindEvents : function () {
			var self = this,
				$view = self.element,
				option = self.options,
				inputbox = $view.find( ".ui-tokentextarea-input" ),
				moreBlock = $view.find( ".ui-tokentextarea-link-base" );

			// delegate a event to HTMLDivElement(each block).
			$view.delegate( "div", "click", function ( event ) {
				if ( $( this ).hasClass( "ui-tokentextarea-sblock" ) ) {
					// If block is selected, it will be removed.
					self._removeTextBlock();
				}

				var lockBlock = $view.find( "div.ui-tokentextarea-sblock" );
				if ( typeof lockBlock !== "undefined" ) {
					lockBlock.removeClass( "ui-tokentextarea-sblock" ).addClass( "ui-tokentextarea-block" );
				}
				$( this ).removeClass( "ui-tokentextarea-block" ).addClass( "ui-tokentextarea-sblock" );
				$view.trigger( "select" );
			});

			inputbox.bind( "keyup", function ( event ) {
				// 8  : backspace
				// 13 : Enter
				// 186 : semi-colon
				// 188 : comma
				var keyValue = event.keyCode,
					valueString = $( inputbox ).val(),
					valueStrings = [],
					index,
					isSeparator = false;

				if ( keyValue === 8 ) {
					if ( valueString.length === 0 ) {
						self._validateTargetBlock();
					}
				} else if ( keyValue === 13 || keyValue === 186 || keyValue === 188 ) {
					if ( valueString.length !== 0 ) {
						// split content by separators(',', ';')
						valueStrings = valueString.split ( /[,;]/ );
						for ( index = 0; index < valueStrings.length; index++ ) {
							if ( valueStrings[index].length !== 0 && valueStrings[index].replace( /\s/g, "" ).length !== 0 ) {
								self._addTextBlock( valueStrings[index] );
							}
						}
					}
					inputbox.val( "" );
					isSeparator = true;
				} else {
					self._unlockTextBlock();
				}

				return !isSeparator;
			});

			moreBlock.click( function () {
				if ( $( moreBlock ).hasClass( "ui-tokentextarea-link-dim" ) ) {
					return;
				}

				$( inputbox ).removeClass( "ui-tokentextarea-input-visible" ).addClass( "ui-tokentextarea-input-invisible" );

				$.mobile.changePage( option.link, {
					transition: "slide",
					reverse: false,
					changeHash: false
				});
			});

			$( document ).bind( "pagechange.mbe", function ( event ) {
				if ( $view.innerWidth() === 0 ) {
					return ;
				}
				self.refresh();
				$( inputbox ).removeClass( "ui-tokentextarea-input-invisible" ).addClass( "ui-tokentextarea-input-visible" );
			});

			$view.bind( "click", function ( event ) {
				if ( self._focusStatus === "focusOut" ) {
					self.focusIn();
				}
			});
		},

		// create a textbutton and append this button to parent layer.
		// @param arg1 : string
		// @param arg2 : index
		_addTextBlock : function ( messages, blockIndex ) {
			if ( arguments.length === 0 ) {
				return;
			}

			if ( !messages ) {
				return ;
			}

			var self = this,
				$view = self.element,
				content = messages,
				index = blockIndex,
				blocks = null,
				textBlock = null;

			if ( self._viewWidth === 0 ) {
				self._viewWidth = $view.innerWidth();
			}

			// Create a new text HTMLDivElement.
			textBlock = $( document.createElement( 'div' ) );

			textBlock.text( content ).addClass( "ui-tokentextarea-block" ).attr( { "aria-label" : "double tap to edit", "tabindex" : 0 } );
			textBlock.css( {'visibility': 'hidden'} );

			blocks = $view.find( "div" );
			if ( index !== null && index <= blocks.length ) {
				$( blocks[index] ).before( textBlock );
			} else {
				$view.find( ".ui-tokentextarea-input" ).before( textBlock );
			}

			textBlock = self._ellipsisTextBlock( textBlock );
			textBlock.css( {'visibility': 'visible'} );

			self._modifyInputBoxWidth();

			textBlock.hide();
			textBlock.fadeIn( "fast", function () {
				self._currentWidth += self._calcBlockWidth( textBlock );
				$view.trigger( "add" );
			});
		},

		_removeTextBlock : function () {
			var self = this,
				$view = this.element,
				lockBlock = $view.find( "div.ui-tokentextarea-sblock" ),
				_temp = null,
				_dummy = function () {};

			if ( lockBlock !== null && lockBlock.length > 0 ) {
				self._currentWidth -= self._calcBlockWidth( lockBlock );

				lockBlock.fadeOut( "fast", function () {
					lockBlock.remove();
					self._modifyInputBoxWidth();
				});

				this._eventRemoveCall = true;
				if ( $view[0].remove ) {
					_temp = $view[0].remove;
					$view[0].remove = _dummy;
				}
				$view.triggerHandler( "remove" );
				if ( _temp) {
					$view[0].remove = _temp;
				}
				this._eventRemoveCall = false;
			} else {
				$view.find( "div:last" ).removeClass( "ui-tokentextarea-block" ).addClass( "ui-tokentextarea-sblock" );
			}
		},

		_calcBlockWidth : function ( block ) {
			return $( block ).outerWidth( true );
		},

		_unlockTextBlock : function () {
			var $view = this.element,
				lockBlock = $view.find( "div.ui-tokentextarea-sblock" );
			if ( lockBlock ) {
				lockBlock.removeClass( "ui-tokentextarea-sblock" ).addClass( "ui-tokentextarea-block" );
			}
		},

		// call when remove text block by backspace key.
		_validateTargetBlock : function () {
			var self = this,
				$view = self.element,
				lastBlock = $view.find( "div:last" ),
				tmpBlock = null;

			if ( lastBlock.hasClass( "ui-tokentextarea-sblock" ) ) {
				self._removeTextBlock();
			} else {
				tmpBlock = $view.find( "div.ui-tokentextarea-sblock" );
				tmpBlock.removeClass( "ui-tokentextarea-sblock" ).addClass( "ui-tokentextarea-block" );
				lastBlock.removeClass( "ui-tokentextarea-block" ).addClass( "ui-tokentextarea-sblock" );
			}
		},

		_ellipsisTextBlock : function ( textBlock ) {
			var self = this,
				$view = self.element,
				maxWidth = self._viewWidth / 2;

			if ( self._calcBlockWidth( textBlock ) > maxWidth ) {
				$( textBlock ).width( maxWidth - self._marginWidth );
			}

			return textBlock;
		},

		_modifyInputBoxWidth : function () {
			var self = this,
				$view = self.element,
				margin = 0,
				labelWidth = 0,
				anchorWidth = 0,
				inputBoxWidth = 0,
				blocks = $view.find( "div" ),
				blockWidth = 0,
				index = 0,
				inputBoxMargin = 10,
				inputBox = $view.find( ".ui-tokentextarea-input" );

			if ( $view.width() === 0 ) {
				return;
			}

			if ( self._labelWidth === 0 ) {
				self._labelWidth = $view.find( ".ui-tokentextarea-label" ).outerWidth( true );
				self._anchorWidth = $view.find( ".ui-tokentextarea-link-base" ).outerWidth( true );
				self._marginWidth = parseInt( ( $( inputBox ).css( "margin-left" ) ), 10 );
				self._marginWidth += parseInt( ( $( inputBox ).css( "margin-right" ) ), 10 );
				self._viewWidth = $view.innerWidth();
			}

			margin = self._marginWidth;
			labelWidth = self._labelWidth;
			anchorWidth = self._anchorWidth;
			inputBoxWidth = self._viewWidth - labelWidth;

			for ( index = 0; index < blocks.length; index += 1 ) {
				blockWidth = self._calcBlockWidth( blocks[index] );

				if ( blockWidth >= inputBoxWidth + anchorWidth ) {
					if ( blockWidth >= inputBoxWidth ) {
						inputBoxWidth = self._viewWidth - blockWidth;
					} else {
						inputBoxWidth = self._viewWidth;
					}
				} else {
					if ( blockWidth > inputBoxWidth ) {
						inputBoxWidth = self._viewWidth - blockWidth;
					} else {
						inputBoxWidth -= blockWidth;
					}
				}
			}

			inputBoxWidth -= margin;
			if ( inputBoxWidth < anchorWidth * 2 ) {
				inputBoxWidth = self._viewWidth - margin;
			}
			$( inputBox ).width( inputBoxWidth - anchorWidth - inputBoxMargin );
		},

		_stringFormat : function ( expression ) {
			var pattern = null,
				message = expression,
				i = 0;
			for ( i = 1; i < arguments.length; i += 1 ) {
				pattern = "{" + ( i - 1 ) + "}";
				message = message.replace( pattern, arguments[i] );
			}
			return message;
		},

		_resizeBlocks : function () {
			var self = this,
				$view = self.element,
				blocks = $view.find( "div" ),
				index = 0;

			for ( index = 0 ; index < blocks.length ; index += 1 ) {
				$( blocks[index] ).css( "width", "auto" );
				blocks[index] = self._ellipsisTextBlock( blocks[index] );
			}
		},

		//---------------------------------------------------- //
		//					Public Method   //
		//----------------------------------------------------//
		//
		// Focus In Event
		//
		focusIn : function () {
			if ( this._focusStatus === "focusIn" ) {
				return;
			}

			var $view = this.element;

			$view.find( ".ui-tokentextarea-label" ).attr( "tabindex", 0 ).show();
			$view.find( ".ui-tokentextarea-desclabel" ).remove();
			$view.find( "div.ui-tokentextarea-sblock" ).removeClass( "ui-tokentextarea-sblock" ).addClass( "ui-tokentextarea-block" );
			$view.find( "div" ).attr( { "aria-label" : "double tap to edit", "tabindex" : 0 } ).show();
			$view.find( ".ui-tokentextarea-input" ).removeClass( "ui-tokentextarea-input-invisible" ).addClass( "ui-tokentextarea-input-visible" ).attr( "tabindex", 0 );
			$view.find( "a" ).attr( "tabindex", 0 ).show();

			// change focus state.
			this._modifyInputBoxWidth();
			this._focusStatus = "focusIn";
			$view.removeClass( "ui-tokentextarea-focusout" ).addClass( "ui-tokentextarea-focusin" ).removeAttr( "tabindex" );
			$view.find( ".ui-tokentextarea-input" ).focus();
		},

		focusOut : function () {
			if ( this._focusStatus === "focusOut" ) {
				return;
			}

			var self = this,
				$view = self.element,
				tempBlock = null,
				stateBlock = null,
				numBlock = null,
				statement = "",
				index = 0,
				lastIndex = 10,
				label = $view.find( ".ui-tokentextarea-label" ),
				more = $view.find( "span" ),
				blocks = $view.find( "div" ),
				currentWidth = $view.outerWidth( true ) - more.outerWidth( true ) - label.outerWidth( true ),
				blockWidth = 0;

			label.removeAttr( "tabindex" );
			$view.find( ".ui-tokentextarea-input" ).removeClass( "ui-tokentextarea-input-visible" ).addClass( "ui-tokentextarea-input-invisible" ).removeAttr( "tabindex" );
			$view.find( "a" ).removeAttr( "tabindex" ).hide();
			blocks.removeAttr( "aria-label" ).removeAttr( "tabindex" ).hide();

			currentWidth = currentWidth - self._reservedWidth;

			for ( index = 0; index < blocks.length; index++ ) {
				blockWidth = $( blocks[index] ).outerWidth( true );
				if ( currentWidth - blockWidth <= 0 ) {
					lastIndex = index - 1;
					break;
				}

				$( blocks[index] ).show();
				currentWidth -= blockWidth;
			}

			if ( lastIndex !== blocks.length ) {
				statement = self._stringFormat( self.options.description, blocks.length - lastIndex - 1 );
				tempBlock = $( document.createElement( 'span' ) );
				tempBlock.addClass( "ui-tokentextarea-desclabel" ).attr( { "aria-label" : "more, double tap to edit", "tabindex" : "-1" } );
				stateBlock = $( document.createElement( 'span' ) ).text( statement ).attr( "aria-hidden", "true" );
				numBlock = $( document.createElement( 'span' ) ).text( blocks.length - lastIndex - 1 ).attr( "aria-label", "and" ).css( "visibility", "hidden" );
				tempBlock.append( stateBlock );
				tempBlock.append( numBlock );
				$( blocks[lastIndex] ).after( tempBlock );
			}

			// update focus state
			this._focusStatus = "focusOut";
			$view.removeClass( "ui-tokentextarea-focusin" ).addClass( "ui-tokentextarea-focusout" ).attr( "tabindex", 0 );
		},

		inputText : function ( message ) {
			var $view = this.element;

			if ( arguments.length === 0 ) {
				return $view.find( ".ui-tokentextarea-input" ).val();
			}
			$view.find( ".ui-tokentextarea-input" ).val( message );
			return message;
		},

		select : function ( index ) {
			var $view = this.element,
				lockBlock = null,
				blocks = null;

			if ( this._focusStatus === "focusOut" ) {
				return;
			}

			if ( arguments.length === 0 ) {
				// return a selected block.
				lockBlock = $view.find( "div.ui-tokentextarea-sblock" );
				if ( lockBlock ) {
					return lockBlock.text();
				}
				return null;
			}
			// 1. unlock all blocks.
			this._unlockTextBlock();
			// 2. select pointed block.
			blocks = $view.find( "div" );
			if ( blocks.length > index ) {
				$( blocks[index] ).removeClass( "ui-tokentextarea-block" ).addClass( "ui-tokentextarea-sblock" );
				$view.trigger( "select" );
			}
			return null;
		},

		add : function ( message, position ) {
			if ( this._focusStatus === "focusOut" ) {
				return;
			}

			this._addTextBlock( message, position );
		},

		remove : function ( position ) {
			var self = this,
				$view = this.element,
				blocks = $view.find( "div" ),
				index = 0,
				_temp = null,
				_dummy = function () {};

			if ( this._focusStatus === "focusOut" ) {
				return;
			}

			if ( arguments.length === 0 ) {
				blocks.fadeOut( "fast", function () {
					blocks.remove();
					self._modifyInputBoxWidth();
					self._trigger( "clear" );
				});
			} else if ( !isNaN( position ) ) {
				// remove selected button
				index = ( ( position < blocks.length ) ? position : ( blocks.length - 1 ) );

				$( blocks[index] ).fadeOut( "fast", function () {
					$( blocks[index] ).remove();
					self._modifyInputBoxWidth();
				});

				this._eventRemoveCall = true;
				if ( $view[0].remove ) {
					_temp = $view[0].remove;
					$view[0].remove = _dummy;
				}
				$view.triggerHandler( "remove" );
				if ( _temp) {
					$view[0].remove = _temp;
				}
				this._eventRemoveCall = false;
			}
		},

		length : function () {
			return this.element.find( "div" ).length;
		},

		refresh : function () {
			var self = this,
				viewWidth = this.element.innerWidth();

			if ( viewWidth && self._viewWidth !== viewWidth ) {
				self._viewWidth = viewWidth;
			}
			self._resizeBlocks();
			self._modifyInputBoxWidth();
		},

		destroy : function () {
			var $view = this.element,
				_temp = null,
				_dummy = function () {};

			if ( this._eventRemoveCall ) {
				return;
			}

			$view.find( ".ui-tokentextarea-label" ).remove();
			$view.find( "div" ).undelegate( "click" ).remove();
			$view.find( "a" ).remove();
			$view.find( ".ui-tokentextarea-input" ).unbind( "keyup" ).remove();

			this._eventRemoveCall = true;
			if ( $view[0].remove ) {
				_temp = $view[0].remove;
				$view[0].remove = _dummy;
			}
			$view.remove();
			if ( _temp) {
				$view[0].remove = _temp;
			}
			this._eventRemoveCall = false;

			this._trigger( "destroy" );
		}
	});

	$( document ).bind( "pagecreate create", function () {
		$( ":jqmData(role='tokentextarea')" ).tokentextarea();
	});

	$( window ).bind( "resize", function () {
		$( ":jqmData(role='tokentextarea')" ).tokentextarea( "refresh" );
	});
} ( jQuery, window, document ) );



/* ***************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 */
/*
* jQuery Mobile Framework : "textinput" plugin for text inputs, textareas
* Copyright (c) jQuery Project
* Licensed under the MIT license.
* http://jquery.org/license
* Authors: Jinhyuk Jun <jinhyuk.jun@samsung.com>
*          Wongi Lee <wongi11.lee@samsung.com>
*/

/**
 * Searchbar can be created using <input> element with type=search
 * <input type="search" name="search" id="search1" value=""  />
 *
 * Searchbar can be inserted 3 cases
 * content : seachbar behave same as content element
 * header : searchbar placed below title(header), It doesn't move when scrolling page
 * inside optionheader : Searchbar placed inside optionheader, searchbar can be seen only expand optionheader
 *
 * Examples:
 *
 *	HTML markup for creating Searchbar
 *		<input type="search"/>
 *
 *	How to make searchbar in content
 *		<input type="search" name="" id="" value=""  />
 *
 *	How to make cancel button in searchbar
 *		<div data-role="header" data-position ="fixed" >
 *			<h1>Searchbar</h1>
 *			<input type="search" data-cancel-btn=true name="" id="" value=""  />
 *		</div>
 *
 *	How to make icon in front of searchbar
 *		<div data-role="header" data-position ="fixed" >
 *			<h1>Searchbar</h1>
 *			<input type="search" data-icon="call" name="" id="" value=""  />
 *		</div>
*/

/**
	@class SearchBar
	The search bar widget is used to search for page content. This widget can be placed in the header, option header, or page content.

	To add a search bar widget to the application, use the following code:

		<label for="search-basic">Search Input:</label>
		<input type="search" name="search" id="searc-basic" value="" data-mini="true" />

	Tizen supports many search bar options as described in the jQueryMobile documentation for search bar options.
	The search bar can define callbacks for events as described in the jQueryMobile documentation for search bar events.
	You can use methods with the search bar as described in the jQueryMobile documentation for search bar methods.
*/

(function ( $, undefined ) {

	$.widget( "tizen.searchbar", $.mobile.widget, {
		options: {
			theme: null,
			initSelector: "input[type='search'],:jqmData(type='search'), input[type='tizen-search'],:jqmData(type='tizen-search')"
		},

		_create: function () {
			var input = this.element,
				o = this.options,
				theme = o.theme || $.mobile.getInheritedTheme( this.element, "c" ),
				themeclass  = " ui-body-" + theme,
				focusedEl,
				clearbtn,
				cancelbtn,
				defaultText,
				defaultTextClass,
				trimedText,
				newClassName,
				newStyle,
				newDiv,
				searchimage,
				inputedText,
				useCancelBtn = false,
				frontIcon = false;

			$( "label[for='" + input.attr( "id" ) + "']" ).addClass( "ui-input-text" );

			if ( typeof input[0].autocorrect !== "undefined" && !$.support.touchOverflow ) {
				// Set the attribute instead of the property just in case there
				// is code that attempts to make modifications via HTML.
				input[0].setAttribute( "autocorrect", "off" );
				input[0].setAttribute( "autocomplete", "off" );
			}

			focusedEl = input.wrap( "<div class='ui-input-search ui-shadow-inset ui-corner-all ui-btn-shadow" + themeclass + "'></div>" ).parent();

			if ( $( this.element ).data( "cancel-btn" ) === true ) {
				useCancelBtn = true;
				focusedEl.addClass( "ui-input-search-default" );
			}
			if ( $( this.element ).data( "icon" ) != undefined ) {
				frontIcon = true;
				focusedEl.addClass( "ui-search-bar-icon" );
			}

			clearbtn = $( "<a href='#' class='ui-input-clear' title='clear text'>clear text</a>" );

			clearbtn.on( "click", function (event) {
					if ( input.attr( "disabled" ) == "disabled" ) {
						return false;
					}
					input
						.val( "" )
						.trigger('change')
						.focus();
					event.preventDefault();
				})
				.appendTo( focusedEl )
				.buttonMarkup({
					icon: "deleteSearch",
					iconpos: "notext",
					corners: true,
					shadow: true
				});

			/* temporarily delete 06.28 Heeju Joo */
			/*function toggleClear() {
				setTimeout(function () {
					clearbtn.toggleClass( "ui-input-clear-hidden", !input.val()
				}, 0);
			}*/


			function showCancel() {
				focusedEl
					.addClass( "ui-input-search-default" )
					.removeClass( "ui-input-search-wide" );
				cancelbtn
					.addClass( "ui-btn-cancel-show" )
					.removeClass( "ui-btn-cancel-hide" );
			}

			function hideCancel() {
				focusedEl
					.addClass( "ui-input-search-wide" )
					.removeClass( "ui-input-search-default" );
				cancelbtn
					.addClass( "ui-btn-cancel-hide" )
					.removeClass( "ui-btn-cancel-show" );
			}

			function makeFrontIcon() {
				var IconStyle = $( input ).jqmData( "icon" ),
					frontIcon = $( "<div data-role='button' data-style='circle'></div>" );

				frontIcon
					.appendTo( focusedEl.parent() )
					.buttonMarkup( {
						icon: IconStyle,
						iconpos: "notext",
						corners: true,
						shadow: true
					} );
				frontIcon.addClass( "ui-btn-search-front-icon" );
			}
			/* temporarily delete - 06.28 Heeju Joo */
			/*toggleClear();

			input.bind( 'paste cut keyup focus change blur', toggleClear );
			*/

			/* N_SE-43150 when input get event "focus", it show clearbtn */
			input.bind( "focus", function() {
				clearbtn.css("display", "inline-block");
			});
			//SLP --start search bar with cancel button
			focusedEl.wrapAll( "<div class='input-search-bar'></div>" );
			searchimage = $("<div class='ui-image-search'></div>").appendTo( focusedEl );

			if ( frontIcon ) {
				makeFrontIcon();
			}

			if ( useCancelBtn ) {
				cancelbtn = $( "<div data-role='button' class='ui-input-cancel' title='clear text'>Cancel</div>" )
					.bind('click', function ( event ) {
						if ( input.attr( "disabled" ) == "disabled" ) {
							return false;
						}
						event.preventDefault();
						event.stopPropagation();

						input
							.val( "" )
							.trigger('change')
							.blur();

						if ( useCancelBtn ) {
							hideCancel();
						}
					} )
					.appendTo( focusedEl.parent() )
					.buttonMarkup( {
						iconpos: "cancel",
						corners: true,
						shadow: true
					} );
			}

			// Input Focused
			input
				.focus( function () {
					if ( input.attr( "disabled" ) == "disabled" ) {
						return false;
					}
					if ( useCancelBtn ) {
						showCancel();
					}
					focusedEl.addClass( $.mobile.focusClass );
				})
				.blur(function () {
					focusedEl.removeClass( $.mobile.focusClass );
				});

			// Default Text
			defaultText = input.jqmData( "default-text" );

			if ( ( defaultText != undefined ) && ( defaultText.length > 0 ) ) {
				defaultTextClass = "ui-input-default-text";
				trimedText = defaultText.replace(/\s/g, "");

				/* Make new class for default text string */
				newClassName = defaultTextClass + "-" + trimedText;
				newStyle = $( "<style>" + '.' + newClassName + ":after" + "{content:" + "'" + defaultText + "'" + "}" + "</style>" );
				$( 'html > head' ).append( newStyle );

				/* Make new empty <DIV> for default text */
				newDiv = $( "<div></div>" );

				/* Add class and append new div */
				newDiv.addClass( defaultTextClass );
				newDiv.addClass( newClassName );
				newDiv.tap( function ( event ) {
					input.blur();
					input.focus();
				} );

				input.parent().append( newDiv );

				/* When focus, default text will be hide. */
				input
					.focus( function () {
						input.parent().find( "div.ui-input-default-text" ).addClass( "ui-input-default-hidden" );
					} )
					.blur( function () {
						var inputedText = input.val();
						if ( inputedText.length > 0 ) {
							input.parent().find( "div.ui-input-default-text" ).addClass( "ui-input-default-hidden" );
						} else {
							input.parent().find( "div.ui-input-default-text" ).removeClass( "ui-input-default-hidden" );
						}
					} );
			}

			if ( !input.attr("placeholder") ) {
				input.attr( "placeholder", "Search" );
			}
		},

		disable: function () {
			this.element.attr( "disabled", true );
			this.element.parent().addClass( "ui-disabled" );
			$( this.element ).blur();
			this.element.parent().parent().find(".ui-input-cancel").addClass( "ui-disabled" );
		},

		enable: function () {
			this.element.attr( "disabled", false );
			this.element.parent().removeClass( "ui-disabled" );
			this.element.parent().parent().find(".ui-input-cancel").removeClass( "ui-disabled" );
			$( this.element ).focus();
		}
	} );

	//auto self-init widgets
	$( document ).bind( "pagecreate create", function ( e ) {
		$.tizen.searchbar.prototype.enhanceWithin( e.target );
	} );

}( jQuery ) );



/* ***************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 *
 *	Author: Kangsik Kim <kangsik81.kim@samsung.com>
 *			Youmin Ha <youmin.ha@samsung.com>
*/

/**
 * In the web environment, it is challenging to display a large amount of data in a grid.
 * When an application needs to show, for example, image gallery with over 1,000 images,
 * the same enormous data must be inserted into a HTML document.
 * It takes a long time to display the data and manipulating DOM is complex.
 * The virtual grid widget supports storing unlimited data without performance issues
 * by reusing a limited number of grid elements.
 * The virtual grid widget is based on the jQuery.template plug-in 
 * For more information, see jQuery.template.
 *
 * HTML Attributes:
 *
 *		data-role:  virtualgrid
 *		data-template :	Has the ID of the jQuery.template element.
 *						jQuery.template for a virtual grid must be defined.
 *						Style for template would use rem unit to support scalability.
 *		data-direction : This option define the direction of the scroll.
 *						You must choose one of the 'x' and 'y' (Default : y)
 *		data-rotation : This option defines whether or not the circulation of the data.
 *						If option is 'true' and scroll is reached the last data,
 *						Widget will present the first data on the screen.
 *						If option is ‘false’, Widget will operate like a scrollview.
 *
 *		ID : <DIV> element that has "data-role=virtualgrid" must have ID attribute.
 *
 * APIs:
 *
 *		create ( {
 *				itemData: function ( idx ) { return json_obj; },
 *				numItemData: number or function () { return number; },
 *				cacheItemData: function ( minIdx, maxIdx ) {}
 *				} )
 *			: Create VirtualGrid widget. At this moment, _create method is called.
 *			args : A collection of options
 *				itemData: A function that returns JSON object for given index. Mandatory.
 *				numItemData: Total number of itemData. Mandatory.
 *				cacheItemData: Virtuallist will ask itemData between minIdx and maxIdx.
 *				Developers can implement this function for preparing data.
 *				Optional.
 *
 *		centerTo ( selector )
 *			: Center the particular item with the class name on the VirtualGrid's display area.;
 *			i.e., this method selects an item in the data elements of grid using the class name and
 *			moves the data elements inside the widget to display the row containing the selected item
 *			in the middle of the screen.
 *			If multiple items are matched with the class name, the first matched item will be selected.
 *			This method is only available when "data-rotation" attribute is "true".
 *
 *		resize ()
 *			: Rearrange items to fit a new widget size.
 *
 * Events:
 *		scrollstart : : This event triggers when a user begin to move the scroll on VirtualGrid.
 *		scrollupdate : : This event triggers while a user moves the scroll on VirtualGrid.
 *		scrollstop : This event triggers when a user stop the scroll on VirtualGrid.
 *		select : This event triggers when a cell is selected.
 *
 * Examples:
 *
 *			<script id="tizen-demo-namecard" type="text/x-jquery-tmpl">
 *				<div class="ui-demo-namecard">
 *					<div class="ui-demo-namecard-pic">
 *						<img class="ui-demo-namecard-pic-img" src="${TEAM_LOGO}" />
 *					</div>
 *					<div class="ui-demo-namecard-contents">
 *						<span class="name ui-li-text-main">${NAME}</span>
 *						<span class="active ui-li-text-sub">${ACTIVE}</span>
 *						<span class="from ui-li-text-sub">${FROM}</span>
 *					</div>
 *				</div>
 *			</script>
 *			<div id="virtualgrid-demo" data-role="virtualgrid" data-template="tizen-demo-namecard" >
 *			</div>
 *
 */

// most of following codes are derived from jquery.mobile.scrollview.js

/**
	@class VirtualGrid
	In the Web environment, it is challenging to display large amount of data in a list, such as displaying a contact list of over 1000 list items. It takes time to display the entire list in HTML and the DOM manipulation is complex.

	The virtual grid widget is used to display a list of unlimited data elements on the screen for better performance. This widget displays the data in the grid format by reusing the existing grid control space. Virtual grids are based on the jQuery.template plugin as described in the jQuery documentation for jQuery.template plugin.

	To add a virtual grid widget to the application, use the following code:

		<script id="tizen-demo-namecard" type="text/x-jquery-tmpl">
			<div class="ui-demo-namecard">
				<div class="ui-demo-namecard-pic">
					<img class="ui-demo-namecard-pic-img" src="${TEAM_LOGO}" />
				</div>
				<div class="ui-demo-namecard-contents">
				<span class="name ui-li-text-main">${NAME}</span>
				</div>
			</div>
		</script>
		<div id="virtualgrid-demo" data-role="virtualgrid" data-template="tizen-demo-namecard">
		</div>
*/
/**
	@property {String} data-template
	Specifies the jQuery.template element ID.
	The jQuery.template must be defined. The template style can use rem units to support scalability.
*/
/**
	@property {String} data-direction
	Defines the scroll direction. The direction options are x (horizontal) and y (vertical).
	The default value is y.
*/
/**
	@property {Boolean} data-rotation
	Defines whether the data elements are displayed from the beginning of the list again once the end of file is reached.
	The default value is false.
*/
/**
	@event scrollstart
	The scrollstart event is fired when the user starts scrolling through the grid:

		<div data-role="virtualgrid" data-scroll="y" data-template="tizen-demo-namecard"></div>
		$(".selector").on("scrollstart", function(event, ui)
		{
		// Handle the scrollstart event
		});
*/
/**
	@event scrollupdate
	The scrollupdate event is fired when the user moves the scroll bar in the grid:

		<div data-role="virtualgrid" data-scroll="y" data-template="tizen-demo-namecard"></div>
		$(".selector").on("scrollupdate", function(event, ui)
		{
		// Handle the scrollupdate event
		});
*/
/**
	@event scrollstop
	The scrollstop event is fired when the user stops scrolling:

		<div data-role="virtualgrid" data-scroll="y" data-template="tizen-demo-namecard"></div>
		$(".selector").on("scrollstop", function(event, ui)
		{
		// Handle the scrollstop event
		});
*/
/**
	@event select
	The select event is fired when a virtual grid cell is selected:

		<div data-role="virtualgrid" data-scroll="y" data-template="tizen-demo-namecard"></div>
		$(".selector").on("select", function(event, ui)
		{
		// Handle the select event
		});
*/
/**
	@method create
	@param {function} itemData(index)
	@param {Number} numItemData
	@param {function} cacheItemData(minIndex, maxIndex)
	The create method is used to call the jQuery _create method. In the method parameters:

	function itemData(index) returns the JSON object matched with the given index. The index value is between 0 and numItemData-1.<br/>
	number numItemData or function numItemData() defines or returns a static number of items.<br/>
	function cacheItemData(minIndex, maxIndex) prepares the JSON data. This method is called before calling the itemData() method with index values between minIndex and maxIndex.<br/>

		<div data-role="virtualgrid" data-scroll="y" data-template="tizen-demo-namecard"></div>
			function itemData(idx)
			{
				return DATA[idx];
			}
			function cacheItemData(minIdx, maxIdx)
			{
			// Prepare JSON data between minIdx and maxIdx
			}
			var numItemData = DATA.length;
			$(".selector").virtualgrid("create",
			{
				itemData, numItemData, cacheItemData
			});
*/
/**
	@method centerTo
	The centerTo method is used to center the particular item with the class name on the VirtualGrid's display area. If multiple items are matched with the class name, the first matched item will be selected. This method is only available when "data-rotation" attribute is "true".

		<div data-role="virtualgrid" data-scroll="y" data-rotation="true" data-template="tizen-demo-namecard"></div>
		$(".selector").virtualgrid("centerTo", selector);
*/
/**
	@method resize
	The resize method is used to rearrange items to fit a new widget size. :

		<div data-role="virtualgrid" data-scroll="y" data-template="tizen-demo-namecard"></div>
		$(".selector").virtualgrid("resize");

	@since Tizen2.0
*/

( function ( $, window, document, undefined ) {

	function circularNum ( num, total ) {
		var n = num % total;
		if ( n < 0 ) {
			n = total + n;
		}
		return n;
	}

	function MomentumTracker ( options ) {
		this.options = $.extend( {}, options );
		this.easing = "easeOutQuad";
		this.reset();
	}

	var tstates = {
			scrolling : 0,
			done : 1
		},
		_OVERFLOW_DIR_NONE = 0,		/* ENUM */
		_OVERFLOW_DIR_UP = 1,		/* ENUM */
		_OVERFLOW_DIR_DOWN = -1,	/* ENUM */
		imgTagSrcAttrRE = /src\s*=\s*[\"\'][\w\/.]+.[A-z]+[\"\']/;

	function getCurrentTime () {
		return Date.now();
	}

	$.extend( MomentumTracker.prototype, {
		start : function ( pos, speed, duration ) {
			this.state = ( speed !== 0 ) ? tstates.scrolling : tstates.done;
			this.pos = pos;
			this.speed = speed;
			this.duration = duration;

			this.fromPos = 0;
			this.toPos = 0;

			this.startTime = getCurrentTime();
		},

		reset : function () {
			this.state = tstates.done;
			this.pos = 0;
			this.speed = 0;
			this.duration = 0;
		},

		update : function () {
			var state = this.state, duration, elapsed, dx, x;

			if ( state == tstates.done ) {
				return this.pos;
			}
			duration = this.duration;
			elapsed = getCurrentTime () - this.startTime;
			elapsed = elapsed > duration ? duration : elapsed;
			dx = this.speed * ( 1 - $.easing[this.easing]( elapsed / duration, elapsed, 0, 1, duration ) );
			x = this.pos + ( dx / 2 );
			this.pos = x;

			if ( elapsed >= duration ) {
				this.state = tstates.done;
			}
			return this.pos;
		},

		done : function () {
			return this.state == tstates.done;
		},

		getPosition : function () {
			return this.pos;
		}
	});

	jQuery.widget ( "mobile.virtualgrid", jQuery.mobile.widget, {
		options : {
			// virtualgrid option
			template : "",
			direction : "y",
			rotation : false
		},

		create : function () {
			this._create.apply( this, arguments );
		},

		_create : function ( args ) {
			$.extend( this, {
				// view
				_$view : null,
				_$clip : null,
				_$rows : null,
				_tracker : null,
				_viewSize : 0,
				_clipSize : 0,
				_cellSize : undefined,
				_currentItemCount : 0,
				_itemCount : 1,
				_inheritedSize : null,

				// timer
				_timerInterval : 0,
				_timerID : 0,
				_timerCB : null,
				_lastMove : null,

				// Data
				_itemData : function ( idx ) { return null; },
				_numItemData : 0,
				_cacheItemData : function ( minIdx, maxIdx ) { },
				_totalRowCnt : 0,
				_templateText : null,
				_maxViewSize : 0,
				_modifyViewPos : 0,
				_maxSizeExceptClip : 0,
				_maxSize : 0,

				// axis - ( true : x , false : y )
				_direction : false,
				_didDrag : true,
				_reservedPos : 0,
				_scalableSize : 0,
				_eventPos : 0,
				_nextPos : 0,
				_movePos : 0,
				_lastY : 0,
				_speedY : 0,
				_lastX : 0,
				_speedX : 0,
				_rowsPerView : 0,
				_fragment : null,

				_filterRatio : 0.9,

				_overflowStartPos : 0,
				_overflowDir : 0,
				_overflowMaxDragDist : 100
			});

			var self = this,
				$dom = $( self.element ),
				opts = self.options,
				$item = null;

			// itemData
			// If mandatory options are not given, Do nothing.
			if ( !args ) {
				return ;
			}

			if ( !self._loadData( args ) ) {
				return;
			}

			// make a fragment.
			self._fragment = document.createDocumentFragment();

			// read defined properties(width and height) from dom element.
			self._inheritedSize = self._getinheritedSize( self.element );

			// set a scroll direction.
			self._direction = opts.direction === 'x' ? true : false;

			// make view layer
			self._$clip = $dom.addClass( "ui-scrollview-clip" ).addClass( "ui-virtualgrid-view" );
			$item = $( document.createElement( "div" ) ).addClass( "ui-scrollview-view" );
			self._clipSize =  self._calculateClipSize();
			self._$clip.append( $item );
			self._$view = $item;
			self._$clip.css( "overflow", "hidden" );
			self._$view.css( "overflow", "hidden" );

			// inherit from scrollview widget.
			self._scrollView = $.tizen.scrollview.prototype;
			self._initScrollView();

			// create tracker.
			self._createTracker();
			self._makePositioned( self._$clip );
			self._timerInterval = 1000 / self.options.fps;

			self._timerID = 0;
			self._timerCB = function () {
				self._handleMomentumScroll();
			};
			$dom.closest( ".ui-content" ).addClass( "ui-virtualgrid-content" ).css( "overflow", "hidden" );

			// add event handler.
			self._addBehaviors();

			self._currentItemCount = 0;
			self._createOverflowArea();
			self._createScrollBar();
			self.refresh();
		},

		// The argument is checked for compliance with the specified format.
		// @param args   : Object
		// @return boolean
		_loadData : function ( args ) {
			var self = this;

			if ( args.itemData && typeof args.itemData == 'function'  ) {
				self._itemData = args.itemData;
			} else {
				return false;
			}
			if ( args.numItemData ) {
				if ( typeof args.numItemData == 'function' ) {
					self._numItemData = args.numItemData( );
				} else if ( typeof args.numItemData == 'number' ) {
					self._numItemData = args.numItemData;
				} else {
					return false;
				}
			} else {
				return false;
			}
			self._getObjectNames( self._itemData( 0 ) );
			return true;
		},

		// Make up the first screen.
		_initLayout: function () {
			var self = this,
				opts = self.options,
				i,
				$row;

			for ( i = -1; i < self._rowsPerView + 1; i += 1 ) {
				$row = self._$rows[ circularNum( i, self._$rows.length ) ];
				self._$view.append( $row );
			}
			self._setElementTransform( -self._cellSize );

			self._replaceRow( self._$view[0].firstChild, self._totalRowCnt - 1 );
			if ( opts.rotation && self._rowsPerView >= self._totalRowCnt ) {
				self._replaceRow( self._$view[0].lastChild, 0 );
			}
			self._setViewSize();
		},

		_setViewSize : function () {
			var self = this,
				height = 0,
				width = 0;

			if ( self._direction ) {
				width = self._cellSize * ( self._rowsPerView + 2 );
				width = parseInt( width, 10 ) + 1;
				self._$view.width( width );
				self._viewSize = self._$view.width();
			} else {
				self._$view.height( self._cellSize * ( self._rowsPerView + 2 ) );
				self._$clip.height( self._clipSize );
				self._viewSize = self._$view.height();
			}
		},

		_getViewWidth : function () {
			var self = this;
			return self._maxSize;
		},

		_getViewHeight : function () {
			var self = this;
			return self._maxSize;
		},

		refresh : function () {
			var self = this,
				opts = self.options,
				width = 0,
				height = 0,
				$template = null;

			$template = $( "#" + opts.template );
			if ( !$template ) {
				return ;
			}
			self._templateText = self._insertAriaAttrToTmpl( $template.text() );

			width = self._calculateClipWidth();
			height = self._calculateClipHeight();
			self._$view.width( width ).height( height );
			self._$clip.width( width ).height( height );

			self._clipSize = self._calculateClipSize();
			self._calculateColumnSize();
			self._initPageProperty();
			self._setScrollBarSize();
		},

		_initPageProperty : function () {
			var self = this,
				rowsPerView = 0,
				$child,
				columnCount = 0,
				totalRowCnt = 0,
				attributeName = self._direction ? "width" : "height";

			columnCount = self._calculateColumnCount();

			totalRowCnt = parseInt( self._numItemData / columnCount, 10 );
			self._totalRowCnt = self._numItemData % columnCount === 0 ? totalRowCnt : totalRowCnt + 1;
			self._itemCount = columnCount;

			if ( self._cellSize <= 0 ) {
				return ;
			}

			rowsPerView = self._clipSize / self._cellSize;
			rowsPerView = Math.ceil( rowsPerView );
			self._rowsPerView = parseInt( rowsPerView, 10 );

			$child = $( self._makeRows( rowsPerView + 2 ) );
			self._$view.append( $child.children() );
			self._$view.children().css( attributeName, self._cellSize + "px" );
			self._$rows = self._$view.children().detach();

			self._reservedPos = -self._cellSize;
			self._scalableSize = -self._cellSize;

			self._initLayout();

			self._blockScroll = self._rowsPerView > self._totalRowCnt;
			self._maxSizeExceptClip = ( self._totalRowCnt - self._rowsPerView ) * self._cellSize;
			self._maxSize = self._totalRowCnt * self._cellSize;
			self._maxViewSize = ( self._rowsPerView ) * self._cellSize;
			self._modifyViewPos = -self._cellSize;
			if ( self._clipSize < self._maxViewSize ) {
				self._modifyViewPos = ( -self._cellSize ) + ( self._clipSize - self._maxViewSize );
			}
		},

		_getinheritedSize : function ( elem ) {
			var $target = $( elem ),
				height,
				width,
				NODETYPE = { ELEMENT_NODE : 1, TEXT_NODE : 3 },
				ret = {
					isDefinedWidth : false,
					isDefinedHeight : false,
					width : 0,
					height : 0
				};

			while ( $target[0].nodeType === NODETYPE.ELEMENT_NODE && ( ret.isDefinedWidth === false || ret.isHeightDefined === false ) ) {
				height = $target[0].style.height;
				width = $target[0].style.width;

				if ( ret.isDefinedHeight === false && height !== "" ) {
					// Size was defined
					ret.isDefinedHeight = true;
					ret.height = parseInt( height, 10 );
				}

				if ( ret.isDefinedWidth === false && width !== "" ) {
					// Size was defined
					ret.isDefinedWidth = true;
					ret.width = parseInt( width, 10 );
				}
				$target = $target.parent();
				if ( $target.hasClass( "ui-content" ) ) {
					break;
				}
			}
			return ret;
		},

		_resize : function () {
			var self = this,
				ret = null,
				rowsPerView = 0,
				itemCount = 0,
				totalRowCnt = 0,
				diffRowCnt = 0,
				clipSize = 0,
				prevcnt = 0,
				clipPosition = 0,
				rowsLength = 0,
				row = null,
				size = 0;

			if ( self._direction ) {
				size = self._calculateClipHeight();
				self._$view.height( size );
				self._$clip.height( size );
			} else {
				size = self._calculateClipWidth();
				self._$view.width( size );
				self._$clip.width( size );
			}

			itemCount = self._calculateColumnCount();
			if ( itemCount != self._itemCount ) {
				totalRowCnt = parseInt( self._numItemData / itemCount, 10 );
				self._totalRowCnt = self._numItemData % itemCount === 0 ? totalRowCnt : totalRowCnt + 1;
				prevcnt = self._itemCount;
				self._itemCount = itemCount;
				clipPosition = self._getClipPosition();
				self._$view.hide();

				diffRowCnt = self._replaceRows( itemCount, prevcnt, self._totalRowCnt, clipPosition );
				self._maxSizeExceptClip = ( self._totalRowCnt - self._rowsPerView ) * self._cellSize;
				self._maxSize = self._totalRowCnt * self._cellSize;
				self._scalableSize += ( -diffRowCnt ) * self._cellSize;
				self._reservedPos  += ( -diffRowCnt ) * self._cellSize;
				self._setScrollBarSize();
				self._setScrollBarPosition( diffRowCnt );

				self._$view.show();
			}

			clipSize = self._calculateClipSize();
			if ( clipSize !== self._clipSize ) {
				rowsPerView = clipSize / self._cellSize;
				rowsPerView = parseInt( Math.ceil( rowsPerView ), 10 );

				if ( rowsPerView > self._rowsPerView ) {
					// increase row.
					self._increaseRow( rowsPerView - self._rowsPerView );
				} else if ( rowsPerView < self._rowsPerView ) {
					// decrease row.
					self._decreaseRow( self._rowsPerView - rowsPerView );
				}
				self._$rows = self._$view.children();
				self._$rows.sort( function ( a, b ) {
					return a.getAttribute( "row-index" ) - b.getAttribute( "row-index" );
				});

				self._rowsPerView = rowsPerView;
				self._clipSize = clipSize;
				self._blockScroll = self._rowsPerView > self._totalRowCnt;
				self._maxSizeExceptClip = ( self._totalRowCnt - self._rowsPerView ) * self._cellSize;
				self._maxSize = self._totalRowCnt * self._cellSize;
				self._maxViewSize = ( self._rowsPerView ) * self._cellSize;
				if ( self._clipSize < self._maxViewSize ) {
					self._modifyViewPos = ( -self._cellSize ) + ( self._clipSize - self._maxViewSize );
				}
				if ( self._direction ) {
					self._$clip.width( self._clipSize );
				} else {
					self._$clip.height( self._clipSize );
				}
				self._setScrollBarSize();
				self._setScrollBarPosition( 0 );
				self._setViewSize();
			}
		},

		resize : function () {
			var self = this,
				height = 0,
				$virtualgrid = $( ".ui-virtualgrid-view" );

			self._inheritedSize = self._getinheritedSize( self.element );

			if ( $virtualgrid.length !== 0 ) {
				self._resize();
			}
		},

		_initScrollView : function () {
			var self = this,
				oldDirection = self.options.direction;
			$.extend( self.options, self._scrollView.options );
			self.options.direction = oldDirection;
			self.options.moveThreshold = 10;
			self.options.showScrollBars = false;
			self._getScrollHierarchy = self._scrollView._getScrollHierarchy;
			self._makePositioned =  self._scrollView._makePositioned;
			self._set_scrollbar_size = self._scrollView._set_scrollbar_size;
			self._setStyleTransform = self._scrollView._setElementTransform;
			self._hideOverflowIndicator = self._scrollView._hideOverflowIndicator;
			self._showOverflowIndicator = self._scrollView._showOverflowIndicator;
			self._setGestureScroll = self._scrollView._setGestureScroll;
		},

		_createTracker : function () {
			var self = this;

			self._tracker = new MomentumTracker( self.options );
			if ( self._direction ) {
				self._hTracker = self._tracker;
				self._$clip.width( self._clipSize );
			} else {
				self._vTracker = self._tracker;
				self._$clip.height( self._clipSize );
			}
		},

		//----------------------------------------------------//
		//		Overflow effect
		//----------------------------------------------------//
		_createOverflowArea : function () {
			var self = this,
				prefix = "<div class=\"ui-virtualgrid-overflow-indicator-",
				suffixTop = "-top\"></div>",
				suffixBottom = "-bottom\"></div>";

			if ( self.options.rotation ) {
				return;
			}

			if ( self._direction ) {
				self._overflowTop = $( prefix + "x" + suffixTop );
				self._overflowBottom = $( prefix + "x" + suffixBottom );
			} else {
				self._overflowTop = $( prefix + "y" + suffixTop );
				self._overflowBottom = $( prefix + "y" + suffixBottom );
			}

			self._$clip.append( self._overflowTop );
			self._$clip.append( self._overflowBottom );
			self._overflowDisplayed = false;
		},

		_hideVGOverflowIndicator : function () {
			if ( this._overflowDisplayed === false ) {
				return;
			}

			this._overflowTop.animate( { opacity: 0 }, 300 );
			this._overflowBottom.animate( { opacity: 0 }, 300 );
			this._overflowDisplayed = false;
		},

		//----------------------------------------------------//
		//		Scrollbar		//
		//----------------------------------------------------//
		_createScrollBar : function () {
			var self = this,
				prefix = "<div class=\"ui-scrollbar ui-scrollbar-",
				suffix = "\"><div class=\"ui-scrollbar-track\"><div class=\"ui-scrollbar-thumb\"></div></div></div>";

			if ( self.options.rotation ) {
				return ;
			}

			if ( self._direction ) {
				self._$clip.append( prefix + "x" + suffix );
				self._hScrollBar = self._$clip.children( ".ui-scrollbar-x" );
				self._hScrollBar.find( ".ui-scrollbar-thumb" ).addClass( "ui-scrollbar-thumb-x" );
			} else {
				self._$clip.append( prefix + "y" + suffix );
				self._vScrollBar = self._$clip.children( ".ui-scrollbar-y" );
				self._vScrollBar.find( ".ui-scrollbar-thumb" ).addClass( "ui-scrollbar-thumb-y" );
			}
		},

		_setScrollBarSize: function () {
			var self = this,
				scrollBarSize = 0,
				currentSize = 0,
				$scrollBar,
				attrName,
				className;

			if ( self.options.rotation ) {
				return ;
			}

			scrollBarSize = parseInt( self._maxViewSize / self._clipSize, 10 );
			if ( self._direction ) {
				$scrollBar = self._hScrollBar.find( ".ui-scrollbar-thumb" );
				attrName = "width";
				currentSize = $scrollBar.width();
				className = "ui-scrollbar-thumb-x";
				self._hScrollBar.css( "width", self._clipSize );
			} else {
				$scrollBar = self._vScrollBar.find( ".ui-scrollbar-thumb" );
				attrName = "height";
				className = "ui-scrollbar-thumb-y";
				currentSize = $scrollBar.height();
				self._vScrollBar.css( "height", self._clipSize );
			}

			if ( scrollBarSize > currentSize ) {
				$scrollBar.removeClass( className );
				$scrollBar.css( attrName, scrollBarSize );
			} else {
				scrollBarSize = currentSize;
			}

			self._itemScrollSize = parseFloat( ( self._clipSize - scrollBarSize ) / ( self._totalRowCnt - self._rowsPerView ) );
			self._itemScrollSize = Math.round( self._itemScrollSize * 100 ) / 100;
		},

		_setScrollBarPosition : function ( di, duration ) {
			var self = this,
				$sbt = null,
				x = "0px",
				y = "0px",
				translate;

			if ( self.options.rotation ) {
				return ;
			}

			self._currentItemCount = self._currentItemCount + di;
			if ( self._vScrollBar ) {
				$sbt = self._vScrollBar.find( ".ui-scrollbar-thumb" );
				y = ( self._currentItemCount * self._itemScrollSize ) + "px";
			} else {
				$sbt = self._hScrollBar.find( ".ui-scrollbar-thumb" );
				x = ( self._currentItemCount * self._itemScrollSize ) + "px";
			}
			self._setStyleTransform( $sbt, x, y, duration );
		},

		_hideScrollBars : function () {
			var self = this,
				vclass = "ui-scrollbar-visible";

			if ( self.options.rotation ) {
				return ;
			}

			if ( self._vScrollBar ) {
				self._vScrollBar.removeClass( vclass );
			} else {
				self._hScrollBar.removeClass( vclass );
			}
		},

		_showScrollBars : function () {
			var self = this,
				vclass = "ui-scrollbar-visible";

			if ( self.options.rotation ) {
				return ;
			}

			if ( self._vScrollBar ) {
				self._vScrollBar.addClass( vclass );
			} else {
				self._hScrollBar.addClass( vclass );
			}
		},

		//----------------------------------------------------//
		//		scroll process		//
		//----------------------------------------------------//
		centerTo : function ( selector ) {
			var self = this,
				row = null,
				targetItem = null,
				targetRowIndex = -1,
				rowsLength = self._$rows.length,
				newPosition,
				i;

			if ( !self.options.rotation ) {
				return;
			}

			for ( i = 0; i < rowsLength; ++i ) {
				row = $( self._$rows[ i ] );
				targetItem = row.children( "." + selector );
				if ( targetItem.length ) {
					targetRowIndex = parseInt( row.attr( "row-index" ), 10 );
					break;
				}
			}

			if ( targetRowIndex === -1 ) {
				targetRowIndex = self._getTargetRowIndex( selector );
				if ( targetRowIndex === -1 ) {
					return;
				}
			}

			newPosition = -( targetRowIndex * self._cellSize - ( self._clipSize - self._cellSize ) / 2 );
			if ( self._direction ) {
				self.scrollTo( newPosition, 0 );
			} else {
				self.scrollTo( 0, newPosition );
			}
		},

		_getTargetRowIndex: function ( selector ) {
			var self = this,
				dataCount = self._numItemData,
				itemCount = self._itemCount,
				attrName = self._direction ? "top" : "left",
				html = "",
				targetRowIndex = self._totalRowCnt,
				i;

			for ( i = 0; i < dataCount; ++i ) {
				html = self._makeHtmlData( i, i % itemCount, attrName );
				if ( self._hasClassItem( html, selector ) ) {
					targetRowIndex = parseInt( i / itemCount, 10 );
					break;
				}
			}

			if ( targetRowIndex === self._totalRowCnt ) {
				return -1;
			}

			return targetRowIndex;
		},

		_hasClassItem: function ( html, selector ) {
			var self = this,
				classString = self._getItemClass( html );

			if ( classString.indexOf( selector ) === -1 ) {
				return false;
			}

			if ( classString.indexOf( "virtualgrid-item" ) === -1 ) {
				return false;
			}

			return true;
		},

		_getItemClass: function ( html ) {
			var classIndex = html.indexOf( "class" ),
				classBeginIndex = Math.min( html.indexOf( "\"", classIndex ), html.indexOf( "'", classIndex ) ),
				classEndIndex = Math.min( html.indexOf( "\"", classBeginIndex + 1 ), html.indexOf( "'", classBeginIndex + 1 ) );

			return html.slice( classBeginIndex + 1, classEndIndex );
		},

		scrollTo: function ( x, y, duration ) {
			var self = this;
			if ( self._direction ) {
				x -= self._cellSize;
				self._sx = self._reservedPos;
				self._reservedPos = x;
			} else {
				y -= self._cellSize;
				self._sy = self._reservedPos;
				self._reservedPos = y;
			}
			self._scrollView.scrollTo.apply( this, [ x, y, duration ] );
		},

		getScrollPosition: function () {
			if ( this.direction ) {
				return { x: -this._ry, y: 0 };
			}
			return { x: 0, y: -this._ry };
		},

		_setScrollPosition: function ( x, y ) {
			var self = this,
				sy = self._scalableSize,
				distance = self._direction ? x : y,
				dy = distance - sy,
				di = parseInt( dy / self._cellSize, 10 ),
				i = 0,
				idx = 0,
				replaceStartIdx = 0,
				realRowCount = self._rowsPerView + 2,
				rawView = self._$view[0];

			if ( self._blockScroll ) {
				if ( dy > 0 && distance >= -self._cellSize && self._scalableSize >= -self._cellSize ) {
					self._overflowDir = _OVERFLOW_DIR_UP;
				}
				if ( dy < 0 && self._scalableSize <= -( self._maxSizeExceptClip + self._cellSize ) ) {
					self._overflowDir = _OVERFLOW_DIR_DOWN;
				}
				return;
			}

			if ( ! self.options.rotation ) {
				if ( dy > 0 && distance >= -self._cellSize && self._scalableSize >= -self._cellSize ) {
					// top
					self._stopMScroll();
					self._scalableSize = -self._cellSize;
					self._setElementTransform( -self._cellSize );
					if ( self._overflowDir === _OVERFLOW_DIR_NONE ) {
						self._overflowDir = _OVERFLOW_DIR_UP;
					}
					return;
				}
				if ( dy < 0 && self._scalableSize <= -( self._maxSizeExceptClip + self._cellSize ) ) {
					// bottom
					self._stopMScroll();
					self._scalableSize = -( self._maxSizeExceptClip + self._cellSize );
					self._setElementTransform( self._modifyViewPos );
					if ( self._overflowDir === _OVERFLOW_DIR_NONE ) {
						self._overflowDir = _OVERFLOW_DIR_DOWN;
					}
					return;
				}
			}

			replaceStartIdx = ( Math.abs( di ) < realRowCount ) ? 0 : ( di > 0 ) ? di - realRowCount : di + realRowCount;
			if ( di > 0 ) { // scroll up
				for ( i = replaceStartIdx; i < di; ++i ) {
					idx = -parseInt( ( sy / self._cellSize ) + i + 3, 10 );
					self._replaceRow( rawView.lastChild, circularNum( idx, self._totalRowCnt ) );
					rawView.insertBefore( rawView.lastChild, rawView.firstChild );
				}
			} else if ( di < 0 ) { // scroll down
				for ( i = replaceStartIdx; i > di; --i ) {
					idx = self._rowsPerView - parseInt( ( sy / self._cellSize ) + i, 10 );
					self._replaceRow( rawView.firstChild, circularNum( idx, self._totalRowCnt ) );
					rawView.insertBefore( rawView.firstChild, rawView.lastChild.nextSibling );
				}
			}
			self._setScrollBarPosition( -di );
			self._scalableSize += di * self._cellSize;
			self._setElementTransform( distance - self._scalableSize - self._cellSize );
		},

		_setElementTransform : function ( value ) {
			var self = this,
				x = 0,
				y = 0;

			if ( self._direction ) {
				x = value + "px";
			} else {
				y = value + "px";
			}
			self._setStyleTransform( self._$view, x, y );
		},

		//----------------------------------------------------//
		//		Event handler		//
		//----------------------------------------------------//
		_handleMomentumScroll: function () {
			var self = this,
				opts = self.options,
				keepGoing = false,
				v = this._$view,
				x = 0,
				y = 0,
				t = self._tracker;

			if ( t ) {
				t.update();
				if ( self._direction ) {
					x = t.getPosition();
				} else {
					y = t.getPosition();
				}
				keepGoing = !t.done();
			}

			self._setScrollPosition( x, y );
			if ( !opts.rotation ) {
				keepGoing = !t.done();
				self._reservedPos = self._direction ? x : y;
				// bottom
				self._reservedPos = self._reservedPos <= (-(self._maxSizeExceptClip - self._modifyViewPos)) ? ( - ( self._maxSizeExceptClip + self._cellSize) ) : self._reservedPos;
				// top
				self._reservedPos = self._reservedPos > -self._cellSize ? -self._cellSize : self._reservedPos;
			} else {
				self._reservedPos = self._direction ? x : y;
			}
			self._$clip.trigger( self.options.updateEventName, [ { x: x, y: y } ] );

			if ( keepGoing ) {
				self._timerID = setTimeout( self._timerCB, self._timerInterval );
			} else {
				self._stopMScroll();
			}
		},

		_startMScroll: function ( speedX, speedY ) {
			var self = this;
			if ( self._direction ) {
				self._sx = self._reservedPos;
			} else {
				self._sy = self._reservedPos;
			}
			self._scrollView._startMScroll.apply( self, [ speedX, speedY ] );
		},

		_stopMScroll: function () {
			this._scrollView._stopMScroll.apply( this );
		},

		_enableTracking: function () {
			var self = this;
			self._$view.bind( self._dragMoveEvt, self._dragMoveCB );
			self._$view.bind( self._dragStopEvt, self._dragStopCB );
			self._scrollView._enableTracking.apply( self );
		},

		_disableTracking: function () {
			var self = this;
			self._$view.unbind( self._dragMoveEvt, self._dragMoveCB );
			self._$view.unbind( self._dragStopEvt, self._dragStopCB );
			self._scrollView._disableTracking.apply( self );
		},

		_handleDragStart: function ( e, ex, ey ) {
			var self = this;
			self._scrollView._handleDragStart.apply( this, [ e, ex, ey ] );
			self._eventPos = self._direction ? ex : ey;
			self._nextPos = self._reservedPos;
		},

		_handleDragMove: function ( e, ex, ey ) {
			var self = this,
				dx = ex - self._lastX,
				dy = ey - self._lastY,
				x = 0,
				y = 0,
				diffFromStartPos = 0,
				diffFromLastPos = 0,
				opacity = 0,
				overflowPos = 0,
				overFlowTarget = null;

			self._lastMove = getCurrentTime();
			self._speedX = dx;
			self._speedY = dy;

			self._didDrag = true;

			self._lastX = ex;
			self._lastY = ey;

			if ( self._direction ) {
				self._movePos = ex - self._eventPos;
				x = self._nextPos + self._movePos;
				overflowPos = ex;
			} else {
				self._movePos = ey - self._eventPos;
				y = self._nextPos + self._movePos;
				overflowPos = ey;
			}
			self._showScrollBars();
			self._setScrollPosition( x, y );
			if ( self._overflowDir !== _OVERFLOW_DIR_NONE ) {
				overFlowTarget = ( self._overflowDir === _OVERFLOW_DIR_UP ) ? self._overflowTop : self._overflowBottom;
				if ( !self._overflowDisplayed ) {
					self._overflowDisplayed = true;
					self._overflowStartPos = overflowPos;
				}
				diffFromStartPos = ( overflowPos - self._overflowStartPos ) * self._overflowDir;
				opacity = ( diffFromStartPos < 0 ) ?
							0 : ( diffFromStartPos > self._overflowMaxDragDist ) ?
								1 : ( diffFromStartPos / self._overflowMaxDragDist );
				overFlowTarget.css( "opacity", opacity );
			}

			return false;
		},

		_handleDragStop: function ( e ) {
			var self = this;

			self._reservedPos = self._movePos ? self._nextPos + self._movePos : self._reservedPos;
			self._scrollView._handleDragStop.apply( this, [ e ] );
			if ( self._overflowDir !== _OVERFLOW_DIR_NONE ) {
				self._overflowDir = _OVERFLOW_DIR_NONE;
				self._hideVGOverflowIndicator();
			}
			return self._didDrag ? false : undefined;
		},

		_addBehaviors: function () {
			var self = this;

			// scroll event handler.
			if ( self.options.eventType === "mouse" ) {
				self._dragStartEvt = "mousedown";
				self._dragStartCB = function ( e ) {
					return self._handleDragStart( e, e.clientX, e.clientY );
				};

				self._dragMoveEvt = "mousemove";
				self._dragMoveCB = function ( e ) {
					return self._handleDragMove( e, e.clientX, e.clientY );
				};

				self._dragStopEvt = "mouseup";
				self._dragStopCB = function ( e ) {
					return self._handleDragStop( e, e.clientX, e.clientY );
				};

				self._$view.bind( "vclick", function ( e ) {
					return !self._didDrag;
				} );
			} else { //touch
				self._dragStartEvt = "touchstart";
				self._dragStartCB = function ( e ) {
					var t = e.originalEvent.targetTouches[0];
					return self._handleDragStart( e, t.pageX, t.pageY );
				};

				self._dragMoveEvt = "touchmove";
				self._dragMoveCB = function ( e ) {
					var t = e.originalEvent.targetTouches[0];
					return self._handleDragMove( e, t.pageX, t.pageY );
				};

				self._dragStopEvt = "touchend";
				self._dragStopCB = function ( e ) {
					return self._handleDragStop( e );
				};
			}
			self._$view.bind( self._dragStartEvt, self._dragStartCB );

			// other events.
			self._$view.delegate( ".virtualgrid-item", "click", function ( event ) {
				var $selectedItem = $( this );
				$selectedItem.trigger( "select", this );
			} );

			$( window ).bind( "resize", function ( e ) {
				var height = 0,
					$virtualgrid = $( ".ui-virtualgrid-view" );
				if ( $virtualgrid.length !== 0 ) {
					self._resize();
				}
			} );

			$( document ).one( "pageshow", function ( event ) {
				var $page = $( self.element ).parents( ".ui-page" ),
					$header = $page.find( ":jqmData(role='header')" ),
					$footer = $page.find( ":jqmData(role='footer')" ),
					$content = $page.find( ":jqmData(role='content')" ),
					footerHeight = $footer ? $footer.height() : 0,
					headerHeight = $header ? $header.height() : 0;

				if ( $page && $content ) {
					$content.height( window.innerHeight - headerHeight - footerHeight ).css( "overflow", "hidden" );
					$content.addClass( "ui-virtualgrid-content" );
				}
			} );
		},

		//----------------------------------------------------//
		//		Calculate size about dom element.		//
		//----------------------------------------------------//
		_calculateClipSize : function () {
			var self = this,
				clipSize = 0;

			if ( self._direction ) {
				clipSize = self._calculateClipWidth();
			} else {
				clipSize = self._calculateClipHeight();
			}
			return clipSize;
		},

		_calculateClipWidth : function () {
			var self = this,
				$parent = self._$clip.parent(),
				paddingValue = 0,
				clipSize = $( window ).width();

			if ( self._inheritedSize.isDefinedWidth ) {
				return self._inheritedSize.width;
			}

			if ( $parent.hasClass( "ui-content" ) ) {
				paddingValue = parseInt( $parent.css( "padding-left" ), 10 );
				clipSize = clipSize - ( paddingValue || 0 );
				paddingValue = parseInt( $parent.css( "padding-right" ), 10 );
				clipSize = clipSize - ( paddingValue || 0 );
			} else {
				clipSize = self._$clip.width();
			}
			return clipSize;
		},

		_calculateClipHeight : function () {
			var self = this,
				$parent = self._$clip.parent(),
				header = null,
				footer = null,
				paddingValue = 0,
				clipSize = $( window ).height();

			if ( self._inheritedSize.isDefinedHeight ) {
				return self._inheritedSize.height;
			}

			if ( !$parent.hasClass( "ui-content" ) ) {
				$parent = $parent.hasClass( "ui-scrollview-view" ) ? $parent.parent() : null;
			}

			if ( $parent && $parent.length ) {
				paddingValue = parseInt( $parent.css( "padding-top" ), 10 );
				clipSize = clipSize - ( paddingValue || 0 );
				paddingValue = parseInt( $parent.css( "padding-bottom" ), 10 );
				clipSize = clipSize - ( paddingValue || 0 );
				header = $parent.siblings( ".ui-header" );
				footer = $parent.siblings( ".ui-footer" );

				if ( header ) {
					if ( header.outerHeight( true ) === null ) {
						clipSize = clipSize - ( $( ".ui-header" ).outerHeight() || 0 );
					} else {
						clipSize = clipSize - header.outerHeight( true );
					}
				}
				if ( footer ) {
					clipSize = clipSize - footer.outerHeight( true );
				}
			} else {
				clipSize = self._$clip.height();
			}
			return clipSize;
		},

		_calculateColumnSize : function () {
			var self = this,
				$tempBlock,
				$cell;

			$tempBlock = $( self._makeRows( 1 ) );
			self._$view.append( $tempBlock.children().first() );
			if ( self._direction ) {
				// x-axis
				self._viewSize = self._$view.width();
				$cell = self._$view.children().first().children().first();
				self._cellSize = $cell.outerWidth( true );
				self._cellOtherSize = $cell.outerHeight( true );
			} else {
				// y-axis
				self._viewSize = self._$view.height();
				$cell = self._$view.children().first().children().first();
				self._cellSize = $cell.outerHeight( true );
				self._cellOtherSize = $cell.outerWidth( true );
			}
			$tempBlock.remove();
			self._$view.children().remove();
		},

		_calculateColumnCount : function ( ) {
			var self = this,
				$view = self._$clip,
				viewSize = self._direction ? $view.innerHeight() : $view.innerWidth(),
				itemCount = 0 ;

			if ( self._direction ) {
				viewSize = viewSize - ( parseInt( $view.css( "padding-top" ), 10 ) + parseInt( $view.css( "padding-bottom" ), 10 ) );
			} else {
				viewSize = viewSize - ( parseInt( $view.css( "padding-left" ), 10 ) + parseInt( $view.css( "padding-right" ), 10 ) );
			}

			itemCount = parseInt( ( viewSize / self._cellOtherSize ), 10 );
			return itemCount > 0 ? itemCount : 1 ;
		},

		// Read the position of clip form property ('webkit-transform').
		// @return : number - position of clip.
		_getClipPosition : function () {
			var self = this,
				matrix = null,
				contents = null,
				result = -self._cellSize,
				$scrollview = self._$view.closest( ".ui-scrollview-view" );

			if ( $scrollview ) {
				matrix = $scrollview.css( "-webkit-transform" );
				contents = matrix.substr( 7 );
				contents = contents.substr( 0, contents.length - 1 );
				contents = contents.split( ', ' );
				result =  Math.abs( contents [5] );
			}
			return result;
		},

		//----------------------------------------------------//
		//		DOM Element handle		//
		//----------------------------------------------------//
		_makeRows : function ( count ) {
			var self = this,
				index = 0,
				row = null,
				wrapper = null;

			wrapper = self._createElement( "div" );
			wrapper.setAttribute( "class", "ui-scrollview-view" );
			for ( index = 0; index < count ; index += 1 ) {
				row = self._makeRow( index );
				if ( self._direction ) {
					row.style.top = 0;
					row.style.left = index * self._cellSize;
				}
				wrapper.appendChild( row );
			}
			return wrapper;
		},

		// make a single row block
		_makeRow : function ( rowIndex ) {
			var self = this,
				index = rowIndex * self._itemCount,
				colIndex = 0,
				blockClassName = self._direction ? "ui-virtualgrid-wrapblock-x" : "ui-virtualgrid-wrapblock-y",
				wrapBlock = self._createElement( "div" ),
				strWrapInner = "",
				attrName = self._direction ? "top" : "left";

			for ( colIndex = 0; colIndex < self._itemCount; colIndex++ ) {
				strWrapInner += self._makeHtmlData( index, colIndex, attrName );
				index += 1;
			}
			wrapBlock.innerHTML = strWrapInner;
			wrapBlock.setAttribute( "class", blockClassName );
			wrapBlock.setAttribute( "row-index", String( rowIndex ) );
			self._fragment.appendChild( wrapBlock );
			return wrapBlock;
		},

		_makeHtmlData : function ( dataIndex, colIndex, attrName ) {
			var self = this,
				htmlStr = "",
				itemData = null;

			itemData = self._itemData( dataIndex );
			if ( itemData ) {
				htmlStr = self._getConvertedTmplStr( itemData );
				htmlStr = self._insertPosToTmplStr( htmlStr, attrName, ( colIndex * self._cellOtherSize ) );
			}

			return htmlStr;
		},

		_insertPosToTmplStr : function ( tmplStr, attrName, posVal ) {
			var tagCloseIdx = tmplStr.indexOf( '>' ),
				classIdx = -1,
				firstPart,
				lastPart,
				result,
				found = false,
				targetIdx = 0,
				firstPartLen,
				i = 0;

			if ( tagCloseIdx === -1 ) {
				return;
			}

			firstPart = tmplStr.slice( 0, tagCloseIdx );
			lastPart = tmplStr.slice( tagCloseIdx, tmplStr.length );

			classIdx = firstPart.indexOf( 'class' );

			if ( classIdx !== -1 ) {
				firstPartLen = firstPart.length;
				for ( i = classIdx + 6; i < firstPartLen; i++ ) {
					if ( firstPart.charAt( i ) === "\"" || firstPart.charAt( i ) === "\'" ) {
						if ( found === false ) {
							found = true;
						} else {
							targetIdx = i;
							break;
						}
					}
				}
				result = firstPart.slice( 0, targetIdx ) + " virtualgrid-item" + firstPart.slice( targetIdx, firstPartLen ) + lastPart;
			} else {
				result = firstPart + " class=\"virtualgrid-item\"" + lastPart;
			}

			if ( !isNaN( posVal ) ) {
				result = result.replace( '>', " style=\"" + attrName + ": " + String( posVal ) + "px\">");
			}

			return result;
		},

		_increaseRow : function ( num ) {
			var self = this,
				rotation = self.options.rotation,
				totalRowCnt = self._totalRowCnt,
				rowView = self._$view[ 0 ],
				firstRow = null,
				lastRow = rowView.lastChild,
				row = null,
				headRowIndex = 0,
				tailRowIndex = 0,
				i;

			if ( !lastRow ) {
				return;
			}

			tailRowIndex = parseInt( lastRow.getAttribute( "row-index" ), 10 );
			if ( !rotation ) {
				firstRow = rowView.firstChild;
				headRowIndex = parseInt( firstRow.getAttribute( "row-index" ), 10 );
			}

			for ( i = 0 ; i < num ; ++i ) {
				if ( tailRowIndex >= totalRowCnt - 1 && !rotation ) {
					if ( headRowIndex == 0 ) {
						break;
					}

					row = self._makeRow( --headRowIndex );
					rowView.insertBefore( row, firstRow );
					firstRow = row;
				} else {
					row = self._makeRow( circularNum( ++tailRowIndex, totalRowCnt ) );
					rowView.appendChild( row );
				}

				if ( self._direction ) {
					$( row ).width( self._cellSize );
				} else {
					$( row ).height( self._cellSize );
				}
			}
		},

		_decreaseRow : function ( num ) {
			var self = this,
				rowView = self._$view[ 0 ],
				i;

			for ( i = 0 ; i < num ; ++i ) {
				rowView.removeChild( rowView.lastChild );
			}
		},

		_replaceRows : function ( curCnt, prevCnt, maxCnt, clipPosition ) {
			var self = this,
				$rows = self._$view.children(),
				prevRowIndex = 0,
				rowIndex = 0,
				diffRowCnt = 0,
				targetCnt = 1,
				filterCondition = ( self._filterRatio * self._cellSize ) + self._cellSize,
				idx = 0;

			if ( filterCondition < clipPosition ) {
				targetCnt += 1;
			}

			prevRowIndex = parseInt( $( $rows[targetCnt] ).attr( "row-index" ), 10 );
			if ( prevRowIndex === 0 ) {
				// only top.
				rowIndex = maxCnt - targetCnt;
			} else {
				rowIndex = Math.round( ( prevRowIndex * prevCnt ) / curCnt );
				if ( rowIndex + self._rowsPerView >= maxCnt ) {
					// only bottom.
					rowIndex = maxCnt - self._rowsPerView;
				}
				diffRowCnt = prevRowIndex - rowIndex;
				rowIndex -= targetCnt;
			}

			for ( idx = 0 ; idx < $rows.length ; idx += 1 ) {
				self._replaceRow( $rows[idx], circularNum( rowIndex, self._totalRowCnt ) );
				rowIndex++;
			}
			return -diffRowCnt;
		},

		_replaceRow : function ( block, index ) {
			var self = this,
				tempBlocks = null;

			while ( block.hasChildNodes() ) {
				block.removeChild( block.lastChild );
			}

			tempBlocks = self._makeRow( index );
			while ( tempBlocks.children.length ) {
				block.appendChild( tempBlocks.children[0] );
			}
			block.setAttribute( "row-index", tempBlocks.getAttribute( "row-index" ) );
			tempBlocks.parentNode.removeChild( tempBlocks );
		},

		_createElement : function ( tag ) {
			var element = document.createElement( tag );

			this._fragment.appendChild( element );
			return element;
		},

		_getObjectNames : function ( obj ) {
			var properties = [],
				name = "";

			for ( name in obj ) {
				properties.push( name );
			}
			this._properties = properties;
		},

		_getConvertedTmplStr : function ( data ) {
			var self = this,
				dataProperties = self._properties,
				i = 0,
				plainMsg,
				ret = "";

			if ( !data ) {
				return ;
			}

			plainMsg = self._templateText;
			for ( i = 0; i < dataProperties.length; i++ ) {
				plainMsg = self._strReplace( plainMsg, "${" + dataProperties[ i ] + "}" , data[ dataProperties[ i ] ] );
			}
			plainMsg = self._changeImgSrcAriaAttrFromTmpl( plainMsg );

			return plainMsg;
		},

		_changeImgSrcAriaAttrFromTmpl : function ( plainMsg ) {
			var self = this,
				ret = "",
				targetTagIdx,
				beforeTargetTag = "",
				afterTargetTag = "",
				imgFileName,
				imgSrcSlashIdx,
				temp,
				srcRegExpResult;

			temp = plainMsg;
			targetTagIdx = temp.indexOf( "$ARIA-IMG-SRC-ALT$" );
			while ( targetTagIdx !== -1 ) {
				imgFileName = "";
				beforeTargetTag = beforeTargetTag + temp.slice( 0, targetTagIdx + 19 );
				afterTargetTag = temp.slice( targetTagIdx + 19, temp.length );
				srcRegExpResult = afterTargetTag.match( imgTagSrcAttrRE );
				if ( srcRegExpResult ) {
					imgSrcSlashIdx = srcRegExpResult[0].lastIndexOf( "/" );
					if ( imgSrcSlashIdx !== -1 ) {
						imgFileName = srcRegExpResult[0].slice( imgSrcSlashIdx + 1, -1 );
					}
				}
				beforeTargetTag = beforeTargetTag.replace( "$ARIA-IMG-SRC-ALT$", imgFileName );
				temp = afterTargetTag;
				targetTagIdx = temp.indexOf( "$ARIA-IMG-SRC-ALT$" );
				ret = beforeTargetTag + afterTargetTag;
			}

			if ( ret === "" ) {
				ret = plainMsg;
			}

			return ret;
		},

		_insertAriaAttrToTmpl : function ( plainMsg ) {
			var ret = "",
				targetTagIdx,
				beforeTargetTag = "",
				afterTargetTag = "",
				temp;

			temp = plainMsg.replace( "<div", "<div tabindex=\"0\" aria-selected=\"true\"" );
			targetTagIdx = temp.indexOf( "<img" );
			if ( targetTagIdx !== -1 ) {
				while ( targetTagIdx !== -1 ) {
					beforeTargetTag = beforeTargetTag + temp.slice( 0, targetTagIdx + 4 );
					afterTargetTag = temp.slice( targetTagIdx + 4, temp.length );
					beforeTargetTag = beforeTargetTag + " role=\"img\" alt=\"$ARIA-IMG-SRC-ALT$\"";
					temp = afterTargetTag;
					targetTagIdx = temp.indexOf( "<img" );
					ret = beforeTargetTag + afterTargetTag;
				}
				temp = ret;
				targetTagIdx = temp.indexOf( "<span" );
				beforeTargetTag = "";
				while ( targetTagIdx !== -1 ) {
					beforeTargetTag = beforeTargetTag + temp.slice( 0, targetTagIdx + 5 );
					afterTargetTag = temp.slice( targetTagIdx + 5, temp.length );
					beforeTargetTag = beforeTargetTag + " aria-hidden=\"true\" tabindex=\"-1\"";
					temp = afterTargetTag;
					targetTagIdx = temp.indexOf( "<span" );
					ret = beforeTargetTag + afterTargetTag;
				}
			}

			if ( ret === "" ) {
				ret = plainMsg;
			}

			return ret;
		},

		_strReplace : function ( plainMsg, stringToFind, stringToReplace ) {
			var temp = plainMsg,
				index = plainMsg.indexOf( stringToFind );
			while ( index !== -1 ) {
				temp = temp.replace( stringToFind, stringToReplace );
				index = temp.indexOf( stringToFind );
			}
			return temp;
		}

	} );

	$( document ).bind( "pagecreate create", function ( e ) {
		$( ":jqmData(role='virtualgrid')" ).virtualgrid();
	} );
} ( jQuery, window, document ) );



(function($, undefined) {

ensureNS("jQuery.mobile.tizen");

jQuery.extend( jQuery.mobile.tizen,
{
    _widgetPrototypes: {},

    /*
     * load the prototype for a widget.
     *
     * If @widget is a string, the function looks for @widget.prototype.html in the proto-html/ subdirectory of the
     * framework's current theme and loads the file via AJAX into a string. Note that the file will only be loaded via
     * AJAX once. If two widget instances based on the same @widget value are to be constructed, the second will be
     * constructed from the cached copy of the prototype of the first instance.
     *
     * If @widget is not a string, it is assumed to be a hash containing at least one key, "proto", the value of which is
     * the string to be used for the widget prototype. if another key named "key" is also provided, it will serve as the
     * key under which to cache the prototype, so it need not be rendered again in the future.
     *
     * Given the string for the widget prototype, the following patterns occurring in the string are replaced:
     *
     *   "${FRAMEWORK_ROOT}" - replaced with the path to the root of the framework
     *
     * The function then creates a jQuery $("<div>") object containing the prototype from the string.
     *
     * If @ui is not provided, the jQuery object containing the prototype is returned.
     *
     * If @ui is provided, it is assumed to be a (possibly multi-level) hash containing CSS selectors. For every level of
     * the hash and for each string-valued key at that level, the CSS selector specified as the value is sought in the
     * prototype jQuery object and, if found, the value of the key is replaced with the jQuery object resulting from the
     * search. Additionally, if the CSS selector is of the form "#widgetid", the "id" attribute will be removed from the
     * elements contained within the resulting jQuery object. The resulting hash is returned.
     *
     * Examples:
     *
     * 1.
     * $.mobile.tizen.loadPrototype("mywidget") => Returns a <div> containing the structure from the file
     * mywidget.prototype.html located in the current theme folder of the current framework.
     *
     * 2. $.mobile.tizen.loadPrototype("mywidget", ui):
     * where ui is a hash that looks like this:
     * ui = {
     *   element1: "<css selector 1>",
     *   element2: "<css selector 2>",
     *   group1: {
     *     group1element1: "<css selector 3>",
     *     group1element1: "<css selector 4>"
     *   }
     *  ...
     * }
     *
     * In this case, after loading the prototype as in Example 1, loadPrototype will traverse @ui and replace the CSS
     * selector strings with the result of the search for the selector string upon the prototype. If any of the CSS
     * selectors are of the form "#elementid" then the "id" attribute will be stripped from the elements selected. This
     * means that they will no longer be accessible via the selector used initially. @ui is then returned thus modified.
     */

    loadPrototype: function(widget, ui) {
        var ret = undefined,
            theScriptTag = $("script[data-framework-version][data-framework-root][data-framework-theme]"),
            frameworkRootPath = theScriptTag.attr("data-framework-root")    + "/" +
                                theScriptTag.attr("data-framework-version") + "/";

        function replaceVariables(s) {
            return s.replace(/\$\{FRAMEWORK_ROOT\}/g, frameworkRootPath);
        }

        function fillObj(obj, uiProto) {
            var selector;

            for (var key in obj) {
                if (typeof obj[key] === "string") {
                    selector = obj[key];
                    obj[key] = uiProto.find(obj[key]);
                    if (selector.substring(0, 1) === "#")
                        obj[key].removeAttr("id");
                }
                else
                if (typeof obj[key] === "object")
                    obj[key] = fillObj(obj[key], uiProto);
            }
            return obj;
        }

        /* If @widget is a string ... */
        if (typeof widget === "string") {
            /* ... try to use it as a key into the cached prototype hash ... */
            ret = $.mobile.tizen._widgetPrototypes[widget];
            if (ret === undefined) {
                /* ... and if the proto was not found, try to load its definition ... */
                var protoPath = frameworkRootPath + "proto-html" + "/" +
                                theScriptTag.attr("data-framework-theme");
                $.ajax({
                    url: protoPath + "/" + widget + ".prototype.html",
                    async: false,
                    dataType: "html"
                })
                 .success(function(data, textStatus, jqXHR) {
                    /* ... and if loading succeeds, cache it and use a copy of it ... */
                    $.mobile.tizen._widgetPrototypes[widget] = $("<div>").html(replaceVariables(data));
                    ret = $.mobile.tizen._widgetPrototypes[widget].clone();
                });
            }
        }
        /* Otherwise ... */
        else {
            /* ... if a key was provided ... */
            if (widget.key !== undefined)
                /* ... try to use it as a key into the cached prototype hash ... */
                ret = $.mobile.tizen._widgetPrototypes[widget.key];

            /* ... and if the proto was not found in the cache ... */
            if (ret === undefined) {
                /* ... and a proto definition string was provided ... */
                if (widget.proto !== undefined) {
                    /* ... create a new proto from the definition ... */
                    ret = $("<div>").html(replaceVariables(widget.proto));
                    /* ... and if a key was provided ... */
                    if (widget.key !== undefined)
                        /* ... cache a copy of the proto under that key */
                        $.mobile.tizen._widgetPrototypes[widget.key] = ret.clone();
                }
            }
            else
                /* otherwise, if the proto /was/ found in the cache, return a copy of it */
                ret = ret.clone();
        }

        /* If the prototype was found/created successfully ... */
        if (ret != undefined)
            /* ... and @ui was provided */
            if (ui != undefined)
                /* ... return @ui, but replace the CSS selectors it contains with the elements they select */
                ret = fillObj(ui, ret);

        return ret;
    }
});
})(jQuery);



/* ***************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software" ),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 *
 *	Author: Minkyu Kang <mk7.kang@samsung.com>
 *	Author: Koeun Choi <koeun.choi@samsung.com>
 */

/*
 * Progress widget
 *
 * HTML Attributes
 *
 *  data-role: set to 'progress'.
 *  data-style: 'circle' or 'pending'.
 *
 * APIs
 *
 *  show(): show the progress.
 *  hide(): hide the progress.
 *  running(boolean): start or stop the running.
 *
 * Events
 *
 *  N/A
 *
 * Examples
 *
 * <li data-role="list-divider">Progress Pending</li>
 * <li>
 *	<div data-role="progress" data-style="pending" id="pending"></div>
 * </li>
 * <li data-role="list-divider">Progress ~ing</li>
 * <li>
 *	<div data-role="progress" data-style="circle" id="progress"></div>Loading..
 * </li>
 *
 * $("#pending").progress( "running", true );
 * $("#progress").progress( "running", true );
 *
 */

/**
	@class Progress
	The progress widget shows that an operation is in progress. <br/>To add a progress widget to the application, use the following code:

		<div data-role="progress" data-style="circle"></div>
*/
/**
	@property {String} data-style
	Sets the style of the progress widget. The style options are pending (pending progress style) and circle (circular progress status style).
*/
/**
	@method running
	The running method is used to set the current running state of the pending or circular progress widget:

		<div id="foo" data-role="progress" data-style="pending"></div>
		$("#foo").progress("running", true);
*/
/**
	@method show
	The show method is used to show the pending or circular progress widget:

		<div id="foo" data-role="progress" data-style="pending"></div>
		$("#foo").progress("show");
*/
/**
	@method hide
	The show method is used to hide the pending or circular progress widget:

		<div id="foo" data-role="progress" data-style="pending"></div>
		$("#foo").progress("hide");
*/

(function ( $, window, undefined ) {
	$.widget( "tizen.progress", $.mobile.widget, {
		options: {
			style: "circle",
			running: false
		},

		show: function () {
			$( this.element ).show();
		},

		hide: function () {
			$( this.element ).hide();
		},

		_start: function () {
			if ( !this.init ) {
				$( this.element ).append( this.html );
				this.init = true;
			}

			this.show();

			$( this.element )
				.find( ".ui-progress-" + this.options.style )
				.addClass( this.runningClass );
		},

		_stop: function () {
			$( this.element )
				.find( ".ui-progress-" + this.options.style )
				.removeClass( this.runningClass );
		},

		running: function ( running ) {
			if ( running === undefined ) {
				return this.options.running;
			}

			this._setOption( "running", running );
		},

		_setOption: function ( key, value ) {
			if ( key === "running" ) {
				if ( typeof value !== "boolean" ) {
					window.alert( "running value MUST be boolean type!" );
					return;
				}

				this.options.running = value;
				this._refresh();
			}
		},

		_refresh: function () {
			if ( this.options.running ) {
				this._start();
			} else {
				this._stop();
			}
		},

		_create: function () {
			var self = this,
				element = this.element,
				style = element.jqmData( "style" ),
				_html,
				runningClass;

			if ( style ) {
				this.options.style = style;
			} else {
				style = this.options.style;
			}

			if ( style == "circle" ) {
				$( this.element ).addClass("ui-progress-container-circle");

				_html =	'<div class="ui-progress-circle"></div>';
			} else if ( style === "pending" ) {
				$( this.element ).addClass("ui-progressbar");

				_html = '<div class="ui-progressbar-bg">' +
						'<div class="ui-progress-pending"></div>' +
					'</div>';
			}

			this.html = $( _html );

			runningClass = "ui-progress-" + style + "-running";

			$.extend( this, {
				init: false,
				runningClass: runningClass
			} );

			if ( style === "pending" ) {
				$( this.element ).append( this.html );
				this.init = true;
			}

			this._refresh();
		}
	} ); /* End of widget */

	$( document ).bind( "pagecreate create", function ( e ) {
		$( e.target ).find( ":jqmData(role='progress')" ).progress();
	} );
}( jQuery, this ));



/*
 *
 * This software is licensed under the MIT licence (as defined by the OSI at
 * http://www.opensource.org/licenses/mit-license.php)
 * 
 * ***************************************************************************
 * Copyright (C) 2011 by Intel Corporation Ltd.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software" ),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 */

// Base class for widgets that need the following features:
//
// I. HTML prototype loading
//
// This class provides HTML prototype loading for widgets. That is, the widget implementation specifies its HTML portions
// in one continuous HTML snippet, and it optionally provides an object containing selectors into the various parts of the
// HTML snippet. This widget loads the HTML snippet into a jQuery object, and optionally assigns jQuery objects to each of
// the selectors in the optionally provided object.
//
// To use this functionality you can either derive from this class, or you can call its prototype's gtype method.
//
// 1. Widgets deriving from this class should define _htmlProto as part of their prototype declaration. _htmlProto looks like
// this:
//
// _htmlProto: {
//     source: string|jQuery object (optional) default: string - The name of the widget
//     ui: {
//         uiElement1: "#ui-element-1-selector",
//         uiElement2: "#ui-element-2-selector",
//         ...
//         subElement: {
//             subElement1: "#sub-element-1-selector",
//             subElement2: "#sub-element-2-selector",
//             ...
//         }
//         ...
//     }
// }
//
// If neither 'source' nor 'ui' are defined, you must still include an empty _htmlProto key (_htmlProto: {}) to indicate
// that you wish to make use of this feature. This will cause a prototype HTML file named after your widget to be loaded.
// The loaded prototype will be placed into your widget's prototype's _protoHtml.source key.
//
// If 'source' is defined as a string, it is the name of the widget (including namespace). This is the default. If your
// widget's HTML prototype is loaded via AJAX and the name of the AJAX file is different from the name of your widget
// (that is, it is not "<widgetName>.prototype.html", then you should explicitly define 'source' as:
//
// If you wish to load HTML prototypes via AJAX, modify the getProtoPath() function defined below to reflect the directory
// structure holding your widget HTML prototypes.
//
// source: "alternateWidgetName"
//
// If AJAX loading fails, source is set to a jQuery object containing a div with an error message. You can check whether
// loading failed via the jQuery object's jqmData( "tizen.widgetex.ajax.fail" ) data item. If false, then the jQuery object
// is the actual prototype loaded via AJAX or present inline. Otherwise, the jQuery object is the error message div.
//
// If 'source' is defined as a jQuery object, it is considered already loaded.
//
// if 'ui' is defined inside _htmlProto, It is assumed to be an object such that every one of its keys is either a string,
// or another object with the same properties as itself.
//
// When a widget is instantiated, the HTML prototype is loaded if not already present in the prototype. If 'ui' is present
// inside _htmlProto, the prototype is cloned. Then, a new structure is created based on 'ui' with each selector replaced
// by a jQuery object containing the results of performing .find() on the prototype's clone with the filter set to the
// value of the string. In the special case where the selector starts with a '#', the ID is removed from the element after
// it is assigned into the structure being created. This structure is then made accessible from the widget instance via
// the '_ui' key (i.e., this._ui).
//
// 2. Use the loadPrototype method when your widget does not derive from $.tizen.widgetex:
// Add _htmlProto to your widget's prototype as described above. Then, in your widget's _create() method, call
// loadPrototype in the following manner:
//
// $.tizen.widgetex.loadPrototype.call(this, "namespace.widgetName" );
//
// Thereafter, you may use the HTML prototype from your widget's prototype or, if you have specified a 'ui' key in your
// _htmlProto key, you may use this._ui from your widget instance.
//
// II. realize method
//
// When a widget is created, some of its properties cannot be set immediately, because they depend on the widths/heights
// of its constituent elements. They can only be calculated when the page containing the widget is made visible via the
// "pageshow" event, because widths/heights always evaluate to 0 when retrieved from a widget that is not visible. When
// you inherit from widgetex, you can add a "_realize" function to your prototype. This function will be called once right
// after _create() if the element that anchors your widget is on a visible page. Otherwise, it will be called when the
// page to which the widget belongs emits the "pageshow" event.
//
// NB: If your widget is inside a container which is itself not visible, such as an expandable or a collapsible, your
// widget will remain hidden even though "pageshow" is fired and therefore _realize is called. In this case, widths and
// heights will be unreliable even during _realize.
//
// III. systematic option handling
//
// If a widget has lots of options, the _setOption function can become a long switch for setting each recognized option.
// It is also tempting to allow options to determine the way a widget is created, by basing decisions on various options
// during _create(). Often, the actions based on option values in _create() are the same as those in _setOption. To avoid
// such code duplication, this class calls _setOption once for each option after _create() has completed.
//
// Furthermore, to avoid writing long switches in a widget's _setOption method, this class implements _setOption in such
// a way that, for any given option (e.g. "myOption" ), _setOption looks for a method _setMyOption in the widget's
// implementation, and if found, calls the method with the value of the option.
//
// If your widget does not inherit from widgetex, you can still use widgetex' systematic option handling:
// 1. define the _setOption method for your widget as follows:
//      _setOption: $.tizen.widgetex.prototype._setOption
// 2. Call this._setOptions(this.options) from your widget's _create() function.
// 3. As with widgetex-derived widgets, implement a corresponding _setMyOptionName function for each option myOptionName
// you wish to handle.
//
// IV. systematic value handling for input elements
//
// If your widget happens to be constructed from an <input> element, you have to handle the "value" attribute specially,
// and you have to emit the "change" signal whenever it changes, in addition to your widget's normal signals and option
// changes. With widgetex, you can assign one of your widget's "data-*" properties to be synchronized to the "value"
// property whenever your widget is constructed onto an <input> element. To do this, define, in your prototype:
//
// _value: {
//      attr: "data-my-attribute",
//      signal: "signal-to-emit"
// }
//
// Then, call this._setValue(newValue) whenever you wish to set the value for your widget. This will set the data-*
// attribute, emit the custom signal (if set) with the new value as its parameter, and, if the widget is based on an
// <input> element, it will also set the "value" attribute and emit the "change" signal.
//
// "attr" is required if you choose to define "_value", and identifies the data-attribute to set in addition to "value",
// if your widget's element is an input.
// "signal" is optional, and will be emitted when setting the data-attribute via this._setValue(newValue).
//
// If your widget does not derive from widgetex, you can still define "_value" as described above and call
// $.tizen.widgetex.setValue(widget, newValue).
//
// V. Systematic enabled/disabled handling for input elements
//
// widgetex implements _setDisabled which will disable the input associated with this widget, if any. Thus, if you derive
// from widgetex and you plan on implementing the disabled state, you should chain up to
// $.tizen.widgetex.prototype._setDisabled(value), rather than $.Widget.prototype._setOption( "disabled", value).

(function ($, undefined) {

// Framework-specific HTML prototype path for AJAX loads
	function getProtoPath() {
		var theScriptTag = $( "script[data-framework-version][data-framework-root][data-framework-theme]" );

		return (theScriptTag.attr( "data-framework-root" ) + "/" +
				theScriptTag.attr( "data-framework-version" ) + "/themes/" +
				theScriptTag.attr( "data-framework-theme" ) + "/proto-html" );
	}

	$.widget( "tizen.widgetex", $.mobile.widget, {
		_createWidget: function () {
			$.tizen.widgetex.loadPrototype.call( this, this.namespace + "." + this.widgetName );
			$.mobile.widget.prototype._createWidget.apply( this, arguments );
		},

		_init: function () {
			// TODO THIS IS TEMPORARY PATCH TO AVOID CTXPOPUP PAGE CRASH
			if ( this.element === undefined ) {
				return;
			}

			var page = this.element.closest( ".ui-page" ),
				self = this,
				myOptions = {};

			if ( page.is( ":visible" ) ) {
				this._realize();
			} else {
				page.bind( "pageshow", function () { self._realize(); } );
			}

			$.extend( myOptions, this.options );

			this.options = {};

			this._setOptions( myOptions );
		},

		_getCreateOptions: function () {
			// if we're dealing with an <input> element, value takes precedence over corresponding data-* attribute, if a
			// mapping has been established via this._value. So, assign the value to the data-* attribute, so that it may
			// then be assigned to this.options in the superclass' _getCreateOptions

			if (this.element.is( "input" ) && this._value !== undefined) {
				var theValue =
					( ( this.element.attr( "type" ) === "checkbox" || this.element.attr( "type" ) === "radio" )
							? this.element.is( ":checked" )
									: this.element.is( "[value]" )
									? this.element.attr( "value" )
											: undefined);

				if ( theValue != undefined ) {
					this.element.attr( this._value.attr, theValue );
				}
			}

			return $.mobile.widget.prototype._getCreateOptions.apply( this, arguments );
		},

		_setOption: function ( key, value ) {
			var setter = "_set" + key.replace(/^[a-z]/, function (c) { return c.toUpperCase(); } );

			if ( this[setter] !== undefined ) {
				this[setter]( value );
			} else {
				$.mobile.widget.prototype._setOption.apply( this, arguments );
			}
		},

		_setDisabled: function ( value ) {
			$.Widget.prototype._setOption.call( this, "disabled", value );
			if ( this.element.is( "input" ) ) {
				this.element.attr( "disabled", value );
			}
		},

		_setValue: function ( newValue ) {
			$.tizen.widgetex.setValue( this, newValue );
		},

		_realize: function () {}
	} );

	$.tizen.widgetex.setValue = function ( widget, newValue ) {
		if ( widget._value !== undefined ) {
			var valueString = ( widget._value.makeString ? widget._value.makeString(newValue) : newValue ),
				inputType;

			widget.element.attr( widget._value.attr, valueString );
			if ( widget._value.signal !== undefined ) {
				widget.element.triggerHandler( widget._value.signal, newValue );
			}

			if ( widget.element.is( "input" ) ) {
				inputType = widget.element.attr( "type" );

				// Special handling for checkboxes and radio buttons, where the presence of the "checked" attribute is really
				// the value
				if ( inputType === "checkbox" || inputType === "radio" ) {
					if ( newValue ) {
						widget.element.attr( "checked", true );
					} else {
						widget.element.removeAttr( "checked" );
					}
				} else {
					widget.element.attr( "value", valueString );
				}

				widget.element.trigger( "change" );
			}
		}
	};

	$.tizen.widgetex.assignElements = function (proto, obj) {
		var ret = {},
			key;

		for ( key in obj ) {
			if ( ( typeof obj[key] ) === "string" ) {
				ret[key] = proto.find( obj[key] );
				if ( obj[key].match(/^#/) ) {
					ret[key].removeAttr( "id" );
				}
			} else {
				if ( (typeof obj[key]) === "object" ) {
					ret[key] = $.tizen.widgetex.assignElements( proto, obj[key] );
				}
			}
		}

		return ret;
	};

	$.tizen.widgetex.loadPrototype = function ( widget, ui ) {
		var ar = widget.split( "." ),
			namespace,
			widgetName,
			source,
			noSource = false,
			htmlProto,
			protoPath;

		if ( ar.length == 2 ) {
			namespace = ar[0];
			widgetName = ar[1];

			// If htmlProto is defined
			if ( $[namespace][widgetName].prototype._htmlProto !== undefined ) {
				// If no source is defined, use the widget name
				source = $[namespace][widgetName].prototype._htmlProto.source;
				if ( source === undefined ) {
					source = widgetName;
					noSource = true;
				}

				// Load the HTML prototype via AJAX if not defined inline
				if ( typeof source === "string" ) {
					if ( noSource ) {	// use external htmlproto file
						// Establish the path for the proto file
						widget = source;
						protoPath = getProtoPath();

						// Make the AJAX call
						$.ajax( {
							url: protoPath + "/" + widget + ".prototype.html",
							async: false,
							dataType: "html"
						}).success( function (data, textStatus, jqXHR ) {
							source = $( "<div></div>" ).html(data).jqmData( "tizen.widgetex.ajax.fail", false );
						} );

						// Assign the HTML proto to the widget prototype
						source  = $( "<div></div>" )
							.text( "Failed to load proto for widget " + namespace + "." + widgetName + "!" )
							.css( {background: "red", color: "blue", border: "1px solid black"} )
							.jqmData( "tizen.widgetex.ajax.fail", true );

					} else {
						// inline definition (string)
						source = $( source ).jqmData( "tizen.widgetex.ajax.fail", false );
					}

				} else {
					// inline definition (object)
					// AJAX loading has trivially succeeded, since there was no AJAX loading at all
					source.jqmData( "tizen.widgetex.ajax.fail", false );
				}
				htmlProto = source;
				$[namespace][widgetName].prototype._htmlProto.source = source;

				// If there's a "ui" portion in the HTML proto, copy it over to this instance, and
				// replace the selectors with the selected elements from a copy of the HTML prototype
				if ( $[namespace][widgetName].prototype._htmlProto.ui !== undefined ) {
					// Assign the relevant parts of the proto
					$.extend( this, {
						_ui: $.tizen.widgetex.assignElements( htmlProto.clone(), $[namespace][widgetName].prototype._htmlProto.ui )
					});
				}
			}
		}
	};

}( jQuery ) );



/*
 * jQuery UI Progressbar @VERSION
 *
 * Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
 * Licensed under the MIT license.
 * http://jquery.org/license
 *
 * http://docs.jquery.com/UI/Progressbar
 *
 * Depends:
 *   jquery.ui.core.js
 *   jquery.ui.widget.js
 * Original file:
 *   jquery.ui.progressbar.js
 */
/* This is from jquery ui plugin - progressbar 11/16/2011 */


/**
	@class ProgressBar
	The progress bar widget shows a control that indicates the progress percentage of an on-going operation. This widget can be scaled to fit inside a parent container.

	To add a progress bar widget to the application, use the following code:

		<div id="foo" data-role="progressbar"</div>
*/
/**
	@event change
	The progress bar can define a callback for the change event, which is fired when the progress value is changed:
		<div id="foo" data-role="progressbar"></div>
		$("#foo").bind("change", function (ev, val) {
			Console.log("Value is changed to " + val);
		});
*/
/**
	@method value
	You can use the value method with the pickers to set or get the current default progress bar value:

		<div id="foo" data-role="progressbar"></div>
		var oldVal = $("#foo").progressbar("value");
		$("#foo").progressbar("value", 50);
*/

(function ( $, window, undefined ) {

	$.widget( "tizen.progressbar", $.mobile.widget, {
		options: {
			value: 0,
			max: 100
		},

		min: 0,

		_create: function () {
			this.element
				.addClass( "ui-progressbar" )
				.attr( {
					role: "progressbar",
					"aria-valuemin": this.min,
					"aria-valuemax": this.options.max,
					"aria-valuenow": this._value()
				} );

			this.valueDiv = $( "<div class='ui-progressbar-value'></div>" )
				.appendTo( this.element );

			this.valueDiv.wrap("<div class='ui-progressbar-bg'></div>");

			this.oldValue = this._value();
			this._refreshValue();
		},

		_destroy: function () {
			this.element
				.removeClass( "ui-progressbar" )
				.removeAttr( "role" )
				.removeAttr( "aria-valuemin" )
				.removeAttr( "aria-valuemax" )
				.removeAttr( "aria-valuenow" );

			this.valueDiv.remove();
		},

		value: function ( newValue ) {
			if ( newValue === undefined ) {
				return this._value();
			}

			this._setOption( "value", newValue );
			return this;
		},

		_setOption: function ( key, value ) {
			if ( key === "value" ) {
				this.options.value = value;
				this._refreshValue();
				if ( this._value() === this.options.max ) {
					this.element.trigger( "complete" );
				}
			}
			// jquery.ui.widget.js MUST be updated to new version!
			//this._super( "_setOption", key, value );
		},

		_value: function () {
			var val = this.options.value;
			// normalize invalid value
			if ( typeof val !== "number" ) {
				val = 0;
			}
			return Math.min( this.options.max, Math.max( this.min, val ) );
		},

		_percentage: function () {
			return 100 * this._value() / this.options.max;
		},

		_refreshValue: function () {
			var value = this.value(),
				percentage = this._percentage();

			if ( this.oldValue !== value ) {
				this.oldValue = value;
				this.element.trigger( "change" );
			}

			this.valueDiv
				.toggle( value > this.min )
				.width( percentage.toFixed(0) + "%" );
			this.element.attr( "aria-valuenow", value );
		}
	} );

	// auto self-init widgets
	$( document ).bind( "pagecreate", function ( e ) {
		$( e.target ).find( ":jqmData(role='progressbar')" ).progressbar();
	} );

}( jQuery, this ) );



/*
 * jQuery Mobile Widget @VERSION
 *
 * This software is licensed under the MIT licence (as defined by the OSI at
 * http://www.opensource.org/licenses/mit-license.php)
 *
 * ***************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 * Copyright (c) 2011 by Intel Corporation Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 *
 * Authors: Kalyan Kondapally <kalyan.kondapally@intel.com>,
 *          Elliot Smith <elliot.smith@intel.com>
 *          Hyunjung Kim <hjnim.kim@samsung.com>
 */

// Widget which turns a html element into a "swipe":
// i.e. each list item has a sliding "cover" which can be swiped
// to the right (to reveal buttons underneath) or left (to
// cover the buttons again). Clicking on a button under a swipe
// also moves the cover back to the left.
//
// In this case, the cover is over a grid of buttons;
// but it is should also be possible to use other types of markup under the
// list items.
//
// WARNING: This doesn't work well inside a scrollview widget, as
// the touch events currently interfere with each other badly (e.g.
// a swipe will work but cause a scroll as well).
//
// Theme: default is to use the theme on the target element,
// theme passed in options, parent theme, or 'c' if none of the above.
// If list items are themed individually, the cover will pick up the
// theme of the list item which is its parent.
//

/**
	@class Swipe
	The swipe widget shows a view on the screen where the items can be swiped vertically to show a menu.
	To add a swipe widget to the application, use the following code:

		<ul data-role="listview">
			<li data-role="swipe">
				<div data-role="swipe-cover">
					<div data-role="button" data-inline="true">OK</div>
					<div data-role="button" data-inline="true">Cancel</div>
				</div>
				<div data-role="swipe-item-cover">
					<p>This is a swipe item cover.<br>
						This will be swiped out when swipe event comes.</p>
				</div>
			</li>
		</ul>

	You can use methods with the swipe as described in the jQueryMobile documentation for view methods.
*/
/**
	@property {String} data-role
	Creates a swipe using the HTML unordered view (&gt;ul&lt;) element.
	The default value is swipe.

	Creates a swipe item cover using an HTML $gt;div$lt; element. This cover can be swiped to show the content beneath it.
	The default value is swipe-item-cover.
*/
/**
	@method open
	uncover swipe item
*/
/**
	@method close
	cover swipe item
*/
/**
	@method opened
	return coveritem status( coverd or uncovred )
*/
/**
	@event animationstart
	The swipe can define a callback for the animationstart event, which is fired after a item is swipe and the swipe animation is start:
*/
/**
	@event animationend
	The swipe can define a callback for the animationend event, which is fired after a item is swiped and the swipe animation is complete:

		<ul data-role="listview">
		<li data-role="swipe">
				<div data-role="swipe-cover">
					<div data-role="button" data-inline="true">OK</div>
					<div data-role="button" data-inline="true">Cancel</div>
				</div>
				<div data-role="swipe-item-cover" id="foo">
				<p>This is a swipe item cover.<br>
						This will be swiped out when swipe event comes.</p>
				</div>
			</li>
		</ul>
		$("#foo").bind("animationend", function (ev)
		{
			Console.log("Swipe cover's animation is complete.");
		});
*/
(function ($) {

	$.widget("tizen.swipe", $.mobile.widget, {
		options: {
			theme: null
		},

		_create: function () {
			// use the theme set on the element, set in options,
			// the parent theme, or 'c' (in that order of preference)
			var theme = this.element.jqmData('theme') ||
				this.options.theme ||
				this.element.parent().jqmData('theme') ||
				's';

			this.options.theme = theme;
			this._isopen = false;
			this.refresh();
		},

		refresh: function () {
			this._cleanupDom();

			var self = this,
				defaultCoverTheme,
				covers,
				coverTheme,
				item,
				itemHasThemeClass;

			defaultCoverTheme = 'ui-body-' + this.options.theme;

			if ( !this.element.parent().hasClass('ui-listview') ) {
				this.element.parent().listview();
			}
			this.element.addClass('ui-swipe');

			// get the item covers
			covers = this.element.find(':jqmData(role="swipe-item-cover")');
			item = this.element.find(':jqmData(role="swipe-item")');

			this._covers = covers;
			this._item = item;
			item.addClass('ui-swipe-item');
			coverTheme = defaultCoverTheme;
			itemHasThemeClass = item.parent().attr('class')
					.match(/ui\-body\-[a-z]|ui\-bar\-[a-z]/);

			covers.each( function () {
				var cover = $( this );

				if ( itemHasThemeClass ) {
					coverTheme = itemHasThemeClass[0];
				}

				cover.addClass('ui-swipe-item-cover');
				cover.addClass( coverTheme );

				if ( cover.has('.ui-swipe-item-cover-inner').length === 0 ) {
					cover.wrapInner( $('<span/>').addClass('ui-swipe-item-cover-inner') );
				}

				if ( !( cover.data('animateRight') && cover.data('animateLeft') ) ) {
					cover.data('animateRight', function () {
						self._animateCover( cover, 110, item );
					});

					cover.data('animateLeft', function () {
						self._animateCover( cover, 0, item );
					});
				}

				// bind to synthetic events
				item.bind( 'swipeleft', cover.data('animateLeft') );
				cover.bind( 'swiperight', cover.data('animateRight') );
				item.find( '.ui-btn' ).bind( 'vclick', cover.data('animateLeft') );
			} );

		},

		_cleanupDom: function () {
			var self = this,
				defaultCoverTheme,
				cover,
				coverTheme = defaultCoverTheme,
				item,
				itemClass,
				itemHasThemeClass,
				text,
				wrapper;

			defaultCoverTheme = 'ui-body-' + this.options.theme;

			this.element.removeClass('ui-swipe');

			// get the item covers
			cover = this.element.find(':jqmData(role="swipe-item-cover")');
			item = this.element.find(':jqmData(role="swipe-item")');

			item.removeClass('ui-swipe-item');
			cover.removeClass('ui-swipe-item-cover');

			itemClass = item.attr('class');
			itemHasThemeClass = itemClass &&
				itemClass.match(/ui\-body\-[a-z]|ui\-bar\-[a-z]/);

			if ( itemHasThemeClass ) {
				coverTheme = itemHasThemeClass[0];
			}

			cover.removeClass(coverTheme);

			// remove wrapper HTML
			wrapper = cover.find('.ui-swipe-item-cover-inner');
			wrapper.children().unwrap();
			text = wrapper.text();

			if ( text ) {
				cover.append( text );
				wrapper.remove();
			}

			// unbind swipe events
			if ( cover.data('animateRight') && cover.data('animateLeft') ) {
				cover.unbind( 'swiperight', cover.data('animateRight') );
				item.unbind( 'swipeleft', cover.data('animateLeft') );

				// unbind clicks on buttons inside the item
				item.find('.ui-btn').unbind( 'vclick', cover.data('animateLeft') );

				cover.data( 'animateRight', null );
				cover.data( 'animateLeft', null );
			}
		},

		// NB I tried to use CSS animations for this, but the performance
		// and appearance was terrible on Android 2.2 browser;
		// so I reverted to jQuery animations
		//
		// once the cover animation is done, the cover emits an
		// animationComplete event
		_animateCover: function ( cover, leftPercentage, item ) {
			var self = this,
				animationOptions = {
					easing: 'linear',
					duration: 'normal',
					queue: true,
					complete: function () {
						cover.trigger('animationend');
					}
				};

			$( this.element.parent() )
				.find(":jqmData(role='swipe')")
				.each(
					function () {
						if ( this !== self.element.get(0) &&
								$( this ).swipe("opened") ) {
							$( this ).swipe("close");
						}
					}
				);

			if ( leftPercentage == 110 ) {
				this._isopen = true;
			} else {
				this._isopen = false;
			}

			cover.stop();
			cover.clearQueue();
			cover.trigger('animationstart');
			cover.clearQueue().animate( { left: leftPercentage + '%' }, animationOptions );
			if ( leftPercentage == 0 ) {
				item.clearQueue().animate({ opacity: 0 }, "slow");
			} else {
				item.clearQueue().animate({ opacity: 1 }, "slow");
			}

		},

		destroy: function () {
			this._cleanupDom();
		},

		open: function () {
			var self = this;

			$( self._covers ).each( function () {
				var cover = $( this );
				self._animateCover( cover, 110, self._item);
			} );
		},

		opened: function () {
			return this._isopen;
		},

		close: function () {
			var self = this;

			$( self._covers ).each( function () {
				var cover = $( this );
				self._animateCover( cover, 0, self._item);
			} );
		}

	});

	$( document ).bind("pagecreate", function ( e ) {
		$( e.target ).find(":jqmData(role='swipe')").swipe();
	});

}( jQuery ));



/* ***************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 *
 * jQuery Mobile Framework : "tabbar" plugin
 * Copyright (c) jQuery Project
 * Licensed under the MIT license.
 * http://jquery.org/license
 * Authors: Jinhyuk Jun <jinhyuk.jun@samsung.com>
*/

/**
 *  Tabbar can be created using data-role = "tabbar" inside footer 
 *  Framework determine which tabbar will display with tabbar attribute
 *
 * Examples:
 *         
 *     HTML markup for creating tabbar: ( 2 ~ 5 li item available )
 *     icon can be changed data-icon attribute (customized icon need)
 *         <div data-role="footer" data-position ="fixed">
 *              <div data-role="tabbar">
 *                     <ul>
 *                            <li><a href="#" class="ui-btn-active">Menu</a></li>
 *                            <li><a href="#">Save</a></li>
 *                            <li><a href="#">Share</a></li>
 *                     </ul>
 *             </div>
 *      </div>
*/

(function ( $, undefined ) {

	$.widget( "tizen.tabbar", $.mobile.widget, {
		options: {
			iconpos: "top",
			grid: null,
			defaultList : 4,
			initSelector: ":jqmData(role='tabbar')"
		},

		_create: function () {

			var $tabbar = this.element,
				$tabbtns,
				textpos,
				iconpos,
				theme = $.mobile.listview.prototype.options.theme,	/* Get current theme */
				ww = window.innerWidth || $( window ).width(),
				wh = window.innerHeight || $( window ).height(),
				tabbarDividerLeft = "<div class='ui-tabbar-divider ui-tabbar-divider-left'></div>",
				tabbarDividerRight = "<div class='ui-tabbar-divider ui-tabbar-divider-right'></div>",
				isLandscape;

			isLandscape = ww > wh && ( ww - wh );

			if ( isLandscape ) {
				$tabbar.removeClass( "ui-portrait-tabbar" ).addClass( "ui-landscape-tabbar" );
			} else {
				$tabbar.removeClass( "ui-landscape-tabbar" ).addClass( "ui-portrait-tabbar" );
			}

			if ( $tabbar.find( "a" ).length ) {
				$tabbtns = $tabbar.find( "a" );
				iconpos = $tabbtns.filter( ":jqmData(icon)" ).length ? this.options.iconpos : undefined;
				textpos = $tabbtns.html().length ? true : false;
			}

			if ( $tabbar.parents( ".ui-header" ).length && $tabbar.parents( ".ui-scrollview-view" ).length ) {
				$tabbar.find( "li" ).addClass( "tabbar-scroll-li" );
				$tabbar.find( "ul" ).addClass( "tabbar-scroll-ul" );

				/* add shadow divider */
				$( tabbarDividerLeft ).appendTo( $tabbar.parents( ".ui-scrollview-clip" ) );
				$( tabbarDividerRight ).appendTo( $tabbar.parents( ".ui-scrollview-clip" ) );

				$( ".ui-tabbar-divider-left" ).hide();
				$( ".ui-tabbar-divider-right" ).hide();

				/* add width calculation*/
				if ( $tabbar.parents( ".ui-scrollview-view" ).data("default-list") ) {
					this.options.defaultList = $tabbar.parents( ".ui-scrollview-view" ).data( "default-list" );
				}
				$tabbar.find( "li" ).css( "width", window.innerWidth / this.options.defaultList + "px" );
			} else {
				if ( $tabbar.find( "ul" ).children().length ) {
					$tabbar.addClass( "ui-navbar" )
						.find( "ul" )
						.grid( { grid: this.options.grid } );
				}
			}

			if ( $tabbar.parents( ".ui-footer" ).length  ) {
				$tabbar.find( "li" ).addClass( "ui-tab-btn-style" );
			}

			/* title tabbar */
			if ( $tabbar.siblings( ".ui-title" ).length ) {
				$tabbar.parents( ".ui-header" ).addClass( "ui-title-tabbar" );
			}

			if ( !iconpos ) {
				$tabbar.addClass( "ui-tabbar-noicons" );
			}
			if ( !textpos ) {
				$tabbar.addClass( "ui-tabbar-notext" );
			}
			if ( textpos && iconpos ) {
				$tabbar.parents( ".ui-header" ).addClass( "ui-title-tabbar-multiline" );
			}

			if ( $tabbar.find( "a" ).length ) {
				$tabbtns.buttonMarkup({
					corners:	false,
					shadow:		false,
					iconpos:	iconpos
				});
			}

			if ( $tabbar.find( ".ui-state-persist" ).length ) {
				$tabbar.addClass( "ui-tabbar-persist" );
			}

			$tabbar.delegate( "a", "vclick", function ( event ) {
                                if ( $tabbtns.parents( "ul" ).is( ".tabbar-scroll-ul" ) ) {
                                        $tabbtns.removeClass( "ui-tabbar-active" );
                                        $( event.target ).parents( "a" ).addClass( "ui-tabbar-active" );

                                } else {
					$tabbtns.not( ".ui-state-persist" ).removeClass( $.mobile.activeBtnClass );
					$( this ).addClass( $.mobile.activeBtnClass );
				}
			});

			$tabbar.addClass( "ui-tabbar");

			$( document ).bind( "pagebeforeshow", function ( event, ui ) {
				var footer_filter = $( event.target ).find( ":jqmData(role='footer')" ),
					tabbar_filter = footer_filter.find( ":jqmData(role='tabbar')" ),
					$elFooterMore = tabbar_filter.siblings( ":jqmData(icon='naviframe-more')" ),
					$elFooterBack = tabbar_filter.siblings( ".ui-btn-back" );

				footer_filter
					.css( "position", "fixed" )
					.css( "bottom", 0 )
					.css( "height", tabbar_filter.height() );
				if ( $elFooterMore.length ) {
					tabbar_filter.addClass( "ui-tabbar-margin-more" );
				}
				if ( $elFooterBack.length ) {
					tabbar_filter.addClass( "ui-tabbar-margin-back" );
				}
			});

			$tabbar.bind( "touchstart vmousedown", function ( e ) {
				var $tabbarScroll = $( e.target ).parents( ".ui-scrollview-view" );
				if ( $tabbarScroll.offset() ) {
					if ( $tabbarScroll.offset().left < 0 ) {
						$( ".ui-tabbar-divider-left" ).show();
					} else {
						$( ".ui-tabbar-divider-left" ).hide();
					}
					if ( ( $tabbarScroll.width() - $tabbarScroll.parents( ".ui-scrollview-clip" ).width() ) ==  Math.abs( $tabbarScroll.offset().left ) ) {
						$( ".ui-tabbar-divider-right" ).hide();
					} else {
						$( ".ui-tabbar-divider-right" ).show();
					}
				}
			});

			this._bindTabbarEvents();
			this._initTabbarAnimation();
		},

		_initTabbarAnimation: function () {
			var isScrollingStart = false,
				isScrollingEnd = false;
			$( document ).bind( "scrollstart.tabbar", function ( e ) {
				if ( $( e.target ).find( ".ui-tabbar" ).length ) {
					isScrollingStart = true;
					isScrollingEnd = false;
				}
			});

			$( document ).bind( "scrollstop.tabbar", function ( e ) {
				var $tabbarScrollview = $( e.target ),
					$elTabbar = $( e.target ).find( ".ui-tabbar" ),
					$elTabbarLI = $( e.target ).find( ".ui-tabbar li" ),
					$minElement = $elTabbarLI.eq( 0 ),
					minElementIndexVal,
					minElementIndex = -1;

				isScrollingEnd = true;
				if ( $elTabbar.length && isScrollingStart == true ) {
					minElementIndexVal = Math.abs( $elTabbarLI.eq( 0 ).offset().left );
					$elTabbarLI.each( function ( i ) {
						var offset	= $elTabbarLI.eq( i ).offset();

						if ( Math.abs( offset.left ) < minElementIndexVal ) {
							minElementIndexVal = Math.abs( offset.left );
							minElementIndex = i;
							$minElement = $elTabbarLI.eq( i );
						}
					});

					if ( $tabbarScrollview.length && isScrollingStart == isScrollingEnd && minElementIndex != -1) {
						isScrollingStart = false;
						$tabbarScrollview.scrollview( "scrollTo", -( window.innerWidth / $elTabbar.data( "defaultList" ) * minElementIndex ) , 0, 357);
					}
				}

				$( ".ui-tabbar-divider-left" ).hide();
				$( ".ui-tabbar-divider-right" ).hide();
			});
		},

		_bindTabbarEvents: function () {
			var $tabbar = this.element;

			$( window ).bind( "orientationchange", function ( e, ui ) {
				var ww = window.innerWidth || $( window ).width(),
					wh = window.innerHeight || $( window ).height(),
					isLandscape = ww > wh && ( ww - wh );

				if ( isLandscape ) {
					$tabbar.removeClass( "ui-portrait-tabbar" ).addClass( "ui-landscape-tabbar" );
				} else {
					$tabbar.removeClass( "ui-landscape-tabbar" ).addClass( "ui-portrait-tabbar" );
				}
			});
		},

		_setDisabled: function ( value, cnt ) {
			this.element.find( "li" ).eq( cnt ).attr( "disabled", value );
			this.element.find( "li" ).eq( cnt ).attr( "aria-disabled", value );
		},

		disable: function ( cnt ) {
			this._setDisabled( true, cnt );
			this.element.find( "li" ).eq( cnt ).addClass( "ui-disabled" );
		},

		enable: function ( cnt ) {
			this._setDisabled( false, cnt );
			this.element.find( "li" ).eq( cnt ).removeClass( "ui-disabled" );
		}
	});

	//auto self-init widgets
	$( document ).bind( "pagecreate create", function ( e ) {
		$( $.tizen.tabbar.prototype.options.initSelector, e.target ).tabbar();
	});
}( jQuery ) );



/*
 * This software is licensed under the MIT licence (as defined by the OSI at
 * http://www.opensource.org/licenses/mit-license.php)
 *
 * ***************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 * Copyright (c) 2011 by Intel Corporation Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 */

( function ($, undefined) {

	$.widget( "tizen.triangle", $.tizen.widgetex, {
		options: {
			extraClass: "",
			offset: null,
			color: null,
			location: "top",
			initSelector: ":jqmData(role='triangle')"
		},

		_create: function () {
			var triangle = $( "<div></div>", {"class" : "ui-triangle"} );

			$.extend(this, {
				_triangle: triangle
			});

			this.element.addClass( "ui-triangle-container" ).append( triangle );
		},

		_doCSS: function () {
			var location = ( this.options.location || "top" ),
				offsetCoord = ( ($.inArray(location, ["top", "bottom"]) === -1) ? "top" : "left"),
				cssArg = {
					"border-bottom-color" : "top"    === location ? this.options.color : "transparent",
					"border-top-color"    : "bottom" === location ? this.options.color : "transparent",
					"border-left-color"   : "right"  === location ? this.options.color : "transparent",
					"border-right-color"  : "left"   === location ? this.options.color : "transparent"
				};

			cssArg[offsetCoord] = this.options.offset;

			this._triangle.removeAttr( "style" ).css( cssArg );
		},

		_setOffset: function ( value ) {
			this.options.offset = value;
			this.element.attr( "data-" + ($.mobile.ns || "") + "offset", value );
			this._doCSS();
		},

		_setExtraClass: function ( value ) {
			this._triangle.addClass( value );
			this.options.extraClass = value;
			this.element.attr( "data-" + ($.mobile.ns || "") + "extra-class", value );
		},

		_setColor: function ( value ) {
			this.options.color = value;
			this.element.attr( "data-" + ($.mobile.ns || "") + "color", value );
			this._doCSS();
		},

		_setLocation: function ( value ) {
			this.element
				.removeClass( "ui-triangle-container-" + this.options.location )
				.addClass( "ui-triangle-container-" + value );
			this._triangle
				.removeClass( "ui-triangle-" + this.options.location )
				.addClass( "ui-triangle-" + value );

			this.options.location = value;
			this.element.attr( "data-" + ($.mobile.ns || "") + "location", value );

			this._doCSS();
		}
	});

	$( document ).bind( "pagecreate create", function ( e ) {
	    $($.tizen.triangle.prototype.options.initSelector, e.target)
	        .not(":jqmData(role='none'), :jqmData(role='nojs')")
	        .triangle();
	});

}(jQuery) );



/*
 * jQuery Mobile Widget @VERSION
 *
 * This software is licensed under the MIT licence (as defined by the OSI at
 * http://www.opensource.org/licenses/mit-license.php)
 *
 * ***************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 * Copyright (c) 2011 by Intel Corporation Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 *
 * Authors: Gabriel Schulhof <gabriel.schulhof@intel.com>,
 *          Elliot Smith <elliot.smith@intel.com>
 *			Hyunjung Kim <hjnim.kim@samsung.com>
 */

/*
 * % Popupwindow widget do not use anymore(will be deprecated, internal use only)
 *
 *
 * Shows other elements inside a popup window.
 *
 * To apply, add the attribute data-role="popupwindow" to a <div> element inside
 * a page. Alternatively, call popupwindow()
 * on an element, eg :
 *
 *     $("#mypopupwindowContent").popupwindow();
 * where the html might be :
 *     <div id="mypopupwindowContent"></div>
 *
 * To trigger the popupwindow to appear, it is necessary to make a call to its
 * 'open()' method. This is typically done by binding a function to an event
 * emitted by an input element, such as a the clicked event emitted by a button
 * element. The open() method takes two arguments, specifying the x and y
 * screen coordinates of the center of the popup window.

 * You can associate a button with a popup window like this:
 *      <div id="mypopupContent" style="display: table;" data-role="popupwindow">
 *          <table>
 *              <tr> <td>Eenie</td>   <td>Meenie</td>  <td>Mynie</td>   <td>Mo</td>  </tr>
 *              <tr> <td>Catch-a</td> <td>Tiger</td>   <td>By-the</td>  <td>Toe</td> </tr>
 *              <tr> <td>If-he</td>   <td>Hollers</td> <td>Let-him</td> <td>Go</td>  </tr>
 *              <tr> <td>Eenie</td>   <td>Meenie</td>  <td>Mynie</td>   <td>Mo</td>  </tr>
 *          </table>
 *      </div>
 * <a href="#myPopupContent" data-rel="popupwindow" data-role="button">Show popup</a>
 *
 * Options:
 *
 *     theme: String; the theme for the popupwindow contents
 *                   Default: null
 *
 *     overlayTheme: String; the theme for the popupwindow
 *                   Default: null
 *
 *     shadow: Boolean; display a shadow around the popupwindow
 *             Default: true
 *
 *     corners: Boolean; display a shadow around the popupwindow
 *             Default: true
 *
 *     fade: Boolean; fades the opening and closing of the popupwindow
 *
 *     transition: String; the transition to use when opening or closing
 *                 a popupwindow
 *                 Default: $.mobile.defaultDialogTransition
 *
 * Events:
 *	popupbeforeposition: triggered after a popup has completed preparations for opening, but has not yet opened
 *	popupafteropen: triggered after a popup has completely opened
 *	popupafterclose triggered when a popup has completely closed
*/

/**
	class Popupwindow
	The pop-up widget shows a list of items in a pop-up window in the middle of the screen. It automatically optimizes the pop-up window size within the screen.
	To add a pop-up widget to the application, use the following code:

		// Basic pop-up
		<div id="center_info" data-role="popup" data-style="center_info">
			<div data-role="text">
				<p>
				Pop-up dialog box, a child window that blocks user interaction in the parent window
				</p>
			</div>
		</div>
		// Pop-up with a title and button
		<div id="center_title_1btn" data-role="popup" data-style="center_title_1btn">
			<p data-role="title">
				Pop-up title
			</p>
			<p data-role="text">
				Pop-up dialog box
			</p>
		<div data-role="button-bg">
			<input type="button" value="Text Button" />
		</div>
		</div>

	The pop-up can define callbacks for events as described in the jQueryMobile documentation for pop-up events. <br/>You can use methods with the pop-up as described in the jQueryMobile documentation for pop-up methods.

	@deprecated 2.0 verisons
*/

/**
	@property {String} data-style
	Defines the pop-up window style.
	The following styles are available:

	center_info: basic pop-up message
	center_title: pop-up message with a title
	center_basic_1btn: pop-up message with 1 button
	center_basic_2btn: pop-up message with 2 horizontal buttons
	center_title_1btn: pop-up message with a title and 1 button
	center_title_2btn: pop-up message with a title and 2 horizontal buttons
	center_title_3btn: pop-up message with a title and 3 horizontal buttons
	center_button_vertical: pop-up message with vertical buttons
	center_checkbox: pop-up message with a check box
	center_liststyle_1btn>: pop-up message with a list and 1 button
	center_liststyle_2btn: pop-up message with a list and 2 horizontal buttons
	center_liststyle_3btn: pop-up message with a list and 3 horizontal buttons
*/

(function ( $, undefined ) {
	$.widget( "tizen.popupwindow", $.tizen.widgetex, {
		options: {
			theme: null,
			overlayTheme: "s",
			style: "custom",
			disabled: false,
			shadow: true,
			corners: true,
			fade: false,
			opacity: 0.7,
			widthRatio: 0.8612,
			transition: $.mobile.defaultDialogTransition,
			initSelector: ":jqmData(role='popupwindow')"
		},

		_htmlProto: {
source:

 [ "<div><div>" ,
  "    <div id='popupwindow-screen' class='ui-selectmenu-screen ui-screen-hidden ui-popupwindow-screen'></div>" ,
  "    <div id='popupwindow-container' class='ui-popupwindow ui-popupwindow-padding ui-selectmenu-hidden ui-overlay-shadow ui-corner-all'></div>" ,
  "</div>" ,
  "</div>" ].join("")
,			ui: {
				screen: "#popupwindow-screen",
				container: "#popupwindow-container"
			}
		},

		_setStyle: function () {
			var popup = this.element,
				style = popup.attr( 'data-style' );

			if ( style ) {
				this.options.style = style;
			}

			popup.addClass( this.options.style );
			popup.find( ":jqmData(role='title')" )
					.wrapAll( "<div class='popup-title'></div>" );
			popup.find( ":jqmData(role='text')" )
					.wrapAll( "<div class='popup-text'></div>" );
			popup.find( ":jqmData(role='button-bg')" )
					.wrapAll( "<div class='popup-button-bg'></div>" );
			popup.find( ":jqmData(role='check-bg')" )
					.wrapAll( "<div class='popup-check-bg'></div>" );
			popup.find( ":jqmData(role='scroller-bg')" )
					.addClass( "popup-scroller-bg" );
			popup.find( ":jqmData(role='text-bottom-bg')" )
					.wrapAll( "<div class='popup-text-bottom-bg'></div>" );
			popup.find( ":jqmData(role='text-left')" )
					.wrapAll( "<div class='popup-text-left'></div>" );
			popup.find( ":jqmData(role='text-right')" )
					.wrapAll( "<div class='popup-text-right'></div>" );
			popup.find( ":jqmData(role='progress-bg')" )
					.wrapAll( "<div class='popup-progress-bg'></div>" );
		},

		_create: function () {
			console.warn("popupwindow() was deprecated. use popup() instead.");
			var thisPage = this.element.closest(":jqmData(role='page')"),
				self = this;

			if ( thisPage.length === 0 ) {
				thisPage = $("body");
			}

			this._ui.placeholder =
					$( "<div><!-- placeholder for " + this.element.attr("id") + " --></div>" )
					.css("display", "none")
					.insertBefore( this.element );

			thisPage.append( this._ui.screen );
			this._ui.container.insertAfter( this._ui.screen );
			this._ui.container.append( this.element );

			this._setStyle();

			this._isOpen = false;

			this._ui.screen.bind( "vclick", function ( e ) {
				self.close();
				return false;
			} );

			this.element.bind( "vclick", function ( e ) {
				if ( $( e.target ).is("ui-btn-ctxpopup-close") ) {
					self.close();
				}
			} );
		},

		destroy: function () {
			this.element.insertBefore( this._ui.placeholder );

			this._ui.placeholder.remove();
			this._ui.container.remove();
			this._ui.screen.remove();
			this.element.triggerHandler("destroyed");
			$.Widget.prototype.destroy.call( this );
		},

		_placementCoords: function ( x, y, cw, ch ) {
			var screenHeight = $( window ).height(),
				screenWidth = $( window ).width(),
				halfheight = ch / 2,
				maxwidth = parseFloat( this._ui.container.css( "max-width" ) ),
				roomtop = y,
				roombot = screenHeight - y,
				newtop,
				newleft;

			if ( roomtop > ch / 2 && roombot > ch / 2 ) {
				newtop = y - halfheight;
			} else {
				newtop = roomtop > roombot ? screenHeight - ch - 30 : 30;
			}

			if ( cw < maxwidth ) {
				newleft = ( screenWidth - cw ) / 2;
			} else {
				newleft = x - cw / 2;

				if ( newleft < 10 ) {
					newleft = 10;
				} else if ( ( newleft + cw ) > screenWidth ) {
					newleft = screenWidth - cw - 10;
				}
			}

			return { x : newleft, y : newtop };
		},

		_setPosition: function ( x_where, y_where ) {
			var x = ( undefined === x_where ? $( window ).width()  / 2 : x_where ),
				y = ( undefined === y_where ? $( window ).height() / 2 : y_where ),
				coords,
				ctxpopup = this.element.data("ctxpopup"),
				popupWidth,
				menuHeight,
				menuWidth,
				screenHeight,
				screenWidth,
				roomtop,
				roombot,
				halfheight,
				maxwidth,
				newtop,
				newleft;

			if ( !ctxpopup ) {
				popupWidth = $( window ).width() * this.options.widthRatio;
				this._ui.container.css( "width", popupWidth );

				if ( this._ui.container.outerWidth() > $( window ).width() ) {
					this._ui.container.css( {"max-width" : $( window ).width() - 30} );
				}
			}

			coords = this._placementCoords( x, y,
					this._ui.container.outerWidth(),
					this._ui.container.outerHeight() );

			menuHeight = this._ui.container.innerHeight();
			menuWidth = this._ui.container.innerWidth();
			screenHeight = $( window ).height();
			screenWidth = $( window ).width();
			roomtop = y;
			roombot = screenHeight - y;
			halfheight = menuHeight / 2;
			maxwidth = parseFloat( this._ui.container.css( "max-width" ) );
			newtop = ( screenHeight - menuHeight ) / 2;

			if ( !maxwidth || menuWidth < maxwidth ) {
				newleft = ( screenWidth - menuWidth ) / 2;
			} else {
				newleft = x - menuWidth / 2;

				if ( newleft < 30 ) {
					newleft = 30;
				} else if ( ( newleft + menuWidth ) > screenWidth ) {
					newleft = screenWidth - menuWidth - 30;
				}
			}

			if ( ctxpopup ) {
				newtop = coords.y;
				newleft = coords.x;
			}

			this._ui.container.css({
				top: newtop,
				left: newleft
			});

			this._ui.screen.css( "height", screenHeight );
		},
		open: function ( x_where, y_where, backgroundclose ) {
			var self = this,
				zIndexMax = 0;

			if ( this._isOpen || this.options.disabled ) {
				return;
			}

			$( document ).find("*").each( function () {
				var el = $( this ),
					zIndex = parseInt( el.css("z-index"), 10 );

				if ( !( el.is( self._ui.container ) ||
						el.is( self._ui.screen ) ||
						isNaN( zIndex ))) {
					zIndexMax = Math.max( zIndexMax, zIndex );
				}
			} );

			this._ui.screen.css( "height", $( window ).height() );

			if ( backgroundclose ) {
				this._ui.screen.css( "opacity", 0 )
						.removeClass("ui-screen-hidden");
			} else {
				this._ui.removeClass("ui-screen-hidden");

				if ( this.options.fade ) {
					this._ui.screen.animate( {opacity: this.options.opacity}, "fast" );
				} else {
					this._ui.screen.css( {opacity: this.options.opacity} );
				}
			}

			this._setPosition( x_where, y_where );

			this.element.trigger("popupbeforeposition");

			this._ui.container
				.removeClass("ui-selectmenu-hidden")
				.addClass("in")
				.animationComplete( function () {
					self.element.trigger("popupafteropen");
				} );

			this._isOpen = true;

			if ( !this._reflow ) {
				this._reflow = function () {
					if ( !self._isOpen ) {
						return;
					}

					self._setPosition( x_where, y_where );
				};

				$( window ).bind( "resize", this._reflow );
			}
		},

		close: function () {
			if ( !this._isOpen ) {
				return;
			}

			if ( this._reflow ) {
				$( window ).unbind( "resize", this._reflow );
				this._reflow = null;
			}

			var self = this,
				hideScreen = function () {
					self._ui.screen.addClass("ui-screen-hidden");
					self._isOpen = false;
				};

			this._ui.container.removeClass("in").addClass("reverse out");

			if ( this.options.transition === "none" ) {
				this._ui.container
					.addClass("ui-selectmenu-hidden")
					.removeAttr("style");
				this.element.trigger("popupafterclose");
			} else {
				this._ui.container.animationComplete( function () {
					self._ui.container
						.removeClass("reverse out")
						.addClass("ui-selectmenu-hidden")
						.removeAttr("style");
					self.element.trigger("popupafterclose");
				} );
			}

			if ( this.options.fade ) {
				this._ui.screen.animate( {opacity: 0}, "fast", hideScreen );
			} else {
				hideScreen();
			}
		},

		_realSetTheme: function ( dst, theme ) {
			var classes = ( dst.attr("class") || "" ).split(" "),
				alreadyAdded = true,
				currentTheme = null,
				matches;

			while ( classes.length > 0 ) {
				currentTheme = classes.pop();
				matches = currentTheme.match(/^ui-body-([a-z])$/);

				if ( matches && matches.length > 1 ) {
					currentTheme = matches[1];
					break;
				} else {
					currentTheme = null;
				}
			}

			dst.removeClass( "ui-body-" + currentTheme );
			if ( ( theme || "" ).match(/[a-z]/) ) {
				dst.addClass( "ui-body-" + theme );
			}
		},

		_setTheme: function ( value ) {
			this._realSetTheme( this.element, value );
			this.options.theme = value;
			this.element.attr( "data-" + ( $.mobile.ns || "" ) + "theme", value );
		},

		_setOverlayTheme: function ( value ) {
			this._realSetTheme( this._ui.container, value );
			this.options.overlayTheme = value;
			this.element.attr( "data-" + ( $.mobile.ns || "" ) + "overlay-theme", value );
		},

		_setShadow: function ( value ) {
			this.options.shadow = value;
			this.element.attr( "data-" + ( $.mobile.ns || "" ) + "shadow", value );
			this._ui.container[value ? "addClass" : "removeClass"]("ui-overlay-shadow");
		},

		_setCorners: function ( value ) {
			this.options.corners = value;
			this.element.attr( "data-" + ( $.mobile.ns || "" ) + "corners", value );
			this._ui.container[value ? "addClass" : "removeClass"]("ui-corner-all");
		},

		_setFade: function ( value ) {
			this.options.fade = value;
			this.element.attr( "data-" + ( $.mobile.ns || "" ) + "fade", value );
		},

		_setTransition: function ( value ) {
			this._ui.container
				.removeClass( this.options.transition || "" )
				.addClass( value );
			this.options.transition = value;
			this.element.attr( "data-" + ( $.mobile.ns || "" ) + "transition", value );
		},

		_setDisabled: function ( value ) {
			$.Widget.prototype._setOption.call( this, "disabled", value );
			if ( value ) {
				this.close();
			}
		}
	});

	$.tizen.popupwindow.bindPopupToButton = function ( btn, popup ) {
		if ( btn.length === 0 || popup.length === 0 ) {
			return;
		}

		var btnVClickHandler = function ( e ) {
			if ( !popup.jqmData("overlay-theme-set") ) {
				popup.popupwindow( "option", "overlayTheme", btn.jqmData("theme") );
			}

			popup.popupwindow( "open",
				btn.offset().left + btn.outerWidth()  / 2,
				btn.offset().top  + btn.outerHeight() / 2 );

			return false;
		};

		if ( ( popup.popupwindow("option", "overlayTheme") || "" ).match(/[a-z]/) ) {
			popup.jqmData( "overlay-theme-set", true );
		}

		btn
			.attr({
				"aria-haspopup": true,
				"aria-owns": btn.attr("href")
			})
			.removeAttr("href")
			.bind( "vclick", btnVClickHandler );

		popup.bind( "destroyed", function () {
			btn.unbind( "vclick", btnVClickHandler );
		} );
	};

	$( document ).bind( "pagecreate create", function ( e ) {
		$( $.tizen.popupwindow.prototype.options.initSelector, e.target )
			.not(":jqmData(role='none'), :jqmData(role='nojs')")
			.popupwindow();

		$( "a[href^='#']:jqmData(rel='popupwindow')", e.target ).each( function () {
			$.tizen.popupwindow.bindPopupToButton( $( this ), $( $( this ).attr("href") ) );
		});
	});
}( jQuery ));



/*
 * jQuery Mobile Widget @VERSION
 *
 * This software is licensed under the MIT licence (as defined by the OSI at
 * http://www.opensource.org/licenses/mit-license.php)
 *
 * ***************************************************************************
 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
 * Copyright (c) 2011 by Intel Corporation Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 *
 * Authors: Gabriel Schulhof <gabriel.schulhof@intel.com>
 *			Hyunjung Kim <hjnim.kim@samsung.com>
 */

/*
 * % ContextPopup widget do not use anymore(will be deprecated, internal use only)
 */
// This widget is implemented in an extremely ugly way. It should derive from $.tizen.popupwindow, but it doesn't
// because there's a bug in jquery.ui.widget.js which was fixed in jquery-ui commit
// b9153258b0f0edbff49496ed16d2aa93bec07d95. Once a version of jquery-ui containing that commit is released
// (probably >= 1.9m5), and jQuery Mobile picks up the widget from there, this widget needs to be rewritten properly.
// The problem is that, when a widget inherits from a superclass and declares an object in its prototype identical in key
// to one in the superclass, upon calling $.widget the object is overwritten in both the prototype of the superclass and
// the prototype of the subclass. The prototype of the superclass should remain unchanged.

/**
	class ContextPopup
		The context pop-up widget shows a list of options and automatically optimizes its size within the screen. This widget is intended for a small list of options for a larger list, use the List widget. <br/>The context pop-up widget requires a target button, which must be clicked to open the context pop-up. In the default application theme, an arrow pointer is displayed at the top-left corner of the context pop-up widget when it is opened.<br/><br/> To add a context pop-up widget to the application, use the following code:

			// Target button
			<a href="#pop_3_icons" id="btn_3_icons" data-role="button" data-inline="true" data-rel="popupwindow">3 Icons</a>
			// Context pop-up
				<div class="horizontal" id="pop_3_icons" data-role="popupwindow" data-show-arrow="true">
				<ul>
					<li class="icon">
						<a href="#" data-role="button" data-icon="call"></a>
					</li>
					<li class="icon">
						<a href="#" data-role="button" data-icon="favorite"></a>
					</li>
					<li class="text">
						<a href="#">Function</a>
					</li>
				</ul>
			</div>
	The context pop-up can define callbacks for events as described in the [jQueryMobile documentation for pop-up events.][1]
	You can use methods with the context pop-up as described in the [jQueryMobile documentation for pop-up methods.][2]
	[1]: http://jquerymobile.com/demos/1.2.0-alpha.1/docs/pages/popup/events.html
	[2]: http://jquerymobile.com/demos/1.2.0-alpha.1/docs/pages/popup/methods.html

	@deprecated 2.0 verisons
*/

(function ( $, undefined ) {
	$.widget( "tizen.ctxpopup", $.tizen.widgetex, {
		options: $.extend( {}, $.tizen.popupwindow.prototype.options, {
			initSelector: ":jqmData(show-arrow)"
		} ),

		_htmlProto: {
source:

 [ "<div><div id='outer' class='ui-ctxpopup'>" ,
  "    <div id='top' class='ui-ctxpopup-row' data-role='triangle' data-location='top'></div>" ,
  "    <div class='ui-ctxpopup-row'>" ,
  "        <div id='left' class='ui-ctxpopup-cell' data-role='triangle' data-location='left'></div>" ,
  "        <div id='container' class='ui-ctxpopup-cell'></div>" ,
  "        <div id='right' class='ui-ctxpopup-cell' data-role='triangle' data-location='right'></div>" ,
  "    </div>" ,
  "    <div id='bottom' class='ui-ctxpopup-row' data-role='triangle' data-location='bottom'></div>" ,
  "</div>" ,
  "</div>" ].join("")
,			ui: {
				outer		: "#outer",
				container	: "#container", // the key has to have the name "container"
				arrow		: {
					all		: ":jqmData(role='triangle')",
					l		: "#left",
					t		: "#top",
					r		: "#right",
					b		: "#bottom"
				}
			}
		},

		_create: function () {
			console.warn("ctxpopup() was deprecated. use popup() instead.");
			if ( !this.element.data( "popupwindow" ) ) {
				this.element.popupwindow();
			}

			this.element.data( "popupwindow" )
				._ui.container
				.removeClass( "ui-popupwindow-padding" )
				.append( this._ui.outer );
			this._ui.outer.trigger( "create" ); // Creates the triangle widgets
			this._ui.container
				.addClass( "ui-popupwindow-padding" )
				.append( this.element );
		},

		_setOption: function ( key, value ) {
			$.tizen.popupwindow.prototype._setOption.apply( this.element.data( "popupwindow" ), arguments );
			this.options[key] = value;
		}
	} );

	var origOpen = $.tizen.popupwindow.prototype.open,
		orig_setOption = $.tizen.popupwindow.prototype._setOption,
		orig_placementCoords = $.tizen.popupwindow.prototype._placementCoords;

	$.tizen.popupwindow.prototype._setOption = function ( key, value ) {
		var ctxpopup = this.element.data( "ctxpopup" ),
			needsApplying = true,
			origContainer;
		if ( ctxpopup ) {
			if ( "shadow" === key || "overlayTheme" === key || "corners" === key ) {
				origContainer = this._ui.container;

				this._ui.container = ctxpopup._ui.container;
				orig_setOption.apply( this, arguments );
				this._ui.container = origContainer;
				needsApplying = false;
			}
			ctxpopup.options[key] = value;
		}

		if ( needsApplying ) {
			orig_setOption.apply(this, arguments);
		}
	};

	$.tizen.popupwindow.prototype._placementCoords = function ( x, y, cx, cy ) {
		var ctxpopup = this.element.data( "ctxpopup" ),
			self = this,
			coords = {},
			minDiff,
			minDiffIdx;

		function getCoords( arrow, x_factor, y_factor ) {
			// Unhide the arrow we want to test to take it into account
			ctxpopup._ui.arrow.all.hide();
			ctxpopup._ui.arrow[arrow].show();

			var isHorizontal = ( "b" === arrow || "t" === arrow ),
			// Names of keys used in calculations depend on whether things are horizontal or not
				coord = ( isHorizontal
						? { point: "x", size: "cx", beg: "left", outerSize: "outerWidth",  niceSize: "width", triangleSize : "height" }
						: { point: "y", size: "cy", beg: "top",  outerSize: "outerHeight", niceSize: "height", triangleSize : "width" } ),
				size = {
					cx : self._ui.container.width(),
					cy : self._ui.container.height()
				},
				halfSize = {
					cx : size.cx / 2,
					cy : size.cy / 2
				},
				desired = {
					"x" : x + halfSize.cx * x_factor,
					"y" : y + halfSize.cy * y_factor
				},
				orig = orig_placementCoords.call( self, desired.x, desired.y, size.cx, size.cy ),

			// The triangleOffset must be clamped to the range described below:
			//
			//                          +-------...
			//                          |   /\
			//                          |  /  \
			//                   ----+--+-,-----...
			//lowerDiff       -->____|  |/ <-- possible rounded corner
			//triangle size   -->    | /|
			//                   ____|/ |
			//                    ^  |\ | <-- lowest possible offset for triangle
			// actual range of    |  | \| 
			// arrow offset       |  |  | 
			// values due to      |  .  . Payload table cell looks like
			// possible rounded   |  .  . a popup window, and it may have
			// corners and arrow  |  .  . arbitrary things like borders,
			// triangle size -    |  |  | shadows, and rounded corners.
			// our clamp range    |  | /|
			//                   _v__|/ |
			//triangle size   -->    |\ | <-- highest possible offset for triangle
			//                   ____| \|
			//upperDiff       -->    |  |\ <-- possible rounded corner
			//                   ----+--+-'-----...
			//                          |  \  /
			//                          |   \/
			//                          +-------...
			//
			// We calculate lowerDiff and upperDiff by considering the offset and width of the payload (this.element)
			// versus the offset and width of the element enclosing the triangle, because the payload is inside
			// whatever decorations (such as borders, shadow, rounded corners) and thus can give a reliable indication
			// of the thickness of the combined decorations

				arrowBeg = ctxpopup._ui.arrow[arrow].offset()[coord.beg],
				arrowSize = ctxpopup._ui.arrow[arrow][coord.outerSize]( true ),
				payloadBeg = self.element.offset()[coord.beg],
				payloadSize = self.element[coord.outerSize]( true ),
				triangleSize = ctxpopup._ui.arrow[arrow][coord.triangleSize](),
				triangleOffset,
				finalposition,
				ret;
			if (isHorizontal) {
				orig.x = 0;
			} else {
				orig.y = 0;
			}
			if (arrow == 'b' && self._target_height) {
				orig.y -= self._target_height;
			}
			if (arrow == 'r' && self._target_width) {
				orig.x -= self._target_width;
			}
			triangleOffset =
				Math.max(
					triangleSize // triangle size
						+ Math.max( 0, payloadBeg - arrowBeg ), // lowerDiff
					Math.min(
							arrowSize // bottom
								- triangleSize // triangle size
								- Math.max( 0, arrowBeg + arrowSize - ( payloadBeg + payloadSize ) ), // upperDiff
							arrowSize / 2 // arrow unrestricted offset
								+ desired[coord.point]
								- orig[coord.point]
								- halfSize[coord.size]
						)
				);
					// Triangle points here
			finalposition = {
				"x": orig.x + ( isHorizontal ? triangleOffset : 0) + ("r" === arrow ? size.cx : 0),
				"y": orig.y + (!isHorizontal ? triangleOffset : 0) + ("b" === arrow ? size.cy : 0)
			};
			ret = {
				actual			: orig,
				triangleOffset	: triangleOffset,
				absDiff			: Math.abs( x - finalposition.x ) + Math.abs( y - finalposition.y )
			};

			// Hide it back
			ctxpopup._ui.arrow[arrow].hide();

			return ret;
		}

		if ( ctxpopup ) {
			// Returns:
			// {
			//    absDiff: int
			//    triangleOffset: int
			//    actual: { x: int, y: int }
			// }

			coords = {
				l : getCoords( "l", 1, 0 ),
				r : getCoords( "r", -1, 0 ),
				t : getCoords( "t", 0, 1 ),
				b : getCoords( "b", 0, -1 )
			};

			$.each( coords, function ( key, value ) {
				if ( minDiff === undefined || value.absDiff < minDiff ) {
					minDiff = value.absDiff;
					minDiffIdx = key;
				}
			} );

			// Side-effect: show the appropriate arrow and move it to the right offset
			ctxpopup._ui.arrow[minDiffIdx]
				.show()
				.triangle( "option", "offset", coords[minDiffIdx].triangleOffset );
			this.element.parents( ".ui-popupwindow" ).addClass( "ui-arrow-" + minDiffIdx );
			return coords[minDiffIdx].actual;
		}

		return orig_placementCoords.call( this, x, y, cx, cy );
	};

	$.tizen.popupwindow.prototype.open = function ( x, y, target_width, target_height ) {
		var ctxpopup = this.element.data( "ctxpopup" );

		this._target_width = target_width;
		this._target_height = target_height;

		if ( ctxpopup ) {
			this._setFade( false );
			this._setShadow( false );
			this._setCorners( false );
			this._setOverlayTheme( null );
			this._setOption( "overlayTheme", ctxpopup.options.overlayTheme );
			ctxpopup._ui.arrow.all.triangle( "option", "color", ctxpopup._ui.container.css( "background-color" ) );

			// temporary
			$( '.ui-popupwindow' ).css( 'background', 'none' );
		}

		origOpen.call( this, x, y, true );
	};

	//auto self-init widgets
	$( document ).bind( "pagecreate create", function ( e ) {
		var ctxpopups = $( $.tizen.ctxpopup.prototype.options.initSelector, e.target );
		$.tizen.ctxpopup.prototype.enhanceWithin( e.target );
	} );
}( jQuery ) );



/*global Globalize:false, range:false, regexp:false*/
/*
 * jQuery Mobile Widget @VERSION
 *
 * This software is licensed under the MIT licence (as defined by the OSI at
 * http://www.opensource.org/licenses/mit-license.php)
 *
 * ***************************************************************************
 * Copyright (C) 2011 by Intel Corporation Ltd.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 * ***************************************************************************
 *
 * Authors: Salvatore Iovene <salvatore.iovene@intel.com>
 *			Daehyon Jung <darrenh.jung@samsung.com>
 */

/**
 * datetimepicker is a widget that lets the user select a date and/or a 
 * time. If you'd prefer use as auto-initialization of form elements, 
 * use input elements with type=date/time/datetime within form tag
 * as same as other form elements.
 * 
 * HTML Attributes:
 * 
 *	data-role: 'datetimepicker'
 *	data-format: date format string. e.g) "MMM dd yyyy, HH:mm"
 *	type: 'date', 'datetime', 'time'
 *	value: pre-set value. only accepts ISO date string. e.g) "2012-05-04", "2012-05-04T01:02:03+09:00" 
 *	data-date: any date/time string "new Date()" accepts.
 *
 * Options:
 *	type: 'date', 'datetime', 'time'
 *	format: see data-format in HTML Attributes.
 *	value: see value in HTML Attributes.
 *	date: preset value as JavaScript Date Object representation.
 *
 * APIs:
 *	value( datestring )
 *		: Set date/time to 'datestring'.
 *	value()
 *		: Get current selected date/time as W3C DTF style string.
 *	getValue() - replaced with 'value()'
 *		: same as value()
 *	setValue( datestring ) - replaced with 'value(datestring)'
 *		: same as value( datestring )
 *	changeTypeFormat( type, format ) - deprecated
 *		: Change Type and Format options. use datetimepicker( "option", "format" ) instead
 *
 * Events:
 *	date-changed: Raised when date/time was changed. Date-changed event will be deprecated
 *
 * Examples:
 *	<ul data-role="listview">
 *		<li class="ui-li-3-2-2">
 *			<span class="ui-li-text-main">
 *				<input type="datetime" name="demo-date" id="demo-date" 
 *					data-format="MMM dd yyyy hh:mm tt"/>
 *			</span>
 *			<span class="ui-li-text-sub">
 *				Date/Time Picker - <span id="selected-date1"><em>(select a date first)</em></span>
 *			</span>
 *		</li>
 *		<li class="ui-li-3-2-2">
 *			<span class="ui-li-text-main">
 *				<input type="date" name="demo-date2" id="demo-date2"/>
 *			</span>
 *			<span class="ui-li-text-sub">
 *				Date Picker  - <span id="selected-date2"><em>(select a date first)</em></span>
 *			</span>
 *		</li>
 *		<li class="ui-li-3-2-2">
 *			<span class="ui-li-text-main">
 *				<input type="time" name="demo-date3" id="demo-date3"/>
 *			</span>
 *			<span class="ui-li-text-sub">
 *				Time Picker - <span id="selected-date3"><em>(select a date first)</em></span>
 *			</span>
 *		</li>
 *	</ul>
 * How to get a return value:
 * ==========================
 * Bind to the 'date-changed' event, e.g.:
 *    $("#myDatetimepicker").bind("change", function() {
 *			// your code
 *    });
 */

/**
	@class DateTimePicker
	The picker widgets show a control that you can use to enter date and time values. <br/> To add a date time picker widget to the application, use the following code:

			<li class="ui-li-dialogue ui-datetime">
				<div class="ui-datetime-text-main">
					<input type="datetime" data-format="MMM dd yyyy hh:mm:ss" name="demo-date" id="demo-date" />
				</div>
				<div class="ui-li-text-sub">Date/Time Picker
					<span id="selected-date1"><em>(select a date first)</em></span>
				</div>
			</li>
*/


( function ( $, window, undefined ) {
	$.widget( "tizen.datetimepicker", $.tizen.widgetex, {

		options: {
			type: null, // date, time, datetime applicable
			format: null,
			date: null,
			initSelector: "input[type='date'], input[type='datetime'], input[type='time'], :jqmData(role='datetimepicker')"
		},

		container : null,

		_calendar: function () {
			return Globalize.culture().calendars.standard;
		},

		_value: {
			attr: "data-" + ( $.mobile.ns || "" ) + "date",
			signal: "date-changed"
		},

		_daysInMonth: [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ],

		_isLeapYear: function ( year ) {
			return year % 4 ? 0 : ( year % 100 ? 1 : ( year % 400 ? 0 : 1 ) );
		},

		_makeTwoDigits: function ( val ) {
			var ret = val.toString(10);
			if ( val < 10 ) {
				ret = "0" + ret;
			}
			return ret;
		},

		_setType: function ( type ) {
			//datetime, date, time
			switch (type) {
			case 'datetime':
			case 'date':
			case 'time':
				this.options.type = type;
				break;
			default:
				this.options.type = 'datetime';
				break;
			}

			this.element.attr( "data-" + ( $.mobile.ns ? $.mobile.ns + "-" : "" ) + "type", this.options.type );
			return this.options.type;
		},

		_setFormat: function ( format ) {
			if ( this.options.format != format ) {
				this.options.format = format;
			} else {
				return;
			}

			this.ui.children().remove();

			var token = this._parsePattern( format ),
				div = document.createElement('div'),
				pat,
				tpl,
				tpl2,
				period,
				btn,
				obj = this;

			while ( token.length > 0 ) {
				pat = token.shift();
				tpl = '<span class="ui-btn-picker ui-datefield-%1"' +
					'data-role="button" data-inline="true" data-pat="' + pat + '">%2</span>';
				tpl2= '<span class="ui-datefield-%1" data-pat="' + pat + '">%2</span>';
				switch ( pat ) {
				case 'H': //0 1 2 3 ... 21 22 23
				case 'HH': //00 01 02 ... 21 22 23
				case 'h': //0 1 2 3 ... 11 12
				case 'hh': //00 01 02 ... 11 12
					$(div).append( tpl.replace('%1', 'hour') );
					break;
				case 'mm': //00 01 ... 59
				case 'm': //0 1 2 ... 59
					if ( this.options.type == 'date' ) {
						$(div).append( tpl.replace('%1', 'month') );
					} else {
						$(div).append( tpl.replace('%1', 'min') );
					}
					break;
				case 'ss':
				case 's':
					$(div).append( tpl.replace('%1', 'sec') );
					break;
				case 'd': // day of month 5
				case 'dd': // day of month(leading zero) 05
					$(div).append( tpl.replace('%1', 'day') );
					break;
				case 'M': // Month of year 9
				case 'MM': // Month of year(leading zero) 09
				case 'MMM':
				case 'MMMM':
					$(div).append( tpl.replace('%1', 'month') );
					break;
				case 'yy':	// year two digit
				case 'yyyy': // year four digit
					$(div).append( tpl.replace('%1', 'year') );
					break;
				case 't': //AM / PM indicator(first letter) A, P
					// add button
				case 'tt': //AM / PM indicator AM/PM
					// add button
					btn = '<a href="#" class="ui-datefield-period"' +
						' data-role="button" data-inline="true">period</a>';
					$(div).append( btn );
					break;
				case 'g':
				case 'gg':
					$(div).append( tpl.replace('%1', 'era').replace('%2', this._calendar().eras.name) );
					break;
				case '\t':
					$(div).append( tpl2.replace('%1', 'tab')
							.replace('%2', "<div class='ui-divider-1st'>&nbsp;</div>" +
								"<div class='ui-divider-2nd'>&nbsp;</div>") );
					break;
				default : // string or any non-clickable object
					$(div).append( tpl2.replace('%1', 'seperator').replace('%2', pat.split(/[\-\/]/).join("") ) );
					break;
				}
			}

			this.ui.append( div );
			if ( this.options.date ) {
				this._setDate( this.options.date );
			}

			this.ui.find('.ui-btn-picker').buttonMarkup();
			this.ui.find('.ui-datefield-period').buttonMarkup().bind( 'vclick', function ( e ) {
				obj._switchAmPm( obj );
				return false;
			});

			this.element.attr( "data-" + ( $.mobile.ns ? $.mobile.ns + "-" : "" ) + "format", this.options.format );
			return this.options.format;
		},

		_setDate: function ( newdate ) {
			if ( typeof ( newdate ) == "string" ) {
				newdate = new Date( newdate );
			}

			var fields = $('span,a', this.ui),
				type,
				fn,
				$field,
				btn,
				i;

			function getMonth() {
				return newdate.getMonth() + 1;
			}

			for ( i = 0; i < fields.length; i++ ) {
				$field = $(fields[i]);
				type = $field.attr("class").match(/ui-datefield-([\w]*)/);
				if ( !type ) {
					type = "";
				}
				switch ( type[1] ) {
				case 'hour':
					fn = newdate.getHours;
					break;
				case 'min':
					fn = newdate.getMinutes;
					break;
				case 'sec':
					fn = newdate.getSeconds;
					break;
				case 'year':
					fn = newdate.getFullYear;
					break;
				case 'month':
					fn = getMonth;
					break;
				case 'day':
					fn = newdate.getDate;
					break;
				case 'period':
					fn = newdate.getHours() < 12 ? this._calendar().AM[0] : this._calendar().PM[0];
					btn = $field.find( '.ui-btn-text' );
					if ( btn.length == 0 ) {
						$field.text(fn);
					} else if ( btn.text() != fn ) {
						btn.text( fn );
					}
					fn = null;
					break;
				default:
					fn = null;
					break;
				}
				if ( fn ) {
					this._updateField( $field, fn.call( newdate ) );
				}
			}

			this.options.date = newdate;

			this._setValue( newdate );

			this.element.attr( "data-" + ( $.mobile.ns ? $.mobile.ns + "-" : "" ) + "date", this.options.date );
			return this.options.date;
		},

		destroy: function () {
			if ( this.ui ) {
				this.ui.remove();
			}

			if ( this.element ) {
				this.element.show();
			}
		},

		value: function ( val ) {
			function timeStr( t, obj ) {
				return obj._makeTwoDigits( t.getHours() ) + ':' +
					obj._makeTwoDigits( t.getMinutes() ) + ':' +
					obj._makeTwoDigits( t.getSeconds() );
			}

			function dateStr( d, obj ) {
				return ( ( d.getFullYear() % 10000 ) + 10000 ).toString().substr(1) + '-' +
					obj._makeTwoDigits( d.getMonth() + 1 ) + '-' +
					obj._makeTwoDigits( d.getDate() );
			}

			var rvalue = null;
			if ( val ) {
				rvalue = this._setDate( val );
			} else {
				switch ( this.options.type ) {
				case 'time':
					rvalue = timeStr( this.options.date, this );
					break;
				case 'date':
					rvalue = dateStr( this.options.date, this );
					break;
				default:
					rvalue = dateStr( this.options.date, this ) + 'T' + timeStr( this.options.date, this );
					break;
				}
			}
			return rvalue;
		},

		setValue: function ( newdate ) {
			console.warn( "setValue was deprecated. use datetimepicker('option', 'date', value) instead." );
			return this.value( newdate );
		},

		/**
		 * return W3C DTF string
		 */
		getValue: function () {
			console.warn("getValue() was deprecated. use datetimepicker('value') instead.");
			return this.value();
		},

		_updateField: function ( target, value ) {
			if ( !target || target.length == 0 ) {
				return;
			}

			if ( value == 0 ) {
				value = "0";
			}

			var pat = target.jqmData( 'pat' ),
				hour,
				text,
				self = this;

			switch ( pat ) {
			case 'H':
			case 'HH':
			case 'h':
			case 'hh':
				hour = value;
				if ( pat.charAt(0) == 'h' ) {
					if ( hour > 12 ) {
						hour -= 12;
					} else if ( hour == 0 ) {
						hour = 12;
					}
				}
				hour = this._makeTwoDigits( hour );
				text = hour;
				break;
			case 'm':
			case 'M':
			case 'd':
			case 's':
				text = value;
				break;
			case 'mm':
			case 'dd':
			case 'MM':
			case 'ss':
				text = this._makeTwoDigits( value );
				break;
			case 'MMM':
				text = this._calendar().months.namesAbbr[ value - 1];
				break;
			case 'MMMM':
				text = this._calendar().months.names[ value - 1 ];
				break;
			case 'yy':
				text = this._makeTwoDigits( value % 100 );
				break;
			case 'yyyy':
				if ( value < 10 ) {
					value = '000' + value;
				} else if ( value < 100 ) {
					value = '00' + value;
				} else if ( value < 1000 ) {
					value = '0' + value;
				}
				text = value;
				break;
			}

			// to avoid reflow where its value isn't out-dated
			if ( target.text() != text ) {
				if ( target.hasClass("ui-datefield-selected") ) {
					target.addClass("out");
					this._new_value = text;

					target.animationComplete( function () {
						target.text( self._new_value);
						target.addClass("in")
							.removeClass("out");

						target.animationComplete( function () {
							target.removeClass("in").
								removeClass("ui-datefield-selected");
						});
					});
				} else {
					target.text( text );
				}
			}
		},

		_switchAmPm: function ( obj ) {
			if ( this._calendar().AM != null ) {
				var date = new Date( this.options.date ),
					text,
					change = 1000 * 60 * 60 * 12;
				if ( date.getHours() > 11 ) {
					change = -change;
				}
				date.setTime( date.getTime() + change );
				this._setDate( date );
			}
		},

		_parsePattern: function ( pattern ) {
			var regex = /\/|\s|dd|d|MMMM|MMM|MM|M|yyyy|yy|y|hh|h|HH|H|mm|m|ss|s|tt|t|f|gg|g|\'[\w\W]*\'$|[\w\W]/g,
				matches,
				i;

			matches = pattern.match( regex );

			for ( i = 0; i < matches.length; i++ ) {
				if ( matches[i].charAt(0) == "'" ) {
					matches[i] = matches[i].substr( 1, matches[i].length - 2 );
				}
			}

			return matches;
		},

		changeTypeFormat: function ( type, format ) {
			console.warn('changeTypeFormat() was deprecated. use datetimepicker("option", "type"|"format", value) instead');
			if ( type ) {
				this._setType( type );
			}

			if ( format ) {
				this._setFormat( format );
			}
		},

		_create: function () {
			var obj = this;

			if ( this.element.is( "input" ) ) {
				( function ( obj ) {
					var type, value, format;

					type = obj.element.get(0).getAttribute( "type" );
					obj.options.type = type;

					value = obj.element.get(0).getAttribute( "value" );
					if ( value ) {
						obj.options.date = new Date( value );
					}
				}( this ) );
			}

			if ( !this.options.format ) {
				switch ( this.options.type ) {
				case 'datetime':
					this.options.format = this._calendar().patterns.d + "\t" + this._calendar().patterns.t;
					break;
				case 'date':
					this.options.format = this._calendar().patterns.d;
					break;
				case 'time':
					this.options.format = this._calendar().patterns.t;
					break;
				}
			}

			if ( !this.options.date ) {
				this.options.date = new Date();
			}

			this.element.hide();
			this.ui = $('<div class="ui-datefield"></div>');
			$(this.element).after( this.ui );

			this._popup_open = false;
			this.ui.bind('vclick', function ( e ) {
				obj._showDataSelector( obj, this, e.target );
			});

			$.extend( this, {
				_globalHandlers: [
					{
						src: $( window ),
						handler: {
							orientationchange: $.proxy( this, "_orientationHandler" )
						}
					}
				]
			});

			$.each( this._globalHandlers, function( idx, value ) {
				value.src.bind( value.handler );
			});
		},
		_orientationHandler: function() {
			var self = this;
			if( self._popup_open ) {
				self._popup_open = false;
				self.container.popupwindow( 'close' );
			}
			return false;
		},
		_populateDataSelector: function ( field, pat ) {
			var values,
				numItems,
				current,
				data,
				range = window.range,
				local,
				yearlb,
				yearhb,
				day;

			switch ( field ) {
			case 'hour':
				if ( pat == 'H' || pat == 'HH' ) {
					// twentyfour
					values = range( 0, 23 );
					data = range( 0, 23 );
					current = this.options.date.getHours();
				} else {
					values = range( 1, 12 );
					current = this.options.date.getHours() - 1;//11
					if ( current >= 11 ) {
						current = current - 12;
						data = range( 13, 23 );
						data.push( 12 ); // consider 12:00 am as 00:00
					} else {
						data = range( 1, 11 );
						data.push( 0 );
					}
					if ( current < 0 ) {
						current = 11; // 12:00 or 00:00
					}
				}
				if ( pat.length == 2 ) {
					// two digit
					values = values.map( this._makeTwoDigits );
				}
				numItems = values.length;
				break;
			case 'min':
			case 'sec':
				values = range( 0, 59 );
				if ( pat.length == 2 ) {
					values = values.map( this._makeTwoDigits );
				}
				data = range( 0, 59 );
				current = ( field == 'min' ? this.options.date.getMinutes() : this.options.date.getSeconds() );
				numItems = values.length;
				break;
			case 'year':
				yearlb = 1900;
				yearhb = 2100;
				data = range( yearlb, yearhb );
				current = this.options.date.getFullYear() - yearlb;
				values = range( yearlb, yearhb );
				numItems = values.length;
				break;
			case 'month':
				switch ( pat.length ) {
				case 1:
					values = range( 1, 12 );
					break;
				case 2:
					values = range( 1, 12 ).map( this._makeTwoDigits );
					break;
				case 3:
					values = this._calendar().months.namesAbbr.slice();
					break;
				case 4:
					values = this._calendar().months.names.slice();
					break;
				}
				if ( values.length == 13 ) { // @TODO Lunar calendar support
					if ( values[12] == "" ) { // to remove lunar calendar reserved space
						values.pop();
					}
				}
				data = range( 1, values.length );
				current = this.options.date.getMonth();
				numItems = values.length;
				break;
			case 'day':
				day = this._daysInMonth[ this.options.date.getMonth() ];
				if ( day == 28 ) {
					day += this._isLeapYear( this.options.date.getFullYear() );
				}
				values = range( 1, day );
				if ( pat.length == 2 ) {
					values = values.map( this._makeTwoDigits );
				}
				data = range( 1, day );
				current = this.options.date.getDate() - 1;
				numItems = day;
				break;
			}

			return {
				values: values,
				data: data,
				numItems: numItems,
				current: current
			};

		},

		_showDataSelector: function ( obj, ui, target ) {
			target = $(target);

			var attr = target.attr("class"),
				field = attr ? attr.match(/ui-datefield-([\w]*)/) : undefined,
				pat,
				data,
				values,
				numItems,
				current,
				valuesData,
				html,
				datans,
				$ul,
				$div,
				$ctx,
				$li,
				i,
				newLeft = 10,
				self = this;

			if ( !attr ) {
				return;
			}
			if ( !field ) {
				return;
			}
			if ( this._popup_open ) {
				return;
			}

			target.not('.ui-datefield-seperator').addClass('ui-datefield-selected');

			pat = target.jqmData('pat');
			data = obj._populateDataSelector.call( obj, field[1], pat );

			values = data.values;
			numItems = data.numItems;
			current = data.current;
			valuesData = data.data;

			if ( values ) {
				datans = "data-" + ($.mobile.ns ? ($.mobile.ns + '-') : "") + 'val="';
				for ( i = 0; i < values.length; i++ ) {
					html += '<li><a class="ui-link" ' + datans + valuesData[i] + '">' + values[i] + '</a></li>';
				}

				$ul = $("<ul></ul>");
				$div = $('<div class="ui-datetimepicker-selector" data-transition="fade" data-fade="false"></div>');
				$div.append( $ul ).appendTo( ui );
				$ctx = $div.ctxpopup();
				$ctx.parents('.ui-popupwindow').addClass('ui-datetimepicker');
				$li = $(html);
				$( $li[current] ).addClass("current");
				$div.jqmData( "list", $li );
				$div.circularview();
				if( !obj._reflow ) {
					obj._reflow = function() {
						$div.circularview( "reflow" );
						$div.circularview( 'centerTo', '.current', 0 );
					}
					$(window).bind( "resize" , obj._reflow );
				}
				if( !obj._close ) {
					obj._close = function() {
						$div.trigger( "popupafterclose" );
					}
					$(window).bind( "navigate", obj._close );
				}
				$ctx.popupwindow( 'open',
						target.offset().left + ( target.width() / 2 ) - window.pageXOffset ,
						target.offset().top + target.height() - window.pageYOffset, target.width(), target.height() );

				this.container = $ctx;
				this._popup_open = true;

				$div.bind('popupafterclose', function ( e ) {
					if ( obj._reflow ) {
						$(window).unbind( "resize", obj._reflow );
						obj._reflow = null;
					}

					if ( obj._close ) {
						$(window).unbind( "navigate", obj._close );
						obj._close = null;
					}

					if ( !( target.hasClass("in") || target.hasClass("out") ) ) {
						target.removeClass("ui-datefield-selected");
					}

					$div.unbind( 'popupafterclose' );
					$ul.unbind( 'vclick' );
					$(obj).unbind( 'update' );
					$ctx.popupwindow( 'destroy' );
					$div.remove();

					self._popup_open = false;
				});

				$(obj).bind( 'update', function ( e, val ) {
					var date = new Date( this.options.date ),
						month,
						date_calibration = function () {
							date.setDate( 1 );
							date.setDate( date.getDate() - 1 );
						};

					switch ( field[1] ) {
					case 'min':
						date.setMinutes( val );
						break;
					case 'hour':
						date.setHours( val );
						break;
					case 'sec':
						date.setSeconds( val );
						break;
					case 'year':
						month = date.getMonth();
						date.setFullYear( val );

						if ( date.getMonth() != month ) {
							date_calibration();
						}
						break;
					case 'month':
						date.setMonth( val - 1 );

						if ( date.getMonth() == val ) {
							date_calibration();
						}
						break;
					case 'day':
						date.setDate( val );
						break;
					}

					obj._setDate( date );

					$ctx.popupwindow( 'close' );
				});

				$ul.bind( 'click', function ( e ) {
					if ( $(e.target).is('a') ) {
						$ul.find(".current").removeClass("current");
						$(e.target).parent().addClass('current');
						var val = $(e.target).jqmData("val");
						$(obj).trigger( 'update', val ); // close popup, unselect field
					}
				});

				$div.circularview( 'centerTo', '.current', 500 );
				$div.bind( 'scrollend' , function ( e ) {
					if ( !obj._reflow ) {
						obj._reflow = function () {
							$div.circularview("reflow");
						};
						$(window).bind("resize", obj._reflow);
					}
				});
			}
			return ui;
		}

	});

	$(document).bind("pagecreate create", function ( e ) {
		$($.tizen.datetimepicker.prototype.options.initSelector, e.target)
			.not(":jqmData(role='none'), :jqmData(role='nojs')")
			.datetimepicker();
	});

} ( jQuery, this ) );


(function($){$.tizen.frameworkData.pkgVersion="0.2.50";}(jQuery));
