/*
 * 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;

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

import android.car.drivingstate.CarUxRestrictions;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;

import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.android.car.ui.R;
import com.android.car.ui.pagedrecyclerview.decorations.grid.GridDividerItemDecoration;
import com.android.car.ui.pagedrecyclerview.decorations.grid.GridOffsetItemDecoration;
import com.android.car.ui.pagedrecyclerview.decorations.linear.LinearDividerItemDecoration;
import com.android.car.ui.pagedrecyclerview.decorations.linear.LinearOffsetItemDecoration;
import com.android.car.ui.pagedrecyclerview.decorations.linear.LinearOffsetItemDecoration.OffsetPosition;

import java.lang.annotation.Retention;

/**
 * View that extends a {@link RecyclerView} and creates a nested {@code RecyclerView} which could
 * potentially include a scrollbar that has page up and down arrows. Interaction with this view is
 * similar to a {@code RecyclerView} as it takes the same adapter and the layout manager.
 */
public final class PagedRecyclerView extends RecyclerView {

    private static final boolean DEBUG = false;
    private static final String TAG = "PagedRecyclerView";

    private final CarUxRestrictionsUtil mCarUxRestrictionsUtil;
    private final CarUxRestrictionsUtil.OnUxRestrictionsChangedListener mListener;

    private boolean mScrollBarEnabled;
    private int mScrollBarContainerWidth;
    @ScrollBarPosition
    private int mScrollBarPosition;
    private boolean mScrollBarAboveRecyclerView;
    private String mScrollBarClass;
    private boolean mFullyInitialized;
    private float mScrollBarPaddingStart;
    private float mScrollBarPaddingEnd;
    private Context mContext;

    @Gutter
    private int mGutter;
    private int mGutterSize;
    private RecyclerView mNestedRecyclerView;
    private Adapter<?> mAdapter;
    private ScrollBar mScrollBar;

    private GridOffsetItemDecoration mOffsetItemDecoration;
    private GridDividerItemDecoration mDividerItemDecoration;
    @PagedRecyclerViewLayout
    int mPagedRecyclerViewLayout;
    private int mNumOfColumns;

    /**
     * The possible values for @{link #setGutter}. The default value is actually {@link
     * PagedRecyclerView.Gutter#BOTH}.
     */
    @IntDef({
            Gutter.NONE,
            Gutter.START,
            Gutter.END,
            Gutter.BOTH,
    })
    @Retention(SOURCE)
    public @interface Gutter {
        /**
         * No gutter on either side of the list items. The items will span the full width of the
         * RecyclerView
         */
        int NONE = 0;

        /** Include a gutter only on the start side (that is, the same side as the scroll bar). */
        int START = 1;

        /** Include a gutter only on the end side (that is, the opposite side of the scroll bar). */
        int END = 2;

        /** Include a gutter on both sides of the list items. This is the default behaviour. */
        int BOTH = 3;
    }

    /**
     * The possible values for setScrollbarPosition. The default value is actually {@link
     * PagedRecyclerView.ScrollBarPosition#START}.
     */
    @IntDef({
            ScrollBarPosition.START,
            ScrollBarPosition.END,
    })
    @Retention(SOURCE)
    public @interface ScrollBarPosition {
        /** Position the scrollbar to the left of the screen. This is default. */
        int START = 0;

        /** Position scrollbar to the right of the screen. */
        int END = 2;
    }

    /**
     * The possible values for setScrollbarPosition. The default value is actually {@link
     * PagedRecyclerViewLayout#LINEAR}.
     */
    @IntDef({
            PagedRecyclerViewLayout.LINEAR,
            PagedRecyclerViewLayout.GRID,
    })
    @Retention(SOURCE)
    public @interface PagedRecyclerViewLayout {
        /** Position the scrollbar to the left of the screen. This is default. */
        int LINEAR = 0;

        /** Position scrollbar to the right of the screen. */
        int GRID = 2;
    }

    /**
     * Interface for a {@link RecyclerView.Adapter} to cap the number of items.
     *
     * <p>NOTE: it is still up to the adapter to use maxItems in {@link
     * RecyclerView.Adapter#getItemCount()}.
     *
     * <p>the recommended way would be with:
     *
     * <pre>{@code
     * {@literal@}Override
     * public int getItemCount() {
     *   return Math.min(super.getItemCount(), mMaxItems);
     * }
     * }</pre>
     */
    public interface ItemCap {
        /** A value to pass to {@link #setMaxItems(int)} that indicates there should be no limit. */
        int UNLIMITED = -1;

