package com.gh.gamecenter.common.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;

import androidx.annotation.Nullable;

import com.gh.gamecenter.common.R;

public class LongPressView extends View {
    private int mLastMotionX, mLastMotionY;
    // 是否移动了
    private boolean isMoved;
    // 是否释放了
    private boolean isReleased;
    // 计数器，防止多次点击导致最后一次形成longpress的时间变短
    private int mCounter;
    // 长按的runnable
    private Runnable mLongPressRunnable;
    // 移动的阈值
    private static final int TOUCH_SLOP = 60;
    private int longPressTimeout = ViewConfiguration.getLongPressTimeout();

    public LongPressView(Context context) {
        super(context);
    }

    public LongPressView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public LongPressView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        if (attrs != null) {
            TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.LongPressViewStyle);
            longPressTimeout = ta.getInteger(R.styleable.LongPressViewStyle_timeout, longPressTimeout);
            ta.recycle();
        }
        mLongPressRunnable = () -> {
            mCounter--;
            if (mCounter > 0 || isReleased || isMoved)
                return;
            performLongClick();// 回调长按事件
        };
    }

    public boolean dispatchTouchEvent(MotionEvent event) {
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mLastMotionX = x;
                mLastMotionY = y;
                mCounter++;
                isReleased = false;
                isMoved = false;
                postDelayed(mLongPressRunnable, longPressTimeout);
                break;
            case MotionEvent.ACTION_MOVE:
                if (isMoved)
                    break;
                if (Math.abs(mLastMotionX - x) > TOUCH_SLOP
                        || Math.abs(mLastMotionY - y) > TOUCH_SLOP) {
                    isMoved = true;
                }
                break;
            case MotionEvent.ACTION_UP:
                isReleased = true;
                break;
        }
        return true;
    }
}
