/*
 * Copyright (C) 2016 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.calculator2;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Parcelable;
import androidx.core.view.ViewCompat;
import androidx.customview.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;

public class DragLayout extends ViewGroup {

    private static final double AUTO_OPEN_SPEED_LIMIT = 600.0;
    private static final String KEY_IS_OPEN = "IS_OPEN";
    private static final String KEY_SUPER_STATE = "SUPER_STATE";

    private FrameLayout mHistoryFrame;
    private ViewDragHelper mDragHelper;

    // No concurrency; allow modifications while iterating.
    private final List<DragCallback> mDragCallbacks = new CopyOnWriteArrayList<>();
    private CloseCallback mCloseCallback;

    private final Map<Integer, PointF> mLastMotionPoints = new HashMap<>();
    private final Rect mHitRect = new Rect();

    private int mVerticalRange;
    private boolean mIsOpen;

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

    @Override
    protected void onFinishInflate() {
        mDragHelper = ViewDragHelper.create(this, 1.0f, new DragHelperCallback());
        mHistoryFrame = (FrameLayout) findViewById(R.id.history_frame);
        super.onFinishInflate();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        measureChildren(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int displayHeight = 0;
        for (DragCallback c : mDragCallbacks) {
            displayHeight = Math.max(displayHeight, c.getDisplayHeight());
        }
        mVerticalRange = getHeight() - displayHeight;

        final int childCount = getChildCount();
        for (int i = 0; i < childCount; ++i) {
            final View child = getChildAt(i);

            int top = 0;
            if (child == mHistoryFrame) {
                if (mDragHelper.getCapturedView() == mHistoryFrame
                        && mDragHelper.getViewDragState() != ViewDragHelper.STATE_IDLE) {
                    top = child.getTop();
                } else {
                    top = mIsOpen ? 0 : -mVerticalRange;
                }
            }
            child.layout(0, top, child.getMeasuredWidth(), top + child.getMeasuredHeight());
        }
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        final Bundle bundle = new Bundle();
        bundle.putParcelable(KEY_SUPER_STATE, super.onSaveInstanceState());
        bundle.putBoolean(KEY_IS_OPEN, mIsOpen);
        return bundle;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        if (state instanceof Bundle) {
            final Bundle bundle = (Bundle) state;
            mIsOpen = bundle.getBoolean(KEY_IS_OPEN);
            mHistoryFrame.setVisibility(mIsOpen ? View.VISIBLE : View.INVISIBLE);
            for (DragCallback c : mDragCallbacks) {
                c.onInstanceStateRestored(mIsOpen);
            }

            state = bundle.getParcelable(KEY_SUPER_STATE);
        }
        super.onRestoreInstanceState(state);
    }

    private void saveLastMotion(MotionEvent event) {
        final int action = event.getActionMasked();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_POINTER_DOWN: {
                final int actionIndex = event.getActionIndex();
                final int pointerId = event.getPointerId(actionIndex);
                final PointF point = new PointF(event.getX(actionIndex), event.getY(actionIndex));
                mLastMotionPoints.put(pointerId, point);
                break;
            }
            case MotionEvent.ACTION_MOVE: {
                for (int i = event.getPointerCount() - 1; i >= 0; --i) {
                    final int pointerId = event.getPointerId(i);
                    final PointF point = mLastMotionPoints.get(pointerId);
                    if (point != null) {
                        point.set(event.getX(i), event.getY(i));
                    }
                }
                break;
            }
            case MotionEvent.ACTION_POINTER_UP: {
                final int actionIndex = event.getActionIndex();
                final int pointerId = event.getPointerId(actionIndex);
                mLastMotionPoints.remove(pointerId);
                break;
            }
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL: {
                mLastMotionPoints.clear();
                break;
            }
        }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        saveLastMotion(event);
        return mDragHelper.shouldInterceptTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // Workaround: do not process the error case where multi-touch would cause a crash.
        if (event.getActionMasked() == MotionEvent.ACTION_MOVE
                && mDragHelper.getViewDragState() == ViewDragHelper.STATE_DRAGGING
                && mDragHelper.getActivePointerId() != ViewDragHelper.INVALID_POINTER
                && event.findPointerIndex(mDragHelper.getActivePointerId()) == -1) {
            mDragHelper.cancel();
            return false;
        }

        saveLastMotion(event);

        mDragHelper.processTouchEvent(event);
        return true;
    }

    @Override
    public void computeScroll() {
        if (mDragHelper.continueSettling(true)) {
            ViewCompat.postInvalidateOnAnimation(this);
        }
    }

    private void onStartDragging() {
        for (DragCallback c : mDragCallbacks) {
            c.onStartDraggingOpen();
        }
        mHistoryFrame.setVisibility(VISIBLE);
    }

    public boolean isViewUnder(View view, int x, int y) {
        view.getHitRect(mHitRect);
        offsetDescendantRectToMyCoords((View) view.getParent(), mHitRect);
        return mHitRect.contains(x, y);
    }

    public boolean isMoving() {
        final int draggingState = mDragHelper.getViewDragState();
        return draggingState == ViewDragHelper.STATE_DRAGGING
                || draggingState == ViewDragHelper.STATE_SETTLING;
    }

    public boolean isOpen() {
        return mIsOpen;
    }

    private void setClosed() {
        if (mIsOpen) {
            mIsOpen = false;
            mHistoryFrame.setVisibility(View.INVISIBLE);

            if (mCloseCallback != null) {
                mCloseCallback.onClose();
            }
        }
    }

    public Animator createAnimator(boolean toOpen) {
        if (mIsOpen == toOpen) {
            return ValueAnimator.ofFloat(0f, 1f).setDuration(0L);
        }

        mIsOpen = toOpen;
        mHistoryFrame.setVisibility(VISIBLE);

        final ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                mDragHelper.cancel();
                mDragHelper.smoothSlideViewTo(mHistoryFrame, 0, mIsOpen ? 0 : -mVerticalRange);
            }
        });

        return animator;
    }

    public void setCloseCallback(CloseCallback callback) {
        mCloseCallback = callback;
    }

    public void addDragCallback(DragCallback callback) {
        mDragCallbacks.add(callback);
    }

    public void removeDragCallback(DragCallback callback) {
        mDragCallbacks.remove(callback);
    }

    /**
     * Callback when the layout is closed.
     * We use this to pop the HistoryFragment off the backstack.
     * We can't use a method in DragCallback because we get ConcurrentModificationExceptions on
     * mDragCallbacks when executePendingTransactions() is called for popping the fragment off the
     * backstack.
     */
    public interface CloseCallback {
        void onClose();
    }

    /**
     * Callbacks for coordinating with the RecyclerView or HistoryFragment.
     */
    public interface DragCallback {
        // Callback when a drag to open begins.
        void onStartDraggingOpen();

        // Callback in onRestoreInstanceState.
        void onInstanceStateRestored(boolean isOpen);

        // Animate the RecyclerView text.
        void whileDragging(float yFraction);

        // Whether we should allow the view to be dragged.
        boolean shouldCaptureView(View view, int x, int y);

        int getDisplayHeight();
    }

    public class DragHelperCallback extends ViewDragHelper.Callback {
        @Override
        public void onViewDragStateChanged(int state) {
            // The view stopped moving.
            if (state == ViewDragHelper.STATE_IDLE
                    && mDragHelper.getCapturedView().getTop() < -(mVerticalRange / 2)) {
                setClosed();
            }
        }

        @Override
        public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
            for (DragCallback c : mDragCallbacks) {
                // Top is between [-mVerticalRange, 0].
                c.whileDragging(1f + (float) top / mVerticalRange);
            }
        }

        @Override
        public int getViewVerticalDragRange(View child) {
            return mVerticalRange;
        }

        @Override
        public boolean tryCaptureView(View view, int pointerId) {
            final PointF point = mLastMotionPoints.get(pointerId);
            if (point == null) {
                return false;
            }

            final int x = (int) point.x;
            final int y = (int) point.y;

            for (DragCallback c : mDragCallbacks) {
                if (!c.shouldCaptureView(view, x, y)) {
                    return false;
                }
            }
            return true;
        }

        @Override
        public int clampViewPositionVertical(View child, int top, int dy) {
            return Math.max(Math.min(top, 0), -mVerticalRange);
        }

        @Override
        public void onViewCaptured(View capturedChild, int activePointerId) {
            super.onViewCaptured(capturedChild, activePointerId);

            if (!mIsOpen) {
                mIsOpen = true;
                onStartDragging();
            }
        }

        @Override
        public void onViewReleased(View releasedChild, float xvel, float yvel) {
            final boolean settleToOpen;
            if (yvel > AUTO_OPEN_SPEED_LIMIT) {
                // Speed has priority over position.
                settleToOpen = true;
            } else if (yvel < -AUTO_OPEN_SPEED_LIMIT) {
                settleToOpen = false;
            } else {
                settleToOpen = releasedChild.getTop() > -(mVerticalRange / 2);
            }

            if (mDragHelper.settleCapturedViewAt(0, settleToOpen ? 0 : -mVerticalRange)) {
                ViewCompat.postInvalidateOnAnimation(DragLayout.this);
            }
        }
    }
}