        /**
         * Sets the maximum number of items available in the adapter. A value less than '0' means
         * the
         * list should not be capped.
         */
        void setMaxItems(int maxItems);
    }

    /**
     * Custom layout manager for the outer recyclerview. Since paddings should be applied by the
     * inner
     * recycler view within its bounds, this layout manager should always have 0 padding.
     */
    private static class PagedRecyclerViewLayoutManager extends LinearLayoutManager {
        PagedRecyclerViewLayoutManager(Context context) {
            super(context);
        }

        @Override
        public int getPaddingTop() {
            return 0;
        }

        @Override
        public int getPaddingBottom() {
            return 0;
        }

        @Override
        public int getPaddingStart() {
            return 0;
        }

        @Override
        public int getPaddingEnd() {
            return 0;
        }

        @Override
        public boolean canScrollHorizontally() {
            return false;
        }

        @Override
        public boolean canScrollVertically() {
            return false;
        }
    }

    /**
     * Custom layout manager for the outer recyclerview. Since paddings should be applied by the
     * inner
     * recycler view within its bounds, this layout manager should always have 0 padding.
     */
    private static class GridPagedRecyclerViewLayoutManager extends GridLayoutManager {
        GridPagedRecyclerViewLayoutManager(Context context, int numOfColumns) {
            super(context, numOfColumns);
        }

        @Override
        public int getPaddingTop() {
            return 0;
        }

        @Override
        public int getPaddingBottom() {
            return 0;
        }

        @Override
        public int getPaddingStart() {
            return 0;
        }

        @Override
        public int getPaddingEnd() {
            return 0;
        }
    }

    public PagedRecyclerView(@NonNull Context context) {
        this(context, null, 0);
    }

    public PagedRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PagedRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        mCarUxRestrictionsUtil = CarUxRestrictionsUtil.getInstance(context);
        mListener = this::updateCarUxRestrictions;

