// jquery.momentum.js - version 0.8 - Kin Blas (jblas@adobe.com)
//
// Copyright (c) 2010. Adobe Systems Incorporated.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of Adobe Systems Incorporated nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

(function(c,f,g,a){var b={fps:60,direction:null,scrollDuration:2000,overshootDuration:250,snapbackDuration:500,moveThreshold:100,startEventName:"MomentumScroller.start",updateEventName:"MomentumScroller.update",stopEventName:"MomentumScroller.stop",eventType:("ontouchend" in g)?"touch":"mouse",showScrollBars:true};function h(n,l){this.opts=c.extend({},b,l);this.$clip=c(n);this.$view=this.$clip.children(":first-child");var m=this.opts.direction;this.hTracker=(m!="vertical")?new e():null;this.vTracker=(m!="horizontal")?new e():null;this.timerInterval=1000/this.opts.fps;this.timerID=0;var k=this;this.timerCB=function(){k.handleMomentumScroll()};this.addBehaviors()}c.extend(h.prototype,{startMScroll:function(o,n){this.stopMScroll();this.showScrollBars();var l=false;var m=this.opts.scrollDuration;this.$clip.trigger(this.opts.startEventName);var r=this.hTracker;if(r){var k=parseInt(this.$view.css("left").replace(/[^-+\d\.]/g,""),10);var q=this.$clip.width();var s=this.$view.width();r.start(k,o,m,(s>q)?-(s-q):0,0);l=!r.done()}var t=this.vTracker;if(t){var k=parseInt(this.$view.css("top").replace(/[^-+\d\.]/g,""),10);var q=this.$clip.height();var s=this.$view.height();t.start(k,n,m,(s>q)?-(s-q):0,0);l=l||!t.done()}if(l){this.timerID=setTimeout(this.timerCB,this.timerInterval)}else{this.stopMScroll()}},stopMScroll:function(){if(this.timerID){this.$clip.trigger(this.opts.stopEventName);clearTimeout(this.timerID)}this.timerID=0;if(this.vTracker){this.vTracker.reset()}if(this.hTracker){this.hTracker.reset()}this.hideScrollBars()},handleMomentumScroll:function(){var n=false;var l=this.$view;var k=0,p=0;var o=this.vTracker;if(o){o.update();p=o.getPosition();n=!o.done()}var m=this.hTracker;if(m){m.update();k=m.getPosition();n=n||!m.done()}this.setScrollPosition(k,p);this.$clip.trigger(this.opts.updateEventName,{x:k,y:p});if(n){this.timerID=setTimeout(this.timerCB,this.timerInterval)}else{this.stopMScroll()}},setScrollPosition:function(k,m){this.$view.css({left:k+"px",top:m+"px"});if(this.$vScrollBar){var l=this.$view.height();this.$vScrollBar.find(".ui-scrollbar-thumb").css("top",-m/l*100+"%")}if(this.$hScrollBar){var l=this.$view.width();this.$hScrollBar.find(".ui-scrollbar-thumb").css("left",-k/l*100+"%")}},handleMouseDown:function(n,p,o){this.stopMScroll();var q=this.$clip;var s=this.$view;this.doSnapBackX=false;this.doSnapBackY=false;this.speedX=0;this.speedY=0;if(this.hTracker){var l=parseInt(q.css("width"),10);var r=parseInt(s.css("width"),10);this.maxX=l-r;if(this.maxX>0){this.maxX=0}this.lastX=p;if(this.$hScrollBar){this.$hScrollBar.find(".ui-scrollbar-thumb").css("width",(l>=r?"100%":Math.floor(l/r*100)+"%"))}}if(this.vTracker){var k=parseInt(q.css("height"),10);var m=parseInt(s.css("height"),10);this.maxY=k-m;if(this.maxY>0){this.maxY=0}this.lastY=o;if(this.$vScrollBar){this.$vScrollBar.find(".ui-scrollbar-thumb").css("height",(k>=m?"100%":Math.floor(k/m*100)+"%"))}}this.lastMove=0;this.enableTracking();if(this.opts.eventType=="mouse"){n.preventDefault()}},handleMouseMove:function(l,n,m){this.lastMove=j();var q=this.$view;var k=0;var s=0;if(this.hTracker){var t=n-this.lastX;var p=parseInt(q.css("left"),10);this.speedX=t;k=p+t;this.doSnapBackX=false;if(k>0||k<this.maxX){k=p+(t/2);this.doSnapBackX=true}this.lastX=n}if(this.vTracker){var r=m-this.lastY;var o=parseInt(q.css("top"),10);this.speedY=r;s=o+r;this.doSnapBackY=false;if(s>0||s<this.maxY){s=o+(r/2);this.doSnapBackY=true}this.lastY=m}this.setScrollPosition(k,s);this.showScrollBars();l.preventDefault()},handleMouseUp:function(o){var m=this.lastMove;var n=j();var k=m&&(n-m)<=this.opts.moveThreshold;var q=(this.hTracker&&this.speedX&&k)?this.speedX:(this.doSnapBackX?1:0);var p=(this.vTracker&&this.speedY&&k)?this.speedY:(this.doSnapBackY?1:0);if(q||p){this.startMScroll(q,p)}else{this.hideScrollBars()}this.disableTracking()},enableTracking:function(){c(g).bind(this.mousemoveType,this.mousemoveCB);c(g).bind(this.mouseupType,this.mouseupCB)},disableTracking:function(){c(g).unbind(this.mousemoveType,this.mousemoveCB);c(g).unbind(this.mouseupType,this.mouseupCB)},showScrollBars:function(){var k="ui-scrollbar-visible";if(this.$vScrollBar){this.$vScrollBar.addClass(k)}if(this.$hScrollBar){this.$hScrollBar.addClass(k)}},hideScrollBars:function(){var k="ui-scrollbar-visible";if(this.$vScrollBar){this.$vScrollBar.removeClass(k)}if(this.$hScrollBar){this.$hScrollBar.removeClass(k)}},addBehaviors:function(){var k=this;if(this.opts.eventType=="mouse"){this.mousedownType="mousedown";this.mousedownCB=function(o){return k.handleMouseDown(o,o.clientX,o.clientY)};this.mousemoveType="mousemove";this.mousemoveCB=function(o){return k.handleMouseMove(o,o.clientX,o.clientY)};this.mouseupType="mouseup";this.mouseupCB=function(o){return k.handleMouseUp(o)}}else{this.mousedownType="touchstart";this.mousedownCB=function(p){var o=p.originalEvent.targetTouches[0];return k.handleMouseDown(p,o.pageX,o.pageY)};this.mousemoveType="touchmove";this.mousemoveCB=function(p){var o=p.originalEvent.targetTouches[0];return k.handleMouseMove(p,o.pageX,o.pageY)};this.mouseupType="touchend";this.mouseupCB=function(o){return k.handleMouseUp(o)}}this.$view.bind(this.mousedownType,this.mousedownCB);if(this.opts.showScrollBars){var l=this.$clip;var m='<div class="ui-scrollbar ui-scrollbar-';var n='"><div class="ui-scrollbar-track"><div class="ui-scrollbar-thumb"></div></div></div>';if(this.vTracker){l.append(m+"vertical"+n);this.$vScrollBar=l.children(".ui-scrollbar-vertical")}if(this.hTracker){l.append(m+"horizontal"+n);this.$hScrollBar=l.children(".ui-scrollbar-horizontal")}}}});function e(){this.easing="easeOutQuad";this.reset()}var i={scrolling:0,overshot:1,snapback:2,done:3};function j(){return(new Date()).getTime()}c.extend(e.prototype,{start:function(o,m,n,l,k){this.state=(m!=0)?((o<l||o>k)?i.snapback:i.scrolling):i.done;this.pos=o;this.speed=m;this.duration=(this.state==i.snapback)?b.snapbackDuration:n;this.minPos=l;this.maxPos=k;this.fromPos=(this.state==i.snapback)?this.pos:0;this.toPos=(this.state==i.snapback)?((this.pos<this.minPos)?this.minPos:this.maxPos):0;this.startTime=j()},reset:function(){this.state=i.done;this.pos=0;this.speed=0;this.minPos=0;this.maxPos=0;this.duration=0},update:function(){var o=this.state;if(o==i.done){return this.pos}var p=this.duration;var l=j()-this.startTime;l=l>p?p:l;if(o==i.scrolling||o==i.overshot){var m=this.speed*(1-c.easing[this.easing](l/p,l,0,1,p));var k=this.pos+m;var n=(o==i.scrolling)&&(k<this.minPos||k>this.maxPos);if(n){k=(k<this.minPos)?this.minPos:this.maxPos}this.pos=k;if(o==i.overshot){if(l>=p){this.state=i.snapback;this.fromPos=this.pos;this.toPos=(k<this.minPos)?this.minPos:this.maxPos;this.duration=b.snapbackDuration;this.startTime=j();l=0}}else{if(o==i.scrolling){if(n){this.state=i.overshot;this.speed=m/2;this.duration=b.overshootDuration;this.startTime=j()}else{if(l>=p){this.state=i.done}}}}}else{if(o==i.snapback){if(l>=p){this.pos=this.toPos;this.state=i.done}else{this.pos=this.fromPos+((this.toPos-this.fromPos)*c.easing[this.easing](l/p,l,0,1,p))}}}return this.pos},done:function(){return this.state==i.done},getPosition:function(){return this.pos}});function d(m,l){var n=c.extend({direction:"vertical"},l);var k=c(m);$parent=k.wrap('<div class="ui-category-list ui-momentum-scroller"></div>').addClass("ui-category-list-view ui-momentum-scroller-view").parent();k.children("li").addClass("ui-category").children(":first-child").addClass("ui-category-header").end().children("ul").addClass("ui-category-items").children("li").addClass("ui-category-item");h.call(this,$parent,n);this.lastHeader=null}c.extend(d.prototype,h.prototype,{setScrollPosition:function(v,u){h.prototype.setScrollPosition.call(this,v,u);u=-u;var m=null;var l=this.$view.find(".ui-category");var o=l.length;for(var r=0;r<o;r++){var n=l.get(r);var t=n.offsetHeight;var q=n.offsetTop;if(u>=q&&u<=(q+t)){m=n;break}}if(m){var w=c(m).children(".ui-category-header").get(0);if(this.lastHeader&&w!=this.lastHeader){this.lastHeader.style.top="0px";this.lastHeader=null}if(w){var z=u-m.offsetTop;var p=w.offsetHeight;var k=m.offsetHeight;if(z+p>k){z=k-p}w.style.top=z+"px";this.lastHeader=w}}}});c.MomentumScroller=h;c.MomentumScroller.config=b;c.fn.extend({momentumScroller:function(k){this.each(function(){c(this).data("momentumScroller",new h(this,k))});return this},categoryList:function(k){this.each(function(){c(this).data("categoryList",new d(this,k))});return this}})})(jQuery,window,document);
