(function( $ ){
	$.fn.handleSwipe = function(options, callback) {

		var fingerCount = 0;
		var startX = -1;
		var startY = -1;
		var curX = 0;
		var curY = 0;
		var deltaX = 0;
		var deltaY = 0;
		var horzDiff = 0;
		var vertDiff = 0;
		var minLength = options.minLength ? options.minLength : 75; // the shortest distance the user may swipe
		var swipeLength = 0;
		var swipeAngle = null;
		var swipeDirection = null;

		var methods = {
			touchStart: function (event) {
				fingerCount = event.touches.length;
				if ( fingerCount == 1 ) {
					startX = event.touches[0].pageX;
					startY = event.touches[0].pageY;
				} else {
					methods.touchCancel(event);
				}
			},

			touchMove: function (event) {
				if ( event.touches.length == 1 && startX != -1) {
					//event.preventDefault();
					curX = event.touches[0].pageX;
					curY = event.touches[0].pageY;
					methods.caluculateAngle();
					if (((swipeAngle <= 45) && (swipeAngle >= 0)) || ((swipeAngle <= 360) && (swipeAngle >= 315)) || ((swipeAngle >= 135) && (swipeAngle <= 225))) {
						event.preventDefault();
					}
				} else {
					methods.touchCancel(event);
				}
			},

			touchEnd: function (event) {
				// check to see if more than one finger was used and that there is an ending coordinate
				if ( fingerCount == 1 && curX != 0 ) {
					event.preventDefault();
					// use the Distance Formula to determine the length of the swipe
					swipeLength = Math.round(Math.sqrt(Math.pow(curX - startX,2) + Math.pow(curY - startY,2)));
					// if the user swiped more than the minimum length, perform the appropriate action
					if ( swipeLength >= minLength ) {
						methods.caluculateAngle();
						methods.determineSwipeDirection();
						methods.processingRoutine(swipeDirection);
						methods.touchCancel(event); // reset the variables
					} else {
						methods.touchCancel(event);
					}	
				} else {
					methods.touchCancel(event);
				}
			},

			touchCancel: function (event) {
				// reset the variables back to default values
				fingerCount = 0;
				startX = -1;
				startY = -1;
				curX = 0;
				curY = 0;
				deltaX = 0;
				deltaY = 0;
				horzDiff = 0;
				vertDiff = 0;
				swipeLength = 0;
				swipeAngle = null;
				swipeDirection = null;
			},

			caluculateAngle: function () {
				var X = startX-curX;
				var Y = curY-startY;
				var Z = Math.round(Math.sqrt(Math.pow(X,2)+Math.pow(Y,2))); //the distance - rounded - in pixels
				var r = Math.atan2(Y,X); //angle in radians (Cartesian system)
				swipeAngle = Math.round(r*180/Math.PI); //angle in degrees
				if ( swipeAngle < 0 ) { swipeAngle =  360 - Math.abs(swipeAngle); }
			},

			determineSwipeDirection: function () {
				if ( (swipeAngle <= 45) && (swipeAngle >= 0) ) {
					swipeDirection = 'left';
				} else if ( (swipeAngle <= 360) && (swipeAngle >= 315) ) {
					swipeDirection = 'left';
				} else if ( (swipeAngle >= 135) && (swipeAngle <= 225) ) {
					swipeDirection = 'right';
				} else if ( (swipeAngle > 45) && (swipeAngle < 135) ) {
					swipeDirection = 'down';
				} else {
					swipeDirection = 'up';
				}
			},

			processingRoutine: callback ? callback : function (swipeDirection) {
				//alert("you moved your finger " + swipeDirection + ".");
			},

			detectSwipeSupport: function() {
				if ('ontouchstart' in document.documentElement) {
					return true;
				} else {
					return false;
				}
			}
		};

		if(methods.detectSwipeSupport()) {
			this.each(function() {
				this.addEventListener("touchstart", methods.touchStart,false);
				this.addEventListener("touchend", methods.touchEnd,false);
				this.addEventListener("touchmove", methods.touchMove,false);
				this.addEventListener("touchcancel", methods.touchCancel,false);
			});
		}
	};
})( jQuery );