        init(context, attrs, defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyleAttr) {
        TypedArray a =
                context.obtainStyledAttributes(
                        attrs, R.styleable.PagedRecyclerView, defStyleAttr,
                        R.style.Widget_Chassis_PagedRecyclerView);

        mScrollBarEnabled = context.getResources().getBoolean(R.bool.chassis_scrollbar_enable);
        mFullyInitialized = false;

        if (!mScrollBarEnabled) {
            a.recycle();
            mFullyInitialized = true;
            return;
        }

        mNestedRecyclerView =
                new RecyclerView(context, attrs,
                        R.style.Widget_Chassis_PagedRecyclerView_NestedRecyclerView);

        mScrollBarPaddingStart =
                context.getResources().getDimension(R.dimen.chassis_scrollbar_padding_start);
        mScrollBarPaddingEnd =
                context.getResources().getDimension(R.dimen.chassis_scrollbar_padding_end);

        mPagedRecyclerViewLayout =
                a.getInt(R.styleable.PagedRecyclerView_layoutStyle, PagedRecyclerViewLayout.LINEAR);
        mNumOfColumns = a.getInt(R.styleable.PagedRecyclerView_numOfColumns, /* defValue= */ 2);
        boolean enableDivider =
                a.getBoolean(R.styleable.PagedRecyclerView_enableDivider, /* defValue= */ true);

        if (mPagedRecyclerViewLayout == PagedRecyclerViewLayout.LINEAR) {

            int linearTopOffset =
                    a.getInteger(R.styleable.PagedRecyclerView_startOffset, /* defValue= */ 0);
            int linearBottomOffset =
                    a.getInteger(R.styleable.PagedRecyclerView_endOffset, /* defValue= */ 0);

            if (enableDivider) {
                RecyclerView.ItemDecoration dividerItemDecoration =
                        new LinearDividerItemDecoration(
                                context.getDrawable(R.drawable.chassis_pagedrecyclerview_divider));
                super.addItemDecoration(dividerItemDecoration);
            }
            RecyclerView.ItemDecoration topOffsetItemDecoration =
                    new LinearOffsetItemDecoration(linearTopOffset, OffsetPosition.START);
            super.addItemDecoration(topOffsetItemDecoration);

            RecyclerView.ItemDecoration bottomOffsetItemDecoration =
                    new LinearOffsetItemDecoration(linearBottomOffset, OffsetPosition.END);
            super.addItemDecoration(bottomOffsetItemDecoration);
        } else {

            int gridTopOffset =
                    a.getInteger(R.styleable.PagedRecyclerView_startOffset, /* defValue= */ 0);
            int gridBottomOffset =
                    a.getInteger(R.styleable.PagedRecyclerView_endOffset, /* defValue= */ 0);

            if (enableDivider) {
                mDividerItemDecoration =
                        new GridDividerItemDecoration(
                                context.getDrawable(R.drawable.chassis_divider),
                                context.getDrawable(R.drawable.chassis_divider),
                                mNumOfColumns);
                super.addItemDecoration(mDividerItemDecoration);
            }

            mOffsetItemDecoration =
                    new GridOffsetItemDecoration(gridTopOffset, mNumOfColumns,
                            OffsetPosition.START);
            super.addItemDecoration(mOffsetItemDecoration);

            GridOffsetItemDecoration bottomOffsetItemDecoration =
                    new GridOffsetItemDecoration(gridBottomOffset, mNumOfColumns,
                            OffsetPosition.END);
            super.addItemDecoration(bottomOffsetItemDecoration);
        }

        super.setLayoutManager(new PagedRecyclerViewLayoutManager(context));
        super.setAdapter(new PagedRecyclerViewAdapter());
        super.setNestedScrollingEnabled(false);
        super.setClipToPadding(false);

        // Gutter
        mGutter = context.getResources().getInteger(R.integer.chassis_scrollbar_gutter);
        mGutterSize = getResources().getDimensionPixelSize(R.dimen.chassis_scrollbar_margin);

        mScrollBarContainerWidth =
                (int) context.getResources().getDimension(
                        R.dimen.chassis_scrollbar_container_width);

        mScrollBarPosition = context.getResources().getInteger(
                R.integer.chassis_scrollbar_position);

        mScrollBarAboveRecyclerView =
                context.getResources().getBoolean(R.bool.chassis_scrollbar_above_recycler_view);
        mScrollBarClass = context.getResources().getString(R.string.chassis_scrollbar_component);
        a.recycle();
        this.mContext = context;
        // Apply inner RV layout changes after the layout has been calculated for this view.
        this.getViewTreeObserver()
                .addOnGlobalLayoutListener(
                        new OnGlobalLayoutListener() {
                            @Override
                            public void onGlobalLayout() {
                                // View holder layout is still pending.
                                if (PagedRecyclerView.this.findViewHolderForAdapterPosition(0)
                                        == null) {
                                    return;
                                }

                                PagedRecyclerView.this.getViewTreeObserver()
                                        .removeOnGlobalLayoutListener(this);
                                initNestedRecyclerView();
                                setNestedViewLayout();

                                mNestedRecyclerView
                                        .getViewTreeObserver()
                                        .addOnGlobalLayoutListener(
                                                new OnGlobalLayoutListener() {
                                                    @Override
                                                    public void onGlobalLayout() {
                                                        mNestedRecyclerView
                                                                .getViewTreeObserver()
                                                                .removeOnGlobalLayoutListener(this);
                                                        ViewGroup.LayoutParams params =
                                                                getLayoutParams();
                                                        params.height = getMeasuredHeight();
                                                        setLayoutParams(params);
                                                        createScrollBarFromConfig();
                                                        mFullyInitialized = true;
                                                    }
                                                });
                            }
                        });
    }

    /**
     * Returns {@code true} if the {@PagedRecyclerView} is fully drawn. Using a global layout
     * mListener
     * may not necessarily signify that this view is fully drawn (i.e. when the scrollbar is
     * enabled).
     * This is because the inner views (scrollbar and inner recycler view) are drawn after the
     * outer
     * views are finished.
     */
    public boolean fullyInitialized() {
        return mFullyInitialized;
    }

    /** Sets the number of columns in which grid needs to be divided. */
    public void setNumOfColumns(int numberOfColumns) {
        mNumOfColumns = numberOfColumns;
        mOffsetItemDecoration.setNumOfColumns(mNumOfColumns);
        mDividerItemDecoration.setNumOfColumns(mNumOfColumns);
    }

