/*
 * touchSwipe - jQuery Plugin
 * http://plugins.jquery.com/project/touchSwipe
 * http://labs.skinkers.com/touchSwipe/
 *
 * Copyright (c) 2010 Matt Bryson (www.skinkers.com)
 * Licensed under the GNU GPL license
 *
 * $Date: 2010-12-01 (Wed, 12 Dec 2010) $
 * $version: 1.0.1
 * 
 * A jQuery plugin to capture left, right, up and down swipes on touch devices.
 * You can capture 2 finger or 1 finger swipes, set the threshold and define either a catch all handler, or individual direction handlers.
 * Options:
 *		debug 		Boolean		Default false. 	If true, the default swipe handler will log to the console when triggered.
 * 		fingers 	int 		Default 1. 	The number of fingers to trigger the swipe, 1 or 2.
 * 		threshold 	int  		Default 75.	The number of pixels that the user must move their finger by before it is considered a swipe.
 * 		swipe 		Funciton 	A catch all handler that is triggered for all swipe directions. Accepts 3 arguments, the original event object, the element that was swiped and the direction of the swipe : "left", "right", "up", "down".
 * 		swipeLeft	Funciton 	A handler that is triggered for "left" swipes. Accepts 2 arguments, the original event object and the element that was swiped.
 * 		swipeRight	Funciton 	A handler that is triggered for "right" swipes. Accepts 2 arguments, the original event object and the element that was swiped.
 * 		swipeUp		Funciton 	A handler that is triggered for "up" swipes. Accepts 2 arguments, the original event object and the element that was swiped.
 * 		swipeDown	Funciton 	A handler that is triggered for "down" swipes. Accepts 2 arguments, the original event object and the element that was swiped.
 *		swipeStatus Function 	A handler triggered for every phase of the swipe.Handler is passed 4 arguments: event : The original event object, phase:The current swipe face, either "start”, "move”, "end” or "cancel”. direction : The swipe direction, either "up”, "down”, "left " or "right”.distance : The distance of the swipe.
 *		triggerOnTouchEnd Boolean Default true If true, the swipe events are triggered when the touch end event is received (user releases finger).  If false, it will be triggered on reaching the threshold, and then cancel the touch event automatically.
 *
 * This jQuery plugin will only run on devices running Mobile Webkit based browsers (iOS 2.0+, android 2.2+)
 */
(function($) 
{
	$.fn.move = function(options) 
	{
		var defaults = {
			x 		: [null,null],
			y 		: [null,null],
			dragStart 		: function(){},
			dragEnd    		: function(){},
			target : null
		};
		
		var options = $.extend(defaults, options);
		
		// Default thresholds & swipe functions
		if (!this) return false;
		
		if (defaults.target == null) defaults.target = this;
		
		var phase="start";
		var mouseIsDown=false;
		
		var PHASE_START="start";
		var PHASE_MOVE="move";
		var PHASE_END="end";
		var PHASE_CANCEL="cancel";
		
		
		var touchCycleComplete=false;
		
		
		
		return this.each(function() 
		{
			var start={x:0, y:0};
			var end={x:0, y:0};
			var distance={x:0,y:0};
			var initial={x:0,y:0};
			//var interval;
			
			function touchStart(event) 
			{
				phase = PHASE_START;
				// disable the standard ability to select the touched object
				
				var fingerCount = (event.touches ? event.touches.length : 1);
				//if (fingerCount < 2) event.preventDefault();
				
				//if (interval) window.clearInterval(interval);
				//interval = window.setInterval(setPositions, 40);
				
				defaults.dragStart();
				// get the total number of fingers touching the screen
				if (!event.touches) mouseIsDown = true;
				
				// check the number of fingers is what we are looking for
				start.x = (event.touches ? event.touches[0].pageX : event.pageX);
				start.y = (event.touches ? event.touches[0].pageY : event.pageY);
				
				initial.x = 0;
				initial.y = 0;
				if (defaults.target.css('top')) initial.y = parseInt(defaults.target.css('top').replace('px', ''));
				if (defaults.target.css('left')) initial.x = parseInt(defaults.target.css('left').replace('px', ''));
			}
			
			function touchMove(event) 
			{
				if (phase == PHASE_END || phase == PHASE_CANCEL)
					return;
					
					
				phase = PHASE_MOVE;
				
				
				
				if ( event.touches || mouseIsDown ) 
				{
					end.x = (event.touches ? event.touches[0].pageX : event.pageX);
					end.y = (event.touches ? event.touches[0].pageY : event.pageY);
					
					distance.x = (initial.x + (end.x - start.x));
					distance.y = (initial.y + (end.y - start.y));
					
					setPositions();
				} 
				else 
				{
					phase = PHASE_CANCEL;
					touchCancel(event);
				}
			}
			
			function touchEnd(event) 
			{
				
				defaults.dragEnd();
				phase = PHASE_END;
				//setPositions();
				//window.clearInterval(interval);
			}
			
			function touchCancel(event) 
			{
				start.x = 0;
				start.y = 0;
				end.x = 0;
				end.y = 0;
				//setPositions();
				//window.clearInterval(interval);
			}
			
			
			function setPositions(){
				if (distance.x > (defaults.x[0])) distance.x = defaults.x[0];
				if (distance.x < (defaults.x[1])) distance.x = defaults.x[1];
				
				if (distance.y > (defaults.y[0])) distance.y = defaults.y[0];
				if (distance.y < (defaults.y[1])) distance.y = defaults.y[1];
				
				if (defaults.x[0] && defaults.x[1]) defaults.target.css('left', distance.x);
				if (defaults.y[0] && defaults.y[1]) defaults.target.css('top', distance.y);
			}
			
			
			try{
				// Add gestures to all swipable areas
				this.addEventListener("touchstart", touchStart, false);
				this.addEventListener("touchmove", touchMove, false);
				this.addEventListener("touchend", touchEnd, false);
				this.addEventListener("touchcancel", touchCancel, false);
				
				this.addEventListener("mousedown", touchStart, false);
				this.addEventListener("mousemove", touchMove, false);
				this.addEventListener("mouseup", touchEnd, false);
			} catch(e){
				// Add gestures to all swipable areas
				$(this).bind("touchstart", touchStart);
				$(this).bind("touchmove", touchMove);
				$(this).bind("touchend", touchEnd);
				$(this).bind("touchcancel", touchCancel);
				
				$(this).bind("mousedown", touchStart);
				$(this).bind("mousemove", touchMove);
				$(this).bind("mouseup", touchEnd);
			}
				
		});
	};
})(jQuery);
