/*
 * Copyright (C) 2019 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.car.ui.recyclerview;

import android.content.Context;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearSnapHelper;
import androidx.recyclerview.widget.OrientationHelper;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.LayoutManager;

import java.util.Objects;

/**
 * Inspired by {@link androidx.car.widget.PagedSnapHelper}
 *
 * <p>Extension of a {@link LinearSnapHelper} that will snap to the start of the target child view
 * to the start of the attached {@link RecyclerView}. The start of the view is defined as the top if
 * the RecyclerView is scrolling vertically; it is defined as the left (or right if RTL) if the
 * RecyclerView is scrolling horizontally.
 */
public class CarUiSnapHelper extends LinearSnapHelper {
    /**
     * The percentage of a View that needs to be completely visible for it to be a viable snap
     * target.
     */
    private static final float VIEW_VISIBLE_THRESHOLD = 0.5f;

    /**
     * When a View is longer than containing RecyclerView, the percentage of the end of this View
     * that needs to be completely visible to prevent the rest of views to be a viable snap target.
     *
     * <p>In other words, if a longer-than-screen View takes more than threshold screen space on its
     * end, do not snap to any View.
     */
    private static final float LONG_ITEM_END_VISIBLE_THRESHOLD = 0.3f;

    private final Context mContext;
    private RecyclerView mRecyclerView;

    public CarUiSnapHelper(Context context) {
        mContext = context;
    }

    // Orientation helpers are lazily created per LayoutManager.
    @Nullable
    private OrientationHelper mVerticalHelper;
    @Nullable
    private OrientationHelper mHorizontalHelper;

    @Override
    public int[] calculateDistanceToFinalSnap(
            @NonNull LayoutManager layoutManager, @NonNull View targetView) {
        int[] out = new int[2];

        // Don't snap when not in touch mode, i.e. when using rotary.
        if (!mRecyclerView.isInTouchMode()) {
            return out;
        }

        if (layoutManager.canScrollHorizontally()) {
            out[0] = distanceToTopMargin(targetView, getHorizontalHelper(layoutManager));
        }

        if (layoutManager.canScrollVertically()) {
            out[1] = distanceToTopMargin(targetView, getVerticalHelper(layoutManager));
        }

        return out;
    }

    /**
     * Finds the view to snap to. The view to snap to is the child of the LayoutManager that is
     * closest to the start of the RecyclerView. The "start" depends on if the LayoutManager
     * is scrolling horizontally or vertically. If it is horizontally scrolling, then the
     * start is the view on the left (right if RTL). Otherwise, it is the top-most view.
     *
     * @param layoutManager The current {@link LayoutManager} for the attached RecyclerView.
     * @return The View closest to the start of the RecyclerView. Returns {@code null}when:
     * <ul>
     *     <li>there is no item; or
     *     <li>no visible item can fully fit in the containing RecyclerView; or
     *     <li>an item longer than containing RecyclerView is about to scroll out.
     * </ul>
     */
    @Override
    @Nullable
    public View findSnapView(LayoutManager layoutManager) {
        int childCount = layoutManager.getChildCount();
        if (childCount == 0) {
            return null;
        }

        OrientationHelper orientationHelper = getOrientationHelper(layoutManager);

        // If there's only one child, then that will be the snap target.
        if (childCount == 1) {
            View firstChild = layoutManager.getChildAt(0);
            return isValidSnapView(firstChild, orientationHelper) ? firstChild : null;
        }

        if (mRecyclerView == null) {
            return null;
        }

        // If the top child view is longer than the RecyclerView (long item), and it's not yet
        // scrolled out - meaning the screen it takes up is more than threshold,
        // do not snap to any view.
        // This way avoids next View snapping to top "pushes" out the end of a long item.
        View firstChild = mRecyclerView.getChildAt(0);
        if (firstChild.getHeight() > mRecyclerView.getHeight()
                // Long item start is scrolled past screen;
                && orientationHelper.getDecoratedStart(firstChild) < 0
                // and it takes up more than threshold screen size.
                && orientationHelper.getDecoratedEnd(firstChild) > (
                mRecyclerView.getHeight() * LONG_ITEM_END_VISIBLE_THRESHOLD)) {
            return null;
        }

        @NonNull View lastVisibleChild = Objects.requireNonNull(
                layoutManager.getChildAt(childCount - 1));

        // Check if the last child visible is the last item in the list.
        boolean lastItemVisible =
                layoutManager.getPosition(lastVisibleChild) == layoutManager.getItemCount() - 1;

        // If it is, then check how much of that view is visible.
        float lastItemPercentageVisible = lastItemVisible
                ? getPercentageVisible(lastVisibleChild, orientationHelper) : 0;

        View closestChild = null;
        int closestDistanceToStart = Integer.MAX_VALUE;
        float closestPercentageVisible = 0.f;

        // Iterate to find the child closest to the top and more than half way visible.
        for (int i = 0; i < childCount; i++) {
            View child = layoutManager.getChildAt(i);
            int startOffset = orientationHelper.getDecoratedStart(child);

            if (Math.abs(startOffset) < closestDistanceToStart) {
                float percentageVisible = getPercentageVisible(child, orientationHelper);

                if (percentageVisible > VIEW_VISIBLE_THRESHOLD
                        && percentageVisible > closestPercentageVisible) {
                    closestDistanceToStart = startOffset;
                    closestChild = child;
                    closestPercentageVisible = percentageVisible;
                }
            }
        }

        View childToReturn = closestChild;

        // If closestChild is null, then that means we were unable to find a closest child that
        // is over the VIEW_VISIBLE_THRESHOLD. This could happen if the views are larger than
        // the given area. In this case, consider returning the lastVisibleChild so that the screen
        // scrolls. Also, check if the last item should be displayed anyway if it is mostly visible.
        if ((childToReturn == null
                || (lastItemVisible && lastItemPercentageVisible > closestPercentageVisible))) {
            childToReturn = lastVisibleChild;
        }

        // Return null if the childToReturn is not valid. This allows the user to scroll freely
        // with no snapping. This can allow them to see the entire view.
        return isValidSnapView(childToReturn, orientationHelper) ? childToReturn : null;
    }