    /**
     * Returns the {@link LayoutManager} for the {@link RecyclerView} displaying the content.
     *
     * <p>In cases where the scroll bar is visible and the nested {@link RecyclerView} is displaying
     * content, {@link #getLayoutManager()} cannot be used because it returns the {@link
     * LayoutManager} of the outer {@link RecyclerView}. {@link #getLayoutManager()} could not be
     * overridden to return the effective manager due to interference with accessibility node tree
     * traversal.
     */
    @Nullable
    public LayoutManager getEffectiveLayoutManager() {
        if (mScrollBarEnabled) {
            return mNestedRecyclerView.getLayoutManager();
        }
        return super.getLayoutManager();
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        mCarUxRestrictionsUtil.register(mListener);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        mCarUxRestrictionsUtil.unregister(mListener);
    }

    private void updateCarUxRestrictions(CarUxRestrictions carUxRestrictions) {
        // If the adapter does not implement ItemCap, then the max items on it cannot be updated.
        if (!(mAdapter instanceof ItemCap)) {
            return;
        }

        int maxItems = ItemCap.UNLIMITED;
        if ((carUxRestrictions.getActiveRestrictions()
                & CarUxRestrictions.UX_RESTRICTIONS_LIMIT_CONTENT)
                != 0) {
            maxItems = carUxRestrictions.getMaxCumulativeContentItems();
        }

        int originalCount = mAdapter.getItemCount();
        ((ItemCap) mAdapter).setMaxItems(maxItems);
        int newCount = mAdapter.getItemCount();

        if (newCount == originalCount) {
            return;
        }

        if (newCount < originalCount) {
            mAdapter.notifyItemRangeRemoved(newCount, originalCount - newCount);
        } else {
            mAdapter.notifyItemRangeInserted(originalCount, newCount - originalCount);
        }
    }

    @Override
    public void setClipToPadding(boolean clipToPadding) {
        if (mScrollBarEnabled) {
            mNestedRecyclerView.setClipToPadding(clipToPadding);
        } else {
            super.setClipToPadding(clipToPadding);
        }
    }

    @SuppressWarnings("rawtypes")
    @Override
    public void setAdapter(@Nullable Adapter adapter) {

        if (mPagedRecyclerViewLayout == PagedRecyclerViewLayout.LINEAR) {
            mNestedRecyclerView.setLayoutManager(new LinearLayoutManager(mContext));
        } else {
            mNestedRecyclerView.setLayoutManager(
                    new GridPagedRecyclerViewLayoutManager(mContext, mNumOfColumns));
            setNumOfColumns(mNumOfColumns);
        }

        this.mAdapter = adapter;
        if (mScrollBarEnabled) {
            mNestedRecyclerView.setAdapter(adapter);
        } else {
            super.setAdapter(adapter);
        }
    }

    @Nullable
    @Override
    public Adapter<?> getAdapter() {
        if (mScrollBarEnabled) {
            return mNestedRecyclerView.getAdapter();
        }
        return super.getAdapter();
    }

    @Override
    public void setLayoutManager(@Nullable LayoutManager layout) {
        if (mScrollBarEnabled) {
            mNestedRecyclerView.setLayoutManager(layout);
        } else {
            super.setLayoutManager(layout);
        }
    }

    @Override
    public void setOnScrollChangeListener(OnScrollChangeListener l) {
        if (mScrollBarEnabled) {
            mNestedRecyclerView.setOnScrollChangeListener(l);
        } else {
            super.setOnScrollChangeListener(l);
        }
    }

    @Override
    public void setVerticalFadingEdgeEnabled(boolean verticalFadingEdgeEnabled) {
        if (mScrollBarEnabled) {
            mNestedRecyclerView.setVerticalFadingEdgeEnabled(verticalFadingEdgeEnabled);
        } else {
            super.setVerticalFadingEdgeEnabled(verticalFadingEdgeEnabled);
        }
    }

    @Override
    public void setFadingEdgeLength(int length) {
        if (mScrollBarEnabled) {
            mNestedRecyclerView.setFadingEdgeLength(length);
        } else {
            super.setFadingEdgeLength(length);
        }
    }

