content: package com.agilie.gesturedetectors;
  
  import android.content.Context;
  import android.view.MotionEvent;
  
  /**
   * @author Almer Thie (code.almeros.com)
   * Copyright (c) 2013, Almer Thie (code.almeros.com)
   *
   * 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.
   *
   * 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 HOLDER 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.
   */
  public abstract class BaseGestureDetector {
      protected final Context mContext;
      protected boolean mGestureInProgress;
  
      protected MotionEvent mPrevEvent;
      protected MotionEvent mCurrEvent;
      
      protected float mCurrPressure;
      protected float mPrevPressure;
      protected long mTimeDelta;
      
      
  	/**
  	 * This value is the threshold ratio between the previous combined pressure
  	 * and the current combined pressure. When pressure decreases rapidly
  	 * between events the position values can often be imprecise, as it usually
  	 * indicates that the user is in the process of lifting a pointer off of the
  	 * device. This value was tuned experimentally.
  	 */
      protected static final float PRESSURE_THRESHOLD = 0.67f;
  
      
      public BaseGestureDetector(Context context) {
      	mContext = context; 	
      }
      
  	/**
  	 * All gesture detectors need to be called through this method to be able to
  	 * detect gestures. This method delegates work to handler methods
  	 * (handleStartProgressEvent, handleInProgressEvent) implemented in
  	 * extending classes.
  	 * 
  	 * @param event
  	 * @return
  	 */
      public boolean onTouchEvent(MotionEvent event){
      	final int actionCode = event.getAction() & MotionEvent.ACTION_MASK;
      	if (!mGestureInProgress) {
      		handleStartProgressEvent(actionCode, event);
      	} else {
      		handleInProgressEvent(actionCode, event);
      	}
      	return true;
      }
      
      /**
  	 * Called when the current event occurred when NO gesture is in progress
  	 * yet. The handling in this implementation may set the gesture in progress
  	 * (via mGestureInProgress) or out of progress
  	 * @param actionCode
  	 * @param event
  	 */
      protected abstract void handleStartProgressEvent(int actionCode, MotionEvent event);
      
  	/**
  	 * Called when the current event occurred when a gesture IS in progress. The
  	 * handling in this implementation may set the gesture out of progress (via
  	 * mGestureInProgress).
  	 * @param actionCode
  	 * @param event
  	 */
      protected abstract void handleInProgressEvent(int actionCode, MotionEvent event);
      
      
      protected void updateStateByEvent(MotionEvent curr){
      	final MotionEvent prev = mPrevEvent;
      	
      	// Reset mCurrEvent
          if (mCurrEvent != null) {
              mCurrEvent.recycle();
              mCurrEvent = null;
          }
          mCurrEvent = MotionEvent.obtain(curr);
          
          
          // Delta time
          mTimeDelta = curr.getEventTime() - prev.getEventTime();
  
          // Pressure
          mCurrPressure = curr.getPressure(curr.getActionIndex());
          mPrevPressure = prev.getPressure(prev.getActionIndex());
      }
      
      protected void resetState() {
          if (mPrevEvent != null) {
              mPrevEvent.recycle();
              mPrevEvent = null;
          }
          if (mCurrEvent != null) {
              mCurrEvent.recycle();
              mCurrEvent = null;
          }
          mGestureInProgress = false;
      }
  
  
      /**
       * Returns {@code true} if a gesture is currently in progress.
       * @return {@code true} if a gesture is currently in progress, {@code false} otherwise.
       */
      public boolean isInProgress() {
          return mGestureInProgress;
      }
  
  	/**
  	 * Return the time difference in milliseconds between the previous accepted
  	 * GestureDetector event and the current GestureDetector event.
  	 * 
  	 * @return Time difference since the last move event in milliseconds.
  	 */
  	public long getTimeDelta() {
  		return mTimeDelta;
  	}
  
  	/**
  	 * Return the event time of the current GestureDetector event being
  	 * processed.
  	 * 
  	 * @return Current GestureDetector event time in milliseconds.
  	 */
  	public long getEventTime() {
  		return mCurrEvent.getEventTime();
  	}
     
  }
  