    private static int distanceToTopMargin(@NonNull View targetView, OrientationHelper helper) {
        final int childTop = helper.getDecoratedStart(targetView);
        final int containerTop = helper.getStartAfterPadding();
        return childTop - containerTop;
    }

    /**
     * Finds the view to snap to. The view to snap to is the child of the LayoutManager that is
     * closest to the start of the RecyclerView. The "start" depends on if the LayoutManager is
     * scrolling horizontally or vertically. If it is horizontally scrolling, then the start is the
     * view on the left (right if RTL). Otherwise, it is the top-most view.
     *
     * @param layoutManager The current {@link RecyclerView.LayoutManager} for the attached
     *                      RecyclerView.
     * @return The View closest to the start of the RecyclerView.
     */
    private static View findTopView(LayoutManager layoutManager, OrientationHelper helper) {
        int childCount = layoutManager.getChildCount();
        if (childCount == 0) {
            return null;
        }

        View closestChild = null;
        int absClosest = Integer.MAX_VALUE;

        for (int i = 0; i < childCount; i++) {
            View child = layoutManager.getChildAt(i);
            if (child == null) {
                continue;
            }
            int absDistance = Math.abs(distanceToTopMargin(child, helper));

            /* if child top is closer than previous closest, set it as closest */
            if (absDistance < absClosest) {
                absClosest = absDistance;
                closestChild = child;
            }
        }
        return closestChild;
    }

    /**
     * Returns whether or not the given View is a valid snapping view. A view is considered valid
     * for snapping if it can fit entirely within the height of the RecyclerView it is contained
     * within.
     *
     * <p>If the view is larger than the RecyclerView, then it might not want to be snapped to
     * to allow the user to scroll and see the rest of the View.
     *
     * @param view   The view to determine the snapping potential.
     * @param helper The {@link OrientationHelper} associated with the current RecyclerView.
     * @return {@code true} if the given view is a valid snapping view; {@code false} otherwise.
     */
    private static boolean isValidSnapView(View view, OrientationHelper helper) {
        return helper.getDecoratedMeasurement(view) <= helper.getTotalSpace();
    }

    /**
     * Returns the percentage of the given view that is visible, relative to its containing
     * RecyclerView.
     *
     * @param view   The View to get the percentage visible of.
     * @param helper An {@link OrientationHelper} to aid with calculation.
     * @return A float indicating the percentage of the given view that is visible.
     */
    static float getPercentageVisible(View view, OrientationHelper helper) {
        int start = helper.getStartAfterPadding();
        int end = helper.getEndAfterPadding();

        int viewStart = helper.getDecoratedStart(view);
        int viewEnd = helper.getDecoratedEnd(view);

        if (viewStart >= start && viewEnd <= end) {
            // The view is within the bounds of the RecyclerView, so it's fully visible.
            return 1.f;
        } else if (viewEnd <= start) {
            // The view is above the visible area of the RecyclerView.
            return 0;
        } else if (viewStart >= end) {
            // The view is below the visible area of the RecyclerView.
            return 0;
        } else if (viewStart <= start && viewEnd >= end) {
            // The view is larger than the height of the RecyclerView.
            return ((float) end - start) / helper.getDecoratedMeasurement(view);
        } else if (viewStart < start) {
            // The view is above the start of the RecyclerView.
            return ((float) viewEnd - start) / helper.getDecoratedMeasurement(view);
        } else {
            // The view is below the end of the RecyclerView.
            return ((float) end - viewStart) / helper.getDecoratedMeasurement(view);
        }
    }