    @Override
    public void addItemDecoration(@NonNull ItemDecoration decor, int index) {
        if (mScrollBarEnabled) {
            mNestedRecyclerView.addItemDecoration(decor, index);
        } else {
            super.addItemDecoration(decor, index);
        }
    }

    @Override
    public void addItemDecoration(@NonNull ItemDecoration decor) {
        if (mScrollBarEnabled) {
            mNestedRecyclerView.addItemDecoration(decor);
        } else {
            super.addItemDecoration(decor);
        }
    }

    @Override
    public void setItemAnimator(@Nullable ItemAnimator animator) {
        if (mScrollBarEnabled) {
            mNestedRecyclerView.setItemAnimator(animator);
        } else {
            super.setItemAnimator(animator);
        }
    }

    @Override
    public void setPadding(int left, int top, int right, int bottom) {
        if (mScrollBarEnabled) {
            mNestedRecyclerView.setPadding(left, top, right, bottom);
            if (mScrollBar != null) {
                mScrollBar.requestLayout();
            }
        } else {
            super.setPadding(left, top, right, bottom);
        }
    }

    @Override
    public void setPaddingRelative(int start, int top, int end, int bottom) {
        if (mScrollBarEnabled) {
            mNestedRecyclerView.setPaddingRelative(start, top, end, bottom);
            if (mScrollBar != null) {
                mScrollBar.requestLayout();
            }
        } else {
            super.setPaddingRelative(start, top, end, bottom);
        }
    }

    @Override
    public ViewHolder findViewHolderForLayoutPosition(int position) {
        if (mScrollBarEnabled) {
            return mNestedRecyclerView.findViewHolderForLayoutPosition(position);
        } else {
            return super.findViewHolderForLayoutPosition(position);
        }
    }

    @Override
    public ViewHolder findContainingViewHolder(View view) {
        if (mScrollBarEnabled) {
            return mNestedRecyclerView.findContainingViewHolder(view);
        } else {
            return super.findContainingViewHolder(view);
        }
    }

    @Override
    @Nullable
    public View findChildViewUnder(float x, float y) {
        if (mScrollBarEnabled) {
            return mNestedRecyclerView.findChildViewUnder(x, y);
        } else {
            return super.findChildViewUnder(x, y);
        }
    }

    @Override
    public void addOnScrollListener(@NonNull OnScrollListener listener) {
        if (mScrollBarEnabled) {
            mNestedRecyclerView.addOnScrollListener(listener);
        } else {
            super.addOnScrollListener(listener);
        }
    }

    @Override
    public void removeOnScrollListener(@NonNull OnScrollListener listener) {
        if (mScrollBarEnabled) {
            mNestedRecyclerView.removeOnScrollListener(listener);
        } else {
            super.removeOnScrollListener(listener);
        }
    }

    @Override
    public int getPaddingStart() {
        return mScrollBarEnabled ? mNestedRecyclerView.getPaddingStart() : super.getPaddingStart();
    }

    @Override
    public int getPaddingEnd() {
        return mScrollBarEnabled ? mNestedRecyclerView.getPaddingEnd() : super.getPaddingEnd();
    }

    @Override
    public int getPaddingTop() {
        return mScrollBarEnabled ? mNestedRecyclerView.getPaddingTop() : super.getPaddingTop();
    }

    @Override
    public int getPaddingBottom() {
        return mScrollBarEnabled ? mNestedRecyclerView.getPaddingBottom()
                : super.getPaddingBottom();
    }

    @Override
    public void setVisibility(int visibility) {
        super.setVisibility(visibility);
        if (mScrollBarEnabled) {
            mNestedRecyclerView.setVisibility(visibility);
        }
    }

    private void initNestedRecyclerView() {
        PagedRecyclerViewAdapter.NestedRowViewHolder vh =
                (PagedRecyclerViewAdapter.NestedRowViewHolder)
                        this.findViewHolderForAdapterPosition(0);
        if (vh == null) {
            throw new Error("Outer RecyclerView failed to initialize.");
        }

        vh.frameLayout.addView(mNestedRecyclerView);
    }

