package com.itant.behaviordemo;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.design.widget.AppBarLayout;
import android.support.design.widget.CoordinatorLayout;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.NestedScrollView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

public class AppBarLayoutOverScrollViewBehavior extends AppBarLayout.Behavior {
    private static final String TAG = "overScroll";
    private static final String TAG_BOTTOM = "bottomList";
    // 最多可以拉伸多长
    private static final float MAX_EXTRA_HEIGHT = 300;
    // 回弹动画时长200ms
    private static final long ANIMATION_DURATION = 350;
    private View imageView;
    private boolean isAnimate;

    private float mTotalDy;
    private boolean isRecovering = false;//是否正在自动回弹中


    // 我的
    private int rawAppbarBottom = 0;
    private int currentAppbarBottom = 0;
    private int rawImageHeight = 0;
    private int currentImageHeight = 0;
    private int rawAppbarHeight = 0;
    private int currentAppbarHeight = 0;
    // 用来标记当前的滑动是不是fling
    private boolean isFling;

    private AppBarLayout appBarLayout;
    //private NestedScrollView nestedScrollView;

    public AppBarLayoutOverScrollViewBehavior() {
    }

    public AppBarLayoutOverScrollViewBehavior(Context context, AttributeSet attrs) {
        super(context, attrs);
    }


    @Override
    public boolean onLayoutChild(final CoordinatorLayout parent, final AppBarLayout abl, int layoutDirection) {
        //Log.e(TAG, "onLayoutChild");
        boolean handled = super.onLayoutChild(parent, abl, layoutDirection);
        // 需要在调用过super.onLayoutChild()方法之后获取
        if (imageView == null) {
            imageView = parent.findViewWithTag(TAG);
            //nestedScrollView = parent.findViewWithTag(TAG_BOTTOM);
            if (imageView != null) {
                initial(abl);
            }
        }
        return handled;
    }

    @Override
    public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, float velocityX, float velocityY) {
        Log.e(TAG, "onNestedPreFling" + velocityY);

        //当y速度>100,就秒弹回
        /*if (velocityY > 100) {
            isAnimate = false;
        }*/
        return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY);
    }

    boolean shouldFling = false;
    float flingVelocityY = 0;

    @Override
    public boolean onNestedFling(@NonNull CoordinatorLayout coordinatorLayout, @NonNull AppBarLayout child, @NonNull View target, float velocityX, float velocityY, boolean consumed) {
        Log.e(TAG, "onNestedFling: " + velocityY);
        isFling = true;

        flingVelocityY = velocityY;
        return super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed);
    }

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes, int type) {
        Log.e(TAG, "start>>>>>>>>>>" + flingVelocityY);
        if (flingVelocityY < -1000) {
            flingVelocityY = 0;
            child.setExpanded(true, true);
            // 防止fling太用力，一直在最大滑动距离那里停留。
            return false;
        }

        /*if (flingVelocityY > 0 && flingVelocityY < 1000) {
            // 防止小fling导致底部的NestScrollView在AppBarLayout展开的时候就上滑了。
            return false;
        }*/

        // 不能简单地由于是fling就忽略，如果是从折叠状态fling下来的，还是要让其继续下拉的
        doingCycle = true;
        if (isFling && child.getBottom() >= rawAppbarBottom) {
            //Log.e(TAG, "start return false");
            return false;
        }

        isAnimate = true;
        if ((nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0 || target instanceof DisInterceptNestedScrollView)
            return true;
        return super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes, type);
    }

    private boolean doingCycle;

    @Override
    public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed, int type) {
        Log.e(TAG, "scrolling.......... " + dy);

        if (imageView != null && !isRecovering && (dy < 0 && child.getBottom() >= rawAppbarHeight)) {
            if (doingCycle) {
                if (currentImageHeight >= rawImageHeight + MAX_EXTRA_HEIGHT) {
                    if (!isFling) {
                        scale(child, target, dy);
                    } else {
                        onStopNestedScroll(coordinatorLayout, child, target, type);
                    }
                } else {
                    scale(child, target, dy);
                }
            } else {
                currentImageHeight = rawImageHeight;
            }
            return;
        }

        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
    }

    @Override
    public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, AppBarLayout abl, View target, int type) {
        Log.e(TAG, "stop<<<<<<<<");

        // 这个方法在拉动的过程中会被频繁调用，如果不处理的话，会造成抖动现象
        isFling = false;
        doingCycle = false;
        recovery(abl);
        super.onStopNestedScroll(coordinatorLayout, abl, target, type);

        //Log.e(TAG, "onStopNestedScroll: ");
    }

    private void initial(AppBarLayout abl) {
        appBarLayout = abl;

        abl.setClipChildren(false);
        rawAppbarBottom = abl.getBottom();
        currentAppbarBottom = rawAppbarBottom;
        rawImageHeight = imageView.getHeight();
        currentImageHeight = rawImageHeight;
        rawAppbarHeight = abl.getHeight();
        currentAppbarHeight = rawAppbarHeight;
    }

    /**
     * 拉伸图片
     */
    private void scale(AppBarLayout abl, View target, int dy) {
        currentImageHeight += -dy;
        currentImageHeight = (int) Math.min(currentImageHeight, rawImageHeight + MAX_EXTRA_HEIGHT);
        mTotalDy += -dy;
        mTotalDy = Math.min(mTotalDy, MAX_EXTRA_HEIGHT);

        imageView.getLayoutParams().height = currentImageHeight;
        imageView.requestLayout();

        currentAppbarHeight = rawAppbarHeight + currentImageHeight - rawImageHeight;
        abl.setBottom(currentAppbarHeight);
        target.setScrollY(0);

        ////Log.e(TAG, "dy: " + dy);
    }

    /**
     * 恢复原形
     */
    private void recovery(final AppBarLayout abl) {
        if (isRecovering) return;
        if (mTotalDy > 0) {
            isRecovering = true;
            mTotalDy = 0;
            if (isAnimate) {
                ValueAnimator anim = ValueAnimator.ofInt(0, currentImageHeight - rawImageHeight).setDuration(ANIMATION_DURATION);
                anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {

                        int value = (int) animation.getAnimatedValue();
                        ////Log.e(TAG, "value: " + value);

                        imageView.getLayoutParams().height = currentImageHeight - value;
                        imageView.requestLayout();

                        // AppbarLayout逐渐恢复
                        currentAppbarHeight = rawAppbarHeight + currentImageHeight - rawImageHeight - value;
                        appBarLayout.setBottom(currentAppbarHeight);
                        currentAppbarBottom = currentAppbarHeight;
                    }
                });

                anim.addListener(new Animator.AnimatorListener() {
                    @Override
                    public void onAnimationStart(Animator animation) {
                    }

                    @Override
                    public void onAnimationEnd(Animator animation) {
                        isRecovering = false;
                        currentImageHeight = rawImageHeight;
                        currentAppbarHeight = rawAppbarHeight;
                        currentAppbarBottom = rawAppbarBottom;
                    }

                    @Override
                    public void onAnimationCancel(Animator animation) {
                    }

                    @Override
                    public void onAnimationRepeat(Animator animation) {
                    }
                });
                anim.start();
            } else {
                isRecovering = false;
                currentImageHeight = rawImageHeight;
                currentAppbarHeight = rawAppbarHeight;

                //ViewGroup.LayoutParams params = imageView.getLayoutParams();
                imageView.getLayoutParams().height = rawImageHeight;
                imageView.requestLayout();

                abl.setBottom(rawAppbarBottom);
                currentAppbarBottom = rawAppbarBottom;
            }
        }
    }
}