    @Override
    public void attachToRecyclerView(@Nullable RecyclerView recyclerView) {
        super.attachToRecyclerView(recyclerView);
        mRecyclerView = recyclerView;
    }

    /**
     * Returns a scroller specific to this {@code PagedSnapHelper}. This scroller is used for all
     * smooth scrolling operations, including flings.
     *
     * @param layoutManager The {@link LayoutManager} associated with the attached
     *                      {@link RecyclerView}.
     * @return a {@link RecyclerView.SmoothScroller} which will handle the scrolling.
     */
    @Override
    protected RecyclerView.SmoothScroller createScroller(@NonNull LayoutManager layoutManager) {
        return new CarUiSmoothScroller(mContext);
    }

    /**
     * Calculate the estimated scroll distance in each direction given velocities on both axes.
     * This method will clamp the maximum scroll distance so that a single fling will never scroll
     * more than one page.
     *
     * @param velocityX Fling velocity on the horizontal axis.
     * @param velocityY Fling velocity on the vertical axis.
     * @return An array holding the calculated distances in x and y directions respectively.
     */
    @Override
    public int[] calculateScrollDistance(int velocityX, int velocityY) {
        int[] outDist = super.calculateScrollDistance(velocityX, velocityY);

        if (mRecyclerView == null) {
            return outDist;
        }

        LayoutManager layoutManager = mRecyclerView.getLayoutManager();
        if (layoutManager == null || layoutManager.getChildCount() == 0) {
            return outDist;
        }

        int lastChildPosition = isAtEnd(layoutManager) ? 0 : layoutManager.getChildCount() - 1;

        OrientationHelper orientationHelper = getOrientationHelper(layoutManager);
        @NonNull View lastChild = Objects.requireNonNull(
                layoutManager.getChildAt(lastChildPosition));
        float percentageVisible = getPercentageVisible(lastChild, orientationHelper);

        int maxDistance = layoutManager.getHeight();
        if (percentageVisible > 0.f) {
            // The max and min distance is the total height of the RecyclerView minus the height of
            // the last child. This ensures that each scroll will never scroll more than a single
            // page on the RecyclerView. That is, the max scroll will make the last child the
            // first child and vice versa when scrolling the opposite way.
            maxDistance -= layoutManager.getDecoratedMeasuredHeight(lastChild);
        }

        int minDistance = -maxDistance;

        outDist[0] = clamp(outDist[0], minDistance, maxDistance);
        outDist[1] = clamp(outDist[1], minDistance, maxDistance);

        return outDist;
    }

    /**
     * Estimates a position to which CarUiSnapHelper will try to snap to for a requested scroll
     * distance.
     *
     * @param helper         The {@link OrientationHelper} that is created from the LayoutManager.
     * @param scrollDistance The intended scroll distance.
     *
     * @return The diff between the target snap position and the current position.
     */
    public int estimateNextPositionDiffForScrollDistance(OrientationHelper helper,
            int scrollDistance) {
        float distancePerChild = computeDistancePerChild(helper.getLayoutManager(), helper);
        if (distancePerChild <= 0) {
            return 0;
        }
        return (int) Math.round(scrollDistance / distancePerChild);
    }