    private void createScrollBarFromConfig() {
        if (DEBUG) {
            Log.d(TAG, "createScrollBarFromConfig");
        }

        Class<?> cls;
        try {
            cls = !TextUtils.isEmpty(mScrollBarClass)
                    ? getContext().getClassLoader().loadClass(mScrollBarClass)
                    : DefaultScrollBar.class;
        } catch (Throwable t) {
            throw andLog("Error loading scroll bar component: " + mScrollBarClass, t);
        }
        try {
            mScrollBar = (ScrollBar) cls.getDeclaredConstructor().newInstance();
        } catch (Throwable t) {
            throw andLog("Error creating scroll bar component: " + mScrollBarClass, t);
        }

        mScrollBar.initialize(
                mNestedRecyclerView, mScrollBarContainerWidth, mScrollBarPosition,
                mScrollBarAboveRecyclerView);

        mScrollBar.setPadding((int) mScrollBarPaddingStart, (int) mScrollBarPaddingEnd);

        if (DEBUG) {
            Log.d(TAG, "started " + mScrollBar.getClass().getSimpleName());
        }
    }

    /**
     * Set the nested view's layout to the specified value.
     *
     * <p>The mGutter is the space to the start/end of the list view items and will be equal in size
     * to
     * the scroll bars. By default, there is a mGutter to both the left and right of the list view
     * items, to account for the scroll bar.
     */
    private void setNestedViewLayout() {
        int startMargin = 0;
        int endMargin = 0;
        if ((mGutter & Gutter.START) != 0) {
            startMargin = mGutterSize;
        }
        if ((mGutter & Gutter.END) != 0) {
            endMargin = mGutterSize;
        }

        MarginLayoutParams layoutParams =
                (MarginLayoutParams) mNestedRecyclerView.getLayoutParams();

        layoutParams.setMarginStart(startMargin);
        layoutParams.setMarginEnd(endMargin);

        layoutParams.height = LayoutParams.MATCH_PARENT;
        layoutParams.width = super.getLayoutManager().getWidth() - startMargin - endMargin;
        // requestLayout() isn't sufficient because we also need to resolveLayoutParams().
        mNestedRecyclerView.setLayoutParams(layoutParams);

        // If there's a mGutter, set ClipToPadding to false so that CardView's shadow will still
        // appear outside of the padding.
        mNestedRecyclerView.setClipToPadding(startMargin == 0 && endMargin == 0);
    }

    private static RuntimeException andLog(String msg, Throwable t) {
        Log.e(TAG, msg, t);
        throw new RuntimeException(msg, t);
    }

    @Override
    public Parcelable onSaveInstanceState() {
        Parcelable superState = super.onSaveInstanceState();
        SavedState ss = new SavedState(superState, getContext());
        if (mScrollBarEnabled) {
            mNestedRecyclerView.saveHierarchyState(ss.mNestedRecyclerViewState);
        }
        return ss;
    }

    @Override
    public void onRestoreInstanceState(Parcelable state) {
        if (!(state instanceof SavedState)) {
            Log.w(TAG, "onRestoreInstanceState called with an unsupported state");
            super.onRestoreInstanceState(state);
        } else {
            SavedState ss = (SavedState) state;
            super.onRestoreInstanceState(ss.getSuperState());
            if (mScrollBarEnabled) {
                mNestedRecyclerView.restoreHierarchyState(ss.mNestedRecyclerViewState);
            }
        }
    }

    static class SavedState extends BaseSavedState {
        SparseArray<Parcelable> mNestedRecyclerViewState;
        Context mContext;

        SavedState(Parcelable superState, Context c) {
            super(superState);
            mContext = c;
            mNestedRecyclerViewState = new SparseArray<>();
        }

        @SuppressWarnings("unchecked")
        private SavedState(Parcel in) {
            super(in);
            mNestedRecyclerViewState = in.readSparseArray(mContext.getClassLoader());
        }

        @SuppressWarnings("unchecked")
        @Override
        public void writeToParcel(Parcel out, int flags) {
            super.writeToParcel(out, flags);
            out.writeSparseArray((SparseArray<Object>) (Object) mNestedRecyclerViewState);
        }

        public static final Parcelable.Creator<SavedState> CREATOR =
                new Parcelable.Creator<SavedState>() {
                    @Override
                    public SavedState createFromParcel(Parcel in) {
                        return new SavedState(in);
                    }

                    @Override
                    public SavedState[] newArray(int size) {
                        return new SavedState[size];
                    }
                };
    }
}
