/*
 * 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.pagedrecyclerview.decorations.grid;

import static java.lang.annotation.RetentionPolicy.SOURCE;

import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.view.View;

import androidx.annotation.IntDef;
import androidx.recyclerview.widget.RecyclerView;

import java.lang.annotation.Retention;

/** Adds an offset to the top of a RecyclerView with a GridLayoutManager or its subclass. */
public class GridOffsetItemDecoration extends RecyclerView.ItemDecoration {

    private int mOffsetPx;
    private Drawable mOffsetDrawable;
    private int mNumColumns;
    @OffsetPosition
    private final int mOffsetPosition;

    /** The possible values for setScrollbarPosition. */
    @IntDef({
            OffsetPosition.START,
            OffsetPosition.END,
    })
    @Retention(SOURCE)
    public @interface OffsetPosition {
        /** Position the offset to the start of the screen. */
        int START = 0;

        /** Position offset to the end of the screen. */
        int END = 1;
    }

    /**
     * Constructor that takes in the size of the offset to be added to the top of the RecyclerView.
     *
     * @param offsetPx The size of the offset to be added to the top of the RecyclerView in pixels
     * @param numColumns The number of columns in the grid of the RecyclerView
     * @param offsetPosition Position where offset needs to be applied.
     */
    public GridOffsetItemDecoration(int offsetPx, int numColumns, int offsetPosition) {
        this.mOffsetPx = offsetPx;
        this.mNumColumns = numColumns;
        this.mOffsetPosition = offsetPosition;
    }

    /**
     * Constructor that takes in a {@link Drawable} to be drawn at the top of the RecyclerView.
     *
     * @param offsetDrawable The {@code Drawable} to be added to the top of the RecyclerView
     * @param numColumns The number of columns in the grid of the RecyclerView
     */
    public GridOffsetItemDecoration(Drawable offsetDrawable, int numColumns, int offsetPosition) {
        this.mOffsetDrawable = offsetDrawable;
        this.mNumColumns = numColumns;
        this.mOffsetPosition = offsetPosition;
    }

    public void setNumOfColumns(int numberOfColumns) {
        mNumColumns = numberOfColumns;
    }

    /**
     * Determines the size and the location of the offset to be added to the top of the
     * RecyclerView.
     *
     * @param outRect The {@link Rect} of offsets to be added around the child view
     * @param view The child view to be decorated with an offset
     * @param parent The RecyclerView onto which dividers are being added
     * @param state The current RecyclerView.State of the RecyclerView
     */
    @Override
    public void getItemOffsets(
            Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);

        if (mOffsetPosition == OffsetPosition.START) {
            boolean childIsInTopRow = parent.getChildAdapterPosition(view) < mNumColumns;
            if (childIsInTopRow) {
                if (mOffsetPx > 0) {
                    outRect.top = mOffsetPx;
                } else if (mOffsetDrawable != null) {
                    outRect.top = mOffsetDrawable.getIntrinsicHeight();
                }
            }
            return;
        }

        int childCount = state.getItemCount();
        int lastRowChildCount = getLastRowChildCount(childCount);

        boolean childIsInBottomRow =
                parent.getChildAdapterPosition(view) >= childCount - lastRowChildCount;
        if (childIsInBottomRow) {
            if (mOffsetPx > 0) {
                outRect.bottom = mOffsetPx;
            } else if (mOffsetDrawable != null) {
                outRect.bottom = mOffsetDrawable.getIntrinsicHeight();
            }
        }
    }

    @Override
    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
        super.onDraw(c, parent, state);
        if (mOffsetDrawable == null) {
            return;
        }

        int parentLeft = parent.getPaddingLeft();
        int parentRight = parent.getWidth() - parent.getPaddingRight();

        if (mOffsetPosition == OffsetPosition.START) {

            int parentTop = parent.getPaddingTop();
            int offsetDrawableBottom = parentTop + mOffsetDrawable.getIntrinsicHeight();

            mOffsetDrawable.setBounds(parentLeft, parentTop, parentRight, offsetDrawableBottom);
            mOffsetDrawable.draw(c);
            return;
        }

        int childCount = state.getItemCount();
        int lastRowChildCount = getLastRowChildCount(childCount);

        int offsetDrawableTop = 0;
        int offsetDrawableBottom = 0;

        for (int i = childCount - lastRowChildCount; i < childCount; i++) {
            View child = parent.getChildAt(i);
            offsetDrawableTop = child.getBottom();
            offsetDrawableBottom = offsetDrawableTop + mOffsetDrawable.getIntrinsicHeight();
        }

        mOffsetDrawable.setBounds(parentLeft, offsetDrawableTop, parentRight, offsetDrawableBottom);
        mOffsetDrawable.draw(c);
    }

    private int getLastRowChildCount(int itemCount) {
        int lastRowChildCount = itemCount % mNumColumns;
        if (lastRowChildCount == 0) {
            lastRowChildCount = mNumColumns;
        }

        return lastRowChildCount;
    }
}
