
// usage: log('inside coolFunc', this, arguments);
// paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
window.log = function(){
  log.history = log.history || [];   // store logs to an array for reference
  log.history.push(arguments);
  if(this.console) {
    arguments.callee = arguments.callee.caller;
    var newarr = [].slice.call(arguments);
    (typeof console.log === 'object' ? log.apply.call(console.log, console, newarr) : console.log.apply(console, newarr));
  }
};

// make it safe to use console.log always
(function(b){function c(){}for(var d="assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,timeStamp,profile,profileEnd,time,timeEnd,trace,warn".split(","),a;a=d.pop();){b[a]=b[a]||c}})((function(){try
{console.log();return window.console;}catch(err){return window.console={};}})());
/*
 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
 *
 * Uses the built in easing capabilities added In jQuery 1.1
 * to offer multiple easing options
 *
 * TERMS OF USE - jQuery Easing
 * 
 * Open source under the BSD License. 
 * 
 * Copyright © 2008 George McGinley Smith
 * 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 the author nor the names of 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. 
 *
*/

// t: current time, b: begInnIng value, c: change In value, d: duration
jQuery.easing['jswing'] = jQuery.easing['swing'];

jQuery.extend( jQuery.easing,
{
	def: 'easeOutQuad',
	swing: function (x, t, b, c, d) {
		//alert(jQuery.easing.default);
		return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
	},
	easeInQuad: function (x, t, b, c, d) {
		return c*(t/=d)*t + b;
	},
	easeOutQuad: function (x, t, b, c, d) {
		return -c *(t/=d)*(t-2) + b;
	},
	easeInOutQuad: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t + b;
		return -c/2 * ((--t)*(t-2) - 1) + b;
	},
	easeInCubic: function (x, t, b, c, d) {
		return c*(t/=d)*t*t + b;
	},
	easeOutCubic: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t + 1) + b;
	},
	easeInOutCubic: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t + b;
		return c/2*((t-=2)*t*t + 2) + b;
	},
	easeInQuart: function (x, t, b, c, d) {
		return c*(t/=d)*t*t*t + b;
	},
	easeOutQuart: function (x, t, b, c, d) {
		return -c * ((t=t/d-1)*t*t*t - 1) + b;
	},
	easeInOutQuart: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
		return -c/2 * ((t-=2)*t*t*t - 2) + b;
	},
	easeInQuint: function (x, t, b, c, d) {
		return c*(t/=d)*t*t*t*t + b;
	},
	easeOutQuint: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t*t*t + 1) + b;
	},
	easeInOutQuint: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
		return c/2*((t-=2)*t*t*t*t + 2) + b;
	},
	easeInSine: function (x, t, b, c, d) {
		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
	},
	easeOutSine: function (x, t, b, c, d) {
		return c * Math.sin(t/d * (Math.PI/2)) + b;
	},
	easeInOutSine: function (x, t, b, c, d) {
		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
	},
	easeInExpo: function (x, t, b, c, d) {
		return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
	},
	easeOutExpo: function (x, t, b, c, d) {
		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
	},
	easeInOutExpo: function (x, t, b, c, d) {
		if (t==0) return b;
		if (t==d) return b+c;
		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
	},
	easeInCirc: function (x, t, b, c, d) {
		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
	},
	easeOutCirc: function (x, t, b, c, d) {
		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
	},
	easeInOutCirc: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
	},
	easeInElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
	},
	easeOutElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
	},
	easeInOutElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
	},
	easeInBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*(t/=d)*t*((s+1)*t - s) + b;
	},
	easeOutBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
	},
	easeInOutBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158; 
		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
	},
	easeInBounce: function (x, t, b, c, d) {
		return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
	},
	easeOutBounce: function (x, t, b, c, d) {
		if ((t/=d) < (1/2.75)) {
			return c*(7.5625*t*t) + b;
		} else if (t < (2/2.75)) {
			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
		} else if (t < (2.5/2.75)) {
			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
		} else {
			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
		}
	},
	easeInOutBounce: function (x, t, b, c, d) {
		if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
		return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
	}
});

/*
 *
 * TERMS OF USE - EASING EQUATIONS
 * 
 * Open source under the BSD License. 
 * 
 * Copyright © 2001 Robert Penner
 * 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 the author nor the names of 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. 
 *
 */

// place any jQuery/helper plugins in here, instead of separate, slower script files.

