/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.systemui.statusbar.phone;

import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;

import com.android.systemui.R;

/**
 * Detects a double tap.
 */
public class DoubleTapHelper {

    private static final long DOUBLETAP_TIMEOUT_MS = 1200;

    private final View mView;
    private final ActivationListener mActivationListener;
    private final DoubleTapListener mDoubleTapListener;
    private final SlideBackListener mSlideBackListener;
    private final DoubleTapLogListener mDoubleTapLogListener;

    private float mTouchSlop;
    private float mDoubleTapSlop;

    private boolean mActivated;

    private float mDownX;
    private float mDownY;
    private boolean mTrackTouch;

    private float mActivationX;
    private float mActivationY;
    private Runnable mTapTimeoutRunnable = this::makeInactive;

    public DoubleTapHelper(View view, ActivationListener activationListener,
            DoubleTapListener doubleTapListener, SlideBackListener slideBackListener,
            DoubleTapLogListener doubleTapLogListener) {
        mTouchSlop = ViewConfiguration.get(view.getContext()).getScaledTouchSlop();
        mDoubleTapSlop = view.getResources().getDimension(R.dimen.double_tap_slop);
        mView = view;

        mActivationListener = activationListener;
        mDoubleTapListener = doubleTapListener;
        mSlideBackListener = slideBackListener;
        mDoubleTapLogListener = doubleTapLogListener;
    }

    public boolean onTouchEvent(MotionEvent event) {
        return onTouchEvent(event, Integer.MAX_VALUE);
    }

    public boolean onTouchEvent(MotionEvent event, int maxTouchableHeight) {
        int action = event.getActionMasked();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                mDownX = event.getX();
                mDownY = event.getY();
                mTrackTouch = true;
                if (mDownY > maxTouchableHeight) {
                    mTrackTouch = false;
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (!isWithinTouchSlop(event)) {
                    makeInactive();
                    mTrackTouch = false;
                }
                break;
            case MotionEvent.ACTION_UP:
                if (isWithinTouchSlop(event)) {
                    if (mSlideBackListener != null && mSlideBackListener.onSlideBack()) {
                        return true;
                    }
                    if (!mActivated) {
                        makeActive();
                        mView.postDelayed(mTapTimeoutRunnable, DOUBLETAP_TIMEOUT_MS);
                        mActivationX = event.getX();
                        mActivationY = event.getY();
                    } else {
                        boolean withinDoubleTapSlop = isWithinDoubleTapSlop(event);
                        if (mDoubleTapLogListener != null) {
                            mDoubleTapLogListener.onDoubleTapLog(withinDoubleTapSlop,
                                    event.getX() - mActivationX,
                                    event.getY() - mActivationY);
                        }
                        if (withinDoubleTapSlop) {
                            if (!mDoubleTapListener.onDoubleTap()) {
                                return false;
                            }
                        } else {
                            makeInactive();
                            mTrackTouch = false;
                        }
                    }
                } else {
                    makeInactive();
                    mTrackTouch = false;
                }
                break;
            case MotionEvent.ACTION_CANCEL:
                makeInactive();
                mTrackTouch = false;
                break;
            default:
                break;
        }
        return mTrackTouch;
    }

    private void makeActive() {
        if (!mActivated) {
            mActivated = true;
            mActivationListener.onActiveChanged(true);
        }
    }

    private void makeInactive() {
        if (mActivated) {
            mActivated = false;
            mActivationListener.onActiveChanged(false);
        }
    }

    private boolean isWithinTouchSlop(MotionEvent event) {
        return Math.abs(event.getX() - mDownX) < mTouchSlop
                && Math.abs(event.getY() - mDownY) < mTouchSlop;
    }

    public boolean isWithinDoubleTapSlop(MotionEvent event) {
        if (!mActivated) {
            // If we're not activated there's no double tap slop to satisfy.
            return true;
        }

        return Math.abs(event.getX() - mActivationX) < mDoubleTapSlop
                && Math.abs(event.getY() - mActivationY) < mDoubleTapSlop;
    }

    @FunctionalInterface
    public interface ActivationListener {
        void onActiveChanged(boolean active);
    }

    @FunctionalInterface
    public interface DoubleTapListener {
        boolean onDoubleTap();
    }

    @FunctionalInterface
    public interface SlideBackListener {
        boolean onSlideBack();
    }

    @FunctionalInterface
    public interface DoubleTapLogListener {
        void onDoubleTapLog(boolean accepted, float dx, float dy);
    }
}
