package jp.agentec.abook.abv.ui.common.detector;

import jp.agentec.abook.abv.cl.util.PreferenceUtil;
import jp.agentec.abook.abv.ui.common.appinfo.AppDefType;
import android.content.Context;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ViewConfiguration;

public abstract class MultiTapDetector {
	private final int POINTS;
	private final int TAPS;
	private final int TIMEOUT;
	private long preDownTime = 0;
	private boolean separateTouches = false;
	private byte tapCount = 0;
	private GestureDetector mGestureDetector;
	private Context mContext;

	public MultiTapDetector(final Context context, int points, int taps) {
		this.POINTS = points;
		this.TAPS = taps;
		this.TIMEOUT = (ViewConfiguration.getDoubleTapTimeout() + 100) * taps;
		this.mContext = context;

		mGestureDetector = new GestureDetector(context, new GestureDetector.OnGestureListener() {
			@Override
			public boolean onSingleTapUp(MotionEvent e) {
				MultiTapDetector.this.onSingleTapUp();
				return true;
			}

			@Override
			public void onShowPress(MotionEvent e) {
			}

			@Override
			public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
				return false;
			}

			@Override
			public void onLongPress(MotionEvent e) {
			}

			@Override
			public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
				return false;
			}

			@Override
			public boolean onDown(MotionEvent e) {
				return false;
			}
		});
	}

	private void reset(long time) {
		preDownTime = time;
		separateTouches = false;
		tapCount = 0;
	}

	public boolean onTouchEvent(MotionEvent event) {
		switch (event.getActionMasked()) {
		case MotionEvent.ACTION_DOWN:
			if (preDownTime == 0 || event.getEventTime() - preDownTime > TIMEOUT) {
				reset(event.getDownTime());
			}
			break;
		case MotionEvent.ACTION_POINTER_UP:
			if (event.getPointerCount() == POINTS) {
				tapCount++;
				//ダブルタップが最大4回以上の場合、falseで返す
				if (tapCount > 4) {
					return false;
				}
			} else {
				preDownTime = 0;
			}
			break;
		case MotionEvent.ACTION_UP:
			if (!separateTouches) {
				separateTouches = true;
			} else if (tapCount == TAPS && event.getEventTime() - preDownTime < TIMEOUT && PreferenceUtil.getUserPref(mContext, AppDefType.UserPrefKey.MONITOR_TOUCH_MODE,0)==0) {
				onMultiTap();
				preDownTime = 0;
				return true;
			}
		}
        return mGestureDetector.onTouchEvent(event);
    }

	public abstract void onMultiTap();
	public abstract void onSingleTapUp();
}