/**
Copyright (c) 2011 Geoff Green (http://labs.kojo.com.au/author/geoff/)

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.

Version 1.0
*/
(function($) { 
    $.fn.mtouch = function(options) {

        var INPUT_TYPE = {
            MOUSE: 1,
            TOUCH: 2
        };

        /**
            var e = {
                start: {
                    x: 0,
                    y: 0,
                    time: 0
                },
                end: {
                    x: 0,
                    y: 0,
                    time: 0
                },
                delta: {
                    x: 0,
                    y: 0,
                    xy: 0,
                    time: 0,
                    velocity: 0
                },
                direction: {
                    radians: 0,
                    degrees: 0,
                    cardinal: 'n',
                    basic: {
                        horizontal: 'left' | 'right' | 'none',
                        vertical: 'up' | 'down' | 'none',
                        major: 'left' | 'right' | 'up' | 'down'
                    }
                }
            };

            var f = {
                startFrame: 0,
                startTime: 0,
                currentFrame: 0,
                roundedCurrentFrame: 0,
                currentFrameRate: 0,
                initialVelocity: 0,
                currentVelocity: 0,
                frameIntervalHandler: null,
                animationIntervalHandler: null
            };
         */
        var settings = {
            animate: function(e, f) { },
            wipe: function(e) { },
            wipeLeft: function(e) { },
            wipeRight: function(e) { },
            wipeUp: function(e) { },
            wipeDown: function(e) { },
            wipeEnd: function(e) { },
            dragged: function (e) { },
            draggedUp: function (e) { },
            draggedDown: function (e) { },
            draggedLeft: function(e) { },
            draggedRight: function(e) { },
            grabbed: function(x, y) { },
            
            /**
             * Minimum/Maximum the cursor/touch needs to have moved in order
             * to fire an event
             */
            minimumMoveX: 0,
            minimumMoveY: 0,
            
            /**
             * Every other touch input plugin had this. All the cool kids were
             * doing it :(
             * 
             * No, but seriously this will call preventDefault() with the mouse
             * move/touch inputs
             */
            preventDefaultEvents: true,
            
            /**
             * cardinalSnap string
             * 'all': snap to any of the 16 points of a compass
             * 'ordinal': snap to any of the cardinal (N,E,S,W) and ordinal (NW, SW, etc.)
             * 'cardinal': snap to any of the cardinal points (N,E,S,W)
             */
            cardinalSnap: 'all',
            /**
             * maxGestureTimeout int (ms)
             * How many milliseconds the start and end of a gesture must be in
             * order to qualify for a swipe check
             */
            maxGestureTimeout: 100,
            /**
             * internalTrackingTick int (ms)
             * How often the internal tracking tick should fire. Higher ms for better
             * performance, but degraded tracking.. lower ms for more precision but
             * degraded performance.
             */
            internalTrackingTick: 20,
            
            /**
             * @todo keep documenting..
             */
            
            /**
             * wipeMinimumFrame int
             * The lowest frame to start from. Usually 1 or 0, but can be any
             * other int depending on what you're animating.
             */
            wipeMinimumFrame: 1,
            
            /**
             * wipeMaximumFrame int
             * The maximum frame to return during the animation. The number of
             * frames in your animation.
             */
            wipeMaximumFrame: 124,
            
            /**
             * wipeFrameLooparound boolean
             * If after hitting the maximum or minimum, should it look back
             * around so the the animation start/end feels connected. 
             * 
             * If true and on frame wipeMinimumFrame, then going back a frame
             * will set the current frame to wipeMaximumFrame. If true and on
             * frame wipeMaximumFrame, then going forward a frame will set the
             * current frame to wipeMinimumFrame
             */
            wipeFrameLooparound: true,
            
            /**
             * wipeDecayConstant float
             * How rate at which the animation should slow down after a wipe
             */
            wipeDecayConstant: 0.005,
            /**
             * The minimum velocity before canceling the animation. If set very
             * low then the animation could still be going through all entire
             * process, but not visibly moving
             */
            wipeCancelSpeed: 0.05,
            
            /**
             * The number of frames to animate at.
             */
            wipeFps: 60,
            
            containerWidth: this.width(),
            containerHeight: this.height(),
            
            /**
             * containerAnchor string
             * 'none': Animation will be stepped on all axis of movement
             * 'horizontal': Animation will be stepped on left/right movement
             * 'vertical': Animation will be stepped on up/down movement
             */
            containerAnchor: 'horizontal'
            
        };

        if (options) $.extend(settings, options);

        this.each(function() {

            var intent = {
                start: {
                    x: 0,
                    y: 0,
                    time: new Date().getTime()
                },
                current: {
                    x: 0,
                    y: 0
                },
                isMoving: false,
                isGrabbed: false
            };

            var swipeAnimation = {
                startFrame: 0,
                startTime: 0,
                currentFrame: 0,
                roundedCurrentFrame: 0,
                currentFrameRate: 0,
                initialVelocity: 0,
                currentVelocity: 0,
                frameIntervalHandler: null,
                animationIntervalHandler: null
            };

            var trackingIntervalHandler = null;
            var trackingIntervals = new Array();
            
            var inputType = INPUT_TYPE.TOUCH;

            function formalizeDirections(e) {
                
                e.direction = { };
                
                // Radians and rotate right
                e.direction.radians = Math.atan2(e.delta.x, e.delta.y) + (Math.PI / 2);
                if (e.direction.radians < 0) {
                    e.direction.radians += 2 * Math.PI;
                }

                e.direction.degrees = e.direction.radians * (180 / Math.PI);
                
                var snappedDegree = 0;
                
                // var degreeRemainder = 0;
                if (settings.cardinalSnap == 'all') {
                    // degreeRemainder = e.direction.degrees % (360 / 16);
                    snappedDegree = Math.round((e.direction.degrees) / 22.5 ) * 22.5;
                }
                else if (settings.cardinalSnap == 'ordinal') {
                    // degreeRemainder = e.direction.degrees % (360 / 8);
                    snappedDegree = Math.round((e.direction.degrees) / 45 ) * 45;
                }
                else {
                    snappedDegree = Math.round((e.direction.degrees) / 90 ) * 90;
                }
                
                switch(snappedDegree) {
                    case 0:e.direction.cardinal = 'e';break;
                    case 22.5:e.direction.cardinal = 'ene';break;
                    case 45:e.direction.cardinal = 'ne';break;
                    case 67.5:e.direction.cardinal = 'nne';break;
                    case 90:e.direction.cardinal = 'n';break;
                    case 112.5:e.direction.cardinal = 'nnw';break;
                    case 135:e.direction.cardinal = 'nw';break;
                    case 157.5:e.direction.cardinal = 'wnw';break;
                    case 180:e.direction.cardinal = 'w';break;
                    case 202.5:e.direction.cardinal = 'wsw';break;
                    case 225:e.direction.cardinal = 'sw';break;
                    case 247.5:e.direction.cardinal = 'ssw';break;
                    case 270:e.direction.cardinal = 's';break;
                    case 292.5:e.direction.cardinal = 'sse';break;
                    case 315:e.direction.cardinal = 'se';break;
                    case 337.5:e.direction.cardinal = 'ese';break;
                    case 360:e.direction.cardinal = 'e';break; 
                }

                e.direction.basic = {};
                e.direction.basic.horizontal = '';
                e.direction.basic.vertical = '';
                e.direction.basic.major = '';
                
                if (e.direction.degrees < 180) {
                    e.direction.basic.vertical = 'up';
                }
                else if (e.direction.degrees > 180) {
                    e.direction.basic.vertical = 'down';
                }
                else {
                    e.direction.basic.vertical = 'none';
                }

                if (e.direction.degrees > 90 && e.direction.degrees < 270) {
                    e.direction.basic.horizontal = 'left';
                }
                else if (e.direction.degrees < 90 && e.direction.degrees > 270) {
                    e.direction.basic.horizontal = 'right';
                }
                else {
                    e.direction.basic.horizontal = 'none';
                }

                if (e.direction.degrees >= 45 && e.direction.degrees < 135) {
                    e.direction.basic.major = 'up';
                }
                else if (e.direction.degrees >= 135 && e.direction.degrees < 225) {
                    e.direction.basic.major = 'left';
                }
                else if (e.direction.degrees >= 225 && e.direction.degrees < 315) {
                    e.direction.basic.major = 'down';
                }
                else {
                    e.direction.basic.major = 'right';
                }

                return e;
            }
            
            function cancelIntent() {
									
                this.removeEventListener('touchmove', onTouchMove);
                this.removeEventListener('mousemove', onMouseMove);
                // startX = null;
                intent.isMoving = false;
                intent.isGrabbed = false;

                if (trackingIntervalHandler != null) {
                    clearTimeout(trackingIntervalHandler);
                    trackingIntervalHandler = null;
                }
                
                trackingIntervals = new Array();
            }

            function cancelWipeAnimation() {
				
                if (swipeAnimation.frameIntervalHandler != null) {
                    clearTimeout(swipeAnimation.frameIntervalHandler);
                    swipeAnimation.frameIntervalHandler = null;
                }
                
                if (swipeAnimation.animationIntervalHandler != null) {
                    clearTimeout(swipeAnimation.animationIntervalHandler);
                    swipeAnimation.animationIntervalHandler = null;
                }
            }

            function beginWipeAnimation(e) {
                var lr = e.direction.basic.major == 'left'  ? -1 : 1;

                swipeAnimation.startTime = new Date().getTime();
                swipeAnimation.initialVelocity = e.delta.velocity;

                cancelWipeAnimation();

                swipeAnimation.frameIntervalHandler = setInterval(function() {
                    swipeAnimation.currentVelocity = swipeAnimation.initialVelocity * Math.exp((-1 * settings.wipeDecayConstant * (new Date().getTime() - swipeAnimation.startTime)) );

                    if (swipeAnimation.currentVelocity <= settings.wipeCancelSpeed) {
                        cancelWipeAnimation();
                    }
                    
                    // Frame skip?
                    swipeAnimation.currentFrameRate = Math.round( lr * settings.wipeMaximumFrame * swipeAnimation.currentVelocity );
                }, 10);
                
                // 67 = 15fps
                // 17 = 60fps
                swipeAnimation.animationIntervalHandler = setInterval(function() {
                    
                    if (settings.wipeFrameLooparound == true) {
                        swipeAnimation.currentFrame = (swipeAnimation.currentFrame + (swipeAnimation.currentFrameRate / (1000 / settings.wipeFps))) % settings.wipeMaximumFrame;
                        
                        if (swipeAnimation.currentFrame <= settings.wipeMinimumFrame) {
                            swipeAnimation.currentFrame = settings.wipeMaximumFrame;
                        }
                    }
                    else {
                        swipeAnimation.currentFrame = (swipeAnimation.currentFrame + (swipeAnimation.currentFrameRate / (1000 / settings.wipeFps)));
                    }
                    
                    swipeAnimation.roundedCurrentFrame = Math.round(swipeAnimation.currentFrame);

                    if (settings.wipeFrameLooparound == true && swipeAnimation.roundedCurrentFrame == 0) {
                        if (lr == -1) {
                            swipeAnimation.roundedCurrentFrame = settings.wipeMaximumFrame;
                        }
                        else {
                            swipeAnimation.roundedCurrentFrame = settings.wipeMinimumFrame;
                        }
                    }

                    settings.animate(e, swipeAnimation);
                }, (1000 / settings.wipeFps));
            }

            function fireWipeEvent(e) {
						
                cancelIntent();
                
                e = formalizeDirections(e);
                
                settings.wipe(e);
                
                if (e.direction.basic.major == 'up') {
                    settings.wipeUp(e);
                }
                else if (e.direction.basic.major == 'left') {
                    settings.wipeLeft(e);
                }
                else if (e.direction.basic.major == 'down') {
                    settings.wipeDown(e);
                }
                else {
                    settings.wipeRight(e);
                }
                
                beginWipeAnimation(e);
            }
         
            /**
             * Checks if the latest action is a swipe
             * 
             */
            function isSwipeIntent() {

                onInternalTick();

                if (trackingIntervals.length > 0) {
                    var start = trackingIntervals[trackingIntervals.length - Math.min(5, trackingIntervals.length)];
                    var end = trackingIntervals[trackingIntervals.length - 1];

                    var delta = {
                        x: start.x - end.x,
                        y: start.y - end.y,
                        xy: Math.sqrt(Math.pow(start.x - end.x,2) + Math.pow(start.y - end.y,2)),
                        time: end.time - start.time
                    };

                    delta.velocity = delta.time == 0 ? 0 : delta.xy / delta.time;

                    if(delta.velocity > 0 && (Math.abs(delta.x) >= settings.minimumMoveX || Math.abs(delta.y) >= settings.minimumMoveY)) {
                        fireWipeEvent({
                            start: start,
                            end: end,
                            delta: delta
                        });
                    }
                }
            }
            
            function beginDragAnimation(e) {

                var lr = 0;
                var dFrame = 0;
                
                if (settings.containerAnchor == 'horizontal') {
                    lr = e.direction.basic.horizontal == 'left' ? -1 : 1;
                    
                    dFrame = (e.delta.x / settings.containerWidth * settings.wipeMaximumFrame);
                }
                else if (settings.containerAnchor == 'vertical') {
                    lr = e.direction.basic.vertical == 'up' ? -1 : 1;
                    
                    dFrame = (e.delta.y / settings.containerHeight * settings.wipeMaximumFrame);
                }
                else { // == 'none'
                    lr = (e.direction.basic.major == 'up' || e.direction.basic.major == 'left') ? -1 : 1;
                    
                    dFrame = Math.sqrt(Math.pow(e.delta.x,2) + Math.pow(e.delta.y,2)) * settings.wipeMaximumFrame;
                }
                
                cancelWipeAnimation();

                if (lr > 0) {
                    // Right
                    if (settings.wipeFrameLooparound == true) {
                        swipeAnimation.currentFrame = (swipeAnimation.startFrame - dFrame) % settings.wipeMaximumFrame;
                    }
                    else {
                        swipeAnimation.currentFrame = (swipeAnimation.startFrame - dFrame);
                    }
                }
                else {
                    if (settings.wipeFrameLooparound == true) {
                        swipeAnimation.currentFrame = (swipeAnimation.startFrame - dFrame) % settings.wipeMaximumFrame;

                        if (swipeAnimation.currentFrame <= 0) {
                            swipeAnimation.currentFrame = settings.wipeMaximumFrame + swipeAnimation.currentFrame;
                        }
                    }
                    else {
                        swipeAnimation.currentFrame = (swipeAnimation.startFrame - dFrame);
                    }
                }

                swipeAnimation.roundedCurrentFrame = Math.round(swipeAnimation.currentFrame);

                if (settings.wipeFrameLooparound == true && swipeAnimation.roundedCurrentFrame == 0) {
                    if (lr == -1) {
                        swipeAnimation.roundedCurrentFrame = settings.wipeMaximumFrame;
                    }
                    else {
                        swipeAnimation.roundedCurrentFrame = settings.wipeMinimumFrame;
                    }
                }

                settings.animate(e, swipeAnimation);
            }

            function fireDragEvent(e) {
                e = formalizeDirections(e);
                
                settings.dragged(e);

                if (e.delta.x > 0) {
                    settings.draggedLeft(e);
                }
                else {
                    settings.draggedRight(e);
                }
                
                if (e.delta.y > 0) {
                    settings.draggedDown(e);
                }
                else {
                    settings.draggedUp(e);
                }
                
                beginDragAnimation(e);
            }

            function onMove(e, pageX, pageY) {
                if(settings.preventDefaultEvents) {
                    e.preventDefault();
                }
                
                intent.current.x = pageX;
                intent.current.y = pageY;

                var delta = {
                    x: intent.start.x - pageX,
                    y: intent.start.y - pageY,
                    xy: Math.sqrt(Math.pow(intent.start.x - pageX,2) + Math.pow(intent.start.y - pageY,2)),
                    time: (new Date()).getTime() - intent.start.time
                };

                if (inputType == INPUT_TYPE.TOUCH) {
                    fireDragEvent({
                        start: intent.start,
                        end: {
                            x: pageX,
                            y: pageY,
                            time: new Date().getTime()
                        },
                        delta: delta
                    });
                }
                else {

                    if(intent.isMoving == true && intent.isGrabbed == false) {
                        // onInternalTick();

                        isSwipeIntent();
                    }
                    else if (intent.isGrabbed == true) {
                        
                        fireDragEvent({
                            start: intent.start,
                            end: {
                                x: pageX,
                                y: pageY,
                                time: new Date().getTime()
                            },
                            delta: delta
                        });
                    }
                }
            }

            function onTouchMove(e) {
                onMove(e, e.touches[0].pageX, e.touches[0].pageY);
            }
            
            function onMouseMove(e) {
                onMove(e, e.pageX, e.pageY);
            }
    	 
            function onGrabbed(pageX, pageY) {
                // Stop all animation
                cancelWipeAnimation();
                swipeAnimation.startFrame = swipeAnimation.currentFrame;
                
                // Reset on grab if the event returns true.
                if (settings.grabbed(pageX, pageY) == true) {
                    swipeAnimation = {
                        startFrame: 0,
                        startTime: 0,
                        currentFrame: 0,
                        roundedCurrentFrame: 0,
                        currentFrameRate: 0,
                        initialVelocity: 0,
                        currentVelocity: 0,
                        frameIntervalHandler: null,
                        animationIntervalHandler: null
                    };
                }
            }
         
            /**
             * Fired whenever a mouse down or touchstart is fired for any common
             * functionality.
             */
            function onIntentBegin(pageX, pageY) {
                cancelIntent();
                
                onGrabbed(pageX, pageY);

                intent.start.x = pageX;
                intent.start.y = pageY

                intent.current.x = pageX;
                intent.current.y = pageY;

                intent.isMoving = true;
                intent.isGrabbed = true;

                trackingIntervals = new Array();
                onInternalTick();
                trackingIntervalHandler = setInterval(onInternalTick, settings.internalTrackingTick);
            }
         
            /**
             * Fired once per settings.internalTrackingTick (default: 20 ms)
             * whenever the user has the mouse/touch down
             */
            function onInternalTick() {
                trackingIntervals.push({
                    x: intent.current.x,
                    y: intent.current.y,
                    time: new Date().getTime()
                });

                // purge anything older than the maximum gesture timeout
                if (trackingIntervals.length > parseInt(settings.maxGestureTimeout / settings.internalTrackingTick)) {
                    trackingIntervals = trackingIntervals.slice(trackingIntervals.length - Math.min(parseInt(settings.maxGestureTimeout / settings.internalTrackingTick), trackingIntervals.length), trackingIntervals.length - 1);
                }
            }
						var start = 0;
            function onTouchStart(e) {
								start = e.touches[0].pageX;
                if (e.touches.length == 1) {
                    if(settings.preventDefaultEvents) {
                        e.preventDefault();
                    }
                    
                    this.addEventListener('touchmove', onTouchMove, false);
                    
                    onIntentBegin(e.touches[0].pageX, e.touches[0].pageY);
                }
            }    

            function onMouseDown(e) {
				
                if(settings.preventDefaultEvents) {
                    e.preventDefault();
                }
                
                this.addEventListener('mousemove', onMouseMove, false);
                
                onIntentBegin(e.pageX, e.pageY);
            }
            
            function onTouchEnd(e) {
								var t = start - e.changedTouches[0].pageX;
								t = ( t < 0 ) ? t * -1 : t;
								
								if( t < 20 ) {
									var index = $(this).index();
									$('#player-title').html(videos[index][0]);
		$('#player-genere').html(videos[index][1]);
		$('#player-description').html(videos[index][2]);
		$('#player-time').html(videos[index][4]);
		
$('.video-js-box').html(
						'<video controls class="video-js" height="548" width="100%" poster="http://threefeethigh.co.uk/video/' + videos[index][3]+'_large.jpg" src="http://threefeethigh.co.uk/video/' + videos[index][3]+'_video.mp4">'+
			'			</video>');

		// VideoJS.setupAllWhenReady(); 
								}
						var count = $('#player-que li').length,
								queLength = count * 208 + count -1,
								limit = -1 * (queLength - $('#player-que').width() + 100); 
		
			
								if ( $('#player-que ul').css('margin-left').replace('px', '')*1 > 0 ) {
									$('#player-que ul').stop().animate({marginLeft:0}, 200);
								} else if (	 -1 * (queLength - $('#player-que').width()) > $('#player-que ul').css('margin-left').replace('px', 
								'')*1 ) {
									$('#player-que ul').stop().animate({marginLeft: -1 * (queLength - $('#player-que').width())}, 200, 'easeOutSine');
								} 
								
                intent.isGrabbed = false;
                
                intent.current.x = e.changedTouches[0].pageX;
                intent.current.y = e.changedTouches[0].pageY;

                isSwipeIntent();
            }
            
            /**
             * Just let the controller know the user has let go. Anything after
             * this is considered a wipe on the browser
             */
            function onMouseUp(e) {
                intent.isGrabbed = false;
            }

            /**
             * Cancel it, like they were mouse upping, then check if it was wiped
             * or not.
             */
            function onMouseOut(e) {
                intent.isGrabbed = false;
                
                onMove(e, e.pageX, e.pageY);
            }

            if ('ontouchstart' in document.documentElement) {
                isTouchInput = true;
                this.addEventListener('touchstart', onTouchStart, false);
                this.addEventListener('touchend', onTouchEnd, false);
            } 
            else {
                inputType = INPUT_TYPE.MOUSE;
                // isTouchInput = false;
                this.addEventListener('mousedown', onMouseDown, false);
                this.addEventListener('mouseup', onMouseUp, false);
                this.addEventListener('mouseout', onMouseOut, false);
            }
        });
 
        return this;
    };
 
})(jQuery);