    /**
     * This method is taken verbatim from the [androidx] {@link LinearSnapHelper} private method
     * implementation.
     *
     * Computes an average pixel value to pass a single child.
     * <p>
     * Returns a negative value if it cannot be calculated.
     *
     * @param layoutManager The {@link RecyclerView.LayoutManager} associated with the attached
     *                      {@link RecyclerView}.
     * @param helper        The relevant {@link OrientationHelper} for the attached
     *                      {@link RecyclerView.LayoutManager}.
     *
     * @return A float value that is the average number of pixels needed to scroll by one view in
     * the relevant direction.
     */
    private float computeDistancePerChild(RecyclerView.LayoutManager layoutManager,
            OrientationHelper helper) {
        View minPosView = null;
        View maxPosView = null;
        int minPos = Integer.MAX_VALUE;
        int maxPos = Integer.MIN_VALUE;
        int childCount = layoutManager.getChildCount();
        if (childCount == 0) {
            return 1;
        }

        for (int i = 0; i < childCount; i++) {
            View child = layoutManager.getChildAt(i);
            final int pos = layoutManager.getPosition(child);
            if (pos == RecyclerView.NO_POSITION) {
                continue;
            }
            if (pos < minPos) {
                minPos = pos;
                minPosView = child;
            }
            if (pos > maxPos) {
                maxPos = pos;
                maxPosView = child;
            }
        }
        if (minPosView == null || maxPosView == null) {
            return 1;
        }
        int start = Math.min(helper.getDecoratedStart(minPosView),
                helper.getDecoratedStart(maxPosView));
        int end = Math.max(helper.getDecoratedEnd(minPosView),
                helper.getDecoratedEnd(maxPosView));
        int distance = end - start;
        if (distance == 0) {
            return 0;
        }
        return 1f * distance / ((maxPos - minPos) + 1);
    }

    /**
     * Returns {@code true} if the RecyclerView is completely displaying the first item.
     */
    public boolean isAtStart(@Nullable LayoutManager layoutManager) {
        if (layoutManager == null || layoutManager.getChildCount() == 0) {
            return true;
        }

        @NonNull View firstChild = Objects.requireNonNull(layoutManager.getChildAt(0));
        OrientationHelper orientationHelper =
                layoutManager.canScrollVertically() ? getVerticalHelper(layoutManager)
                        : getHorizontalHelper(layoutManager);

        // Check that the first child is completely visible and is the first item in the list.
        return orientationHelper.getDecoratedStart(firstChild)
                >= orientationHelper.getStartAfterPadding() && layoutManager.getPosition(firstChild)
                == 0;
    }

    /**
     * Returns {@code true} if the RecyclerView is completely displaying the last item.
     */
    public boolean isAtEnd(@Nullable LayoutManager layoutManager) {
        if (layoutManager == null || layoutManager.getChildCount() == 0) {
            return true;
        }

        int childCount = layoutManager.getChildCount();
        OrientationHelper orientationHelper =
                layoutManager.canScrollVertically() ? getVerticalHelper(layoutManager)
                        : getHorizontalHelper(layoutManager);

        @NonNull View lastVisibleChild = Objects.requireNonNull(
                layoutManager.getChildAt(childCount - 1));

        // The list has reached the bottom if the last child that is visible is the last item
        // in the list and it's fully shown.
        return layoutManager.getPosition(lastVisibleChild) == (layoutManager.getItemCount() - 1)
                && layoutManager.getDecoratedBottom(lastVisibleChild)
                <= orientationHelper.getEndAfterPadding();
    }

    /**
     * Returns an {@link OrientationHelper} that corresponds to the current scroll direction of the
     * given {@link LayoutManager}.
     */
    @NonNull
    private OrientationHelper getOrientationHelper(@NonNull LayoutManager layoutManager) {
        return layoutManager.canScrollVertically()
                ? getVerticalHelper(layoutManager)
                : getHorizontalHelper(layoutManager);
    }

    @NonNull
    private OrientationHelper getVerticalHelper(@NonNull LayoutManager layoutManager) {
        if (mVerticalHelper == null || mVerticalHelper.getLayoutManager() != layoutManager) {
            mVerticalHelper = OrientationHelper.createVerticalHelper(layoutManager);
        }
        return mVerticalHelper;
    }

    @NonNull
    private OrientationHelper getHorizontalHelper(@NonNull LayoutManager layoutManager) {
        if (mHorizontalHelper == null || mHorizontalHelper.getLayoutManager() != layoutManager) {
            mHorizontalHelper = OrientationHelper.createHorizontalHelper(layoutManager);
        }
        return mHorizontalHelper;
    }

    /**
     * Ensures that the given value falls between the range given by the min and max values. This
     * method does not check that the min value is greater than or equal to the max value. If the
     * parameters are not well-formed, this method's behavior is undefined.
     *
     * @param value The value to clamp.
     * @param min   The minimum value the given value can be.
     * @param max   The maximum value the given value can be.
     * @return A number that falls between {@code min} or {@code max} or one of those values if the
     * given value is less than or greater than {@code min} and {@code max} respectively.
     */
    private static int clamp(int value, int min, int max) {
        return Math.max(min, Math.min(max, value));
    }
}
