package com.example.mylib_test.activity.touch.NestedView;

import android.content.Context;
import androidx.core.view.GestureDetectorCompat;
import androidx.core.view.NestedScrollingChild;
import androidx.core.view.NestedScrollingChildHelper;
import androidx.core.view.ViewCompat;
import android.util.AttributeSet;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.widget.LinearLayout;
import android.widget.OverScroller;

public class NestedScrollingChildView extends LinearLayout implements NestedScrollingChild, OnGestureListener {

    private final OverScroller mScroller;
    private GestureDetectorCompat mDetector;

    public NestedScrollingChildView(Context context) {
        this(context, null);
    }

    public NestedScrollingChildView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public NestedScrollingChildView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setOrientation(LinearLayout.VERTICAL);
        mScroller = new OverScroller(context);
        mNestedScrollingChildHelper = new NestedScrollingChildHelper(this);
        mDetector = new GestureDetectorCompat(context, this);
        //todo 1
        setNestedScrollingEnabled(true);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        final boolean handled = mDetector.onTouchEvent(event);
        if (!handled && event.getAction() == MotionEvent.ACTION_UP) {
            //todo 5
            stopNestedScroll();
        }
        return true;
    }

    @Override
    public boolean onDown(MotionEvent e) {
        startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
        return true;
    }


    int[] offsetInWindow=new int[2];

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        int[] consumed = new int[2];
        System.out.println("e1 y:"+e1.getY()+"\t rawY:"+e1.getRawY());
        System.out.println("e2 y:"+e2.getY()+"\t rawY:"+e2.getRawY());
        System.out.println("distanceY:" + distanceY);
        System.out.println("offsetInWindow[1]:"+offsetInWindow[1]);
        int restDistanceY = (int) distanceY-offsetInWindow[1];
        //todo 2
        if (dispatchNestedPreScroll(0, restDistanceY, consumed, offsetInWindow)) {
            //offsetInWindow 如果不加这个参数会出现抖动,
            // 因为父亲消耗后,布局会偏移导致  每次的触摸事件e 其实也跟着偏移了(偏移量是上一次的布局的位移),
            //所以e需要修正
            restDistanceY = restDistanceY-consumed[1];
            System.out.println("consumed:" + consumed[1]);
        }
        if (Math.abs(restDistanceY) > 1){
            scrollBy(0, restDistanceY);
            System.out.println("scrollBy:" + restDistanceY);
        }
//        dispatchNestedScroll(0, 0, 0, 0, null);
        return true;
    }
    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        //todo 3
        if (!dispatchNestedPreFling(velocityX, -velocityY)) {
            //最后一个限制 就是本身的高度了~
            mScroller.fling(0, getScrollY(), 0, -(int) velocityY, 0, 0, 0, getMeasuredHeight());
            invalidate();
        }
        return true;
    }


    @Override
    public void scrollTo(int x, int y) {
        //防止滑动出界; 滑动多了也不怕
        if (y < 0)
            y = 0;
        if (y > getMeasuredHeight())
            y = getMeasuredHeight();
        super.scrollTo(x, y);
    }

    @Override
    public void computeScroll() {
        if (mScroller.computeScrollOffset()) {
            scrollTo(0, mScroller.getCurrY());
            invalidate();
        }
    }
//固定用法

    private final NestedScrollingChildHelper mNestedScrollingChildHelper;

    @Override
    public void setNestedScrollingEnabled(boolean enabled) {
        //确定能不能 嵌套滑动;
        mNestedScrollingChildHelper.setNestedScrollingEnabled(true);
    }

    @Override
    public boolean isNestedScrollingEnabled() {
        //因为上面的方法 helper已经得出结论直接调用下面的方法即可
        return mNestedScrollingChildHelper.isNestedScrollingEnabled();
    }

    @Override
    public boolean startNestedScroll(int axes) {
        //做准备:主要是找到 Nested(嵌套)ScrollingParent
        return mNestedScrollingChildHelper.startNestedScroll(axes);
    }

    @Override
    public void stopNestedScroll() {
        //停止嵌套滑动;
        mNestedScrollingChildHelper.stopNestedScroll();
    }

    @Override
    public boolean hasNestedScrollingParent() {
        //因为 startNestedScroll里面已经得出结论了  直接调用下方法即可;
        return mNestedScrollingChildHelper.hasNestedScrollingParent();
    }

    @Override
    public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) {
        //如果返回true证明 parent消耗了位移 ;
        //主要计算->offsetInWindow,代表 child就是当前 经过此方法后 在屏幕上的差值;
        return mNestedScrollingChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
    }

    @Override
    public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
        //如果返回true证明 parent消耗了位移 ;
        //主要计算->offsetInWindow,代表 child就是当前 经过此方法后 在屏幕上的差值;
        return mNestedScrollingChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
    }

    @Override
    public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
        return mNestedScrollingChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
    }

    @Override
    public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
        return mNestedScrollingChildHelper.dispatchNestedPreFling(velocityX, velocityY);
    }

    @Override
    public void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        mNestedScrollingChildHelper.onDetachedFromWindow();
    }


//另一个接口

    @Override
    public void onLongPress(MotionEvent e) {

    }
    @Override
    public void onShowPress(MotionEvent e) {
    }

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



}