/*
 * Copyright (C) 2017 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.wallpaper.picker.individual;

import static com.android.wallpaper.picker.WallpaperPickerDelegate.PREVIEW_WALLPAPER_REQUEST_CODE;
import static com.android.wallpaper.widget.BottomActionBar.BottomAction.APPLY;
import static com.android.wallpaper.widget.BottomActionBar.BottomAction.EDIT;
import static com.android.wallpaper.widget.BottomActionBar.BottomAction.INFORMATION;
import static com.android.wallpaper.widget.BottomActionBar.BottomAction.ROTATION;

import android.app.Activity;
import android.app.ProgressDialog;
import android.app.WallpaperManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources.NotFoundException;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.Handler;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.widget.ContentLoadingProgressBar;
import androidx.fragment.app.DialogFragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.OnScrollListener;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;

import com.android.wallpaper.R;
import com.android.wallpaper.asset.Asset;
import com.android.wallpaper.asset.Asset.DrawableLoadedListener;
import com.android.wallpaper.model.Category;
import com.android.wallpaper.model.CategoryProvider;
import com.android.wallpaper.model.CategoryReceiver;
import com.android.wallpaper.model.LiveWallpaperInfo;
import com.android.wallpaper.model.WallpaperCategory;
import com.android.wallpaper.model.WallpaperInfo;
import com.android.wallpaper.model.WallpaperReceiver;
import com.android.wallpaper.model.WallpaperRotationInitializer;
import com.android.wallpaper.model.WallpaperRotationInitializer.Listener;
import com.android.wallpaper.model.WallpaperRotationInitializer.NetworkPreference;
import com.android.wallpaper.module.FormFactorChecker;
import com.android.wallpaper.module.FormFactorChecker.FormFactor;
import com.android.wallpaper.module.Injector;
import com.android.wallpaper.module.InjectorProvider;
import com.android.wallpaper.module.PackageStatusNotifier;
import com.android.wallpaper.module.UserEventLogger;
import com.android.wallpaper.module.WallpaperChangedNotifier;
import com.android.wallpaper.module.WallpaperPersister;
import com.android.wallpaper.module.WallpaperPersister.Destination;
import com.android.wallpaper.module.WallpaperPreferences;
import com.android.wallpaper.module.WallpaperSetter;
import com.android.wallpaper.picker.BaseActivity;
import com.android.wallpaper.picker.BottomActionBarFragment;
import com.android.wallpaper.picker.CurrentWallpaperBottomSheetPresenter;
import com.android.wallpaper.picker.MyPhotosStarter.MyPhotosStarterProvider;
import com.android.wallpaper.picker.PreviewActivity;
import com.android.wallpaper.picker.RotationStarter;
import com.android.wallpaper.picker.SetWallpaperDialogFragment;
import com.android.wallpaper.picker.SetWallpaperErrorDialogFragment;
import com.android.wallpaper.picker.StartRotationDialogFragment;
import com.android.wallpaper.picker.StartRotationErrorDialogFragment;
import com.android.wallpaper.picker.WallpaperInfoHelper;
import com.android.wallpaper.picker.WallpapersUiContainer;
import com.android.wallpaper.picker.individual.SetIndividualHolder.OnSetListener;
import com.android.wallpaper.util.DiskBasedLogger;
import com.android.wallpaper.util.SizeCalculator;
import com.android.wallpaper.widget.BottomActionBar;
import com.android.wallpaper.widget.WallpaperInfoView;
import com.android.wallpaper.widget.WallpaperPickerRecyclerViewAccessibilityDelegate;
import com.android.wallpaper.widget.WallpaperPickerRecyclerViewAccessibilityDelegate.BottomSheetHost;

import com.bumptech.glide.Glide;
import com.bumptech.glide.MemoryCategory;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.Random;

/**
 * Displays the Main UI for picking an individual wallpaper image.
 */
public class IndividualPickerFragment extends BottomActionBarFragment
        implements RotationStarter, StartRotationErrorDialogFragment.Listener,
        CurrentWallpaperBottomSheetPresenter.RefreshListener,
        SetWallpaperErrorDialogFragment.Listener, SetWallpaperDialogFragment.Listener,
        StartRotationDialogFragment.Listener {

    /**
     * Position of a special tile that doesn't belong to an individual wallpaper of the category,
     * such as "my photos" or "daily rotation".
     */
    static final int SPECIAL_FIXED_TILE_ADAPTER_POSITION = 0;
    static final String ARG_CATEGORY_COLLECTION_ID = "category_collection_id";

    private static final String TAG = "IndividualPickerFrgmnt";
    private static final int UNUSED_REQUEST_CODE = 1;
    private static final String TAG_START_ROTATION_DIALOG = "start_rotation_dialog";
    private static final String TAG_START_ROTATION_ERROR_DIALOG = "start_rotation_error_dialog";
    private static final String PROGRESS_DIALOG_NO_TITLE = null;
    private static final boolean PROGRESS_DIALOG_INDETERMINATE = true;
    private static final String TAG_SET_WALLPAPER_ERROR_DIALOG_FRAGMENT =
            "individual_set_wallpaper_error_dialog";
    private static final String KEY_NIGHT_MODE = "IndividualPickerFragment.NIGHT_MODE";

    /**
     * An interface for updating the thumbnail with the specific wallpaper.
     */
    public interface ThumbnailUpdater {
        /**
         * Updates the thumbnail with the specific wallpaper.
         */
        void updateThumbnail(WallpaperInfo wallpaperInfo);

        /**
         * Restores to the thumbnails of the wallpapers which were applied.
         */
        void restoreThumbnails();
    }

    /**
     * An interface for receiving the destination of the new applied wallpaper.
     */
    public interface WallpaperDestinationCallback {
        /**
         * Called when the destination of the wallpaper is set.
         *
         * @param destination the destination which a wallpaper may be set.
         *                    See {@link Destination} for more details.
         */
        void onDestinationSet(@Destination int destination);
    }

    /**
     * The listener which will be notified when the wallpaper is selected.
     */
    public interface WallpaperSelectedListener {
        /**
         * Called when the wallpaper is selected.
         *
         * @param position the position of the selected wallpaper
         */
        void onWallpaperSelected(int position);
    }

    /**
     * Interface to be implemented by a Fragment hosting a {@link IndividualPickerFragment}
     */
    public interface IndividualPickerFragmentHost {
        /**
         * Sets the title in the toolbar.
         */
        void setToolbarTitle(CharSequence title);

        /**
         * Moves to the previous fragment.
         */
        void moveToPreviousFragment();
    }

    WallpaperPersister mWallpaperPersister;
    WallpaperPreferences mWallpaperPreferences;
    WallpaperChangedNotifier mWallpaperChangedNotifier;
    RecyclerView mImageGrid;
    IndividualAdapter mAdapter;
    WallpaperCategory mCategory;
    WallpaperRotationInitializer mWallpaperRotationInitializer;
    List<WallpaperInfo> mWallpapers;
    Point mTileSizePx;
    WallpapersUiContainer mWallpapersUiContainer;
    @FormFactor
    int mFormFactor;
    PackageStatusNotifier mPackageStatusNotifier;

    Handler mHandler;
    Random mRandom;
    boolean mIsWallpapersReceived;

    WallpaperChangedNotifier.Listener mWallpaperChangedListener =
            new WallpaperChangedNotifier.Listener() {
        @Override
        public void onWallpaperChanged() {
            if (mFormFactor != FormFactorChecker.FORM_FACTOR_DESKTOP) {
                return;
            }

            ViewHolder selectedViewHolder = mImageGrid.findViewHolderForAdapterPosition(
                    mAdapter.mSelectedAdapterPosition);

            // Null remote ID => My Photos wallpaper, so deselect whatever was previously selected.
            if (mWallpaperPreferences.getHomeWallpaperRemoteId() == null) {
                if (selectedViewHolder instanceof SelectableHolder) {
                    ((SelectableHolder) selectedViewHolder).setSelectionState(
                            SelectableHolder.SELECTION_STATE_DESELECTED);
                }
            } else {
                mAdapter.updateSelectedTile(mAdapter.mPendingSelectedAdapterPosition);
            }
        }
    };
    PackageStatusNotifier.Listener mAppStatusListener;
    BottomActionBar mBottomActionBar;
    WallpaperInfoView mWallpaperInfoView;
    @Nullable WallpaperInfo mSelectedWallpaperInfo;

    private UserEventLogger mUserEventLogger;
    private ProgressDialog mProgressDialog;
    private boolean mTestingMode;
    private CurrentWallpaperBottomSheetPresenter mCurrentWallpaperBottomSheetPresenter;
    private SetIndividualHolder mPendingSetIndividualHolder;
    private ContentLoadingProgressBar mLoading;

    /**
     * Staged error dialog fragments that were unable to be shown when the activity didn't allow
     * committing fragment transactions.
     */
    private SetWallpaperErrorDialogFragment mStagedSetWallpaperErrorDialogFragment;
    private StartRotationErrorDialogFragment mStagedStartRotationErrorDialogFragment;

    private Runnable mCurrentWallpaperBottomSheetExpandedRunnable;

    /**
     * Whether {@code mUpdateDailyWallpaperThumbRunnable} has been run at least once in this
     * invocation of the fragment.
     */
    private boolean mWasUpdateRunnableRun;

    /**
     * A Runnable which regularly updates the thumbnail for the "Daily wallpapers" tile in desktop
     * mode.
     */
    private Runnable mUpdateDailyWallpaperThumbRunnable = new Runnable() {
        @Override
        public void run() {
            ViewHolder viewHolder = mImageGrid.findViewHolderForAdapterPosition(
                    SPECIAL_FIXED_TILE_ADAPTER_POSITION);
            if (viewHolder instanceof DesktopRotationHolder) {
                updateDesktopDailyRotationThumbnail((DesktopRotationHolder) viewHolder);
            } else { // viewHolder is null
                // If the rotation tile is unavailable (because user has scrolled down, causing the
                // ViewHolder to be recycled), schedule the update for some time later. Once user scrolls up
                // again, the ViewHolder will be re-bound and its thumbnail will be updated.
                mHandler.postDelayed(mUpdateDailyWallpaperThumbRunnable,
                        DesktopRotationHolder.CROSSFADE_DURATION_MILLIS
                                + DesktopRotationHolder.CROSSFADE_DURATION_PAUSE_MILLIS);
            }
        }
    };

    private WallpaperSetter mWallpaperSetter;
    private WallpaperInfo mAppliedWallpaperInfo;
    private WallpaperManager mWallpaperManager;
    private int mWallpaperDestination;
    private WallpaperSelectedListener mWallpaperSelectedListener;

    public static IndividualPickerFragment newInstance(String collectionId) {
        Bundle args = new Bundle();
        args.putString(ARG_CATEGORY_COLLECTION_ID, collectionId);

        IndividualPickerFragment fragment = new IndividualPickerFragment();
        fragment.setArguments(args);
        return fragment;
    }

    /**
     * Highlights the applied wallpaper (if it exists) according to the destination a wallpaper
     * would be set.
     *
     * @param wallpaperDestination the destination a wallpaper would be set.
     *                             It will be either {@link Destination#DEST_HOME_SCREEN}
     *                             or {@link Destination#DEST_LOCK_SCREEN}.
     */
    public void highlightAppliedWallpaper(@Destination int wallpaperDestination) {
        mWallpaperDestination = wallpaperDestination;
        if (mWallpapers != null) {
            refreshAppliedWallpaper();
        }
    }

    private void updateDesktopDailyRotationThumbnail(DesktopRotationHolder holder) {
        int wallpapersIndex = mRandom.nextInt(mWallpapers.size());
        Asset newThumbnailAsset = mWallpapers.get(wallpapersIndex).getThumbAsset(
                getActivity());
        holder.updateThumbnail(newThumbnailAsset, new DrawableLoadedListener() {
            @Override
            public void onDrawableLoaded() {
                if (getActivity() == null) {
                    return;
                }

                // Schedule the next update of the thumbnail.
                int delayMillis = DesktopRotationHolder.CROSSFADE_DURATION_MILLIS
                        + DesktopRotationHolder.CROSSFADE_DURATION_PAUSE_MILLIS;
                mHandler.postDelayed(mUpdateDailyWallpaperThumbRunnable, delayMillis);
            }
        });
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Injector injector = InjectorProvider.getInjector();
        Context appContext = getContext().getApplicationContext();
        mWallpaperPreferences = injector.getPreferences(appContext);

        mWallpaperChangedNotifier = WallpaperChangedNotifier.getInstance();
        mWallpaperChangedNotifier.registerListener(mWallpaperChangedListener);

        mWallpaperManager = WallpaperManager.getInstance(appContext);

        mFormFactor = injector.getFormFactorChecker(appContext).getFormFactor();

        mPackageStatusNotifier = injector.getPackageStatusNotifier(appContext);

        mUserEventLogger = injector.getUserEventLogger(appContext);

        mWallpaperPersister = injector.getWallpaperPersister(appContext);
        mWallpaperSetter = new WallpaperSetter(
                mWallpaperPersister,
                injector.getPreferences(appContext),
                injector.getUserEventLogger(appContext),
                false);

        mWallpapers = new ArrayList<>();
        mRandom = new Random();
        mHandler = new Handler();

        // Clear Glide's cache if night-mode changed to ensure thumbnails are reloaded
        if (savedInstanceState != null && (savedInstanceState.getInt(KEY_NIGHT_MODE)
                != (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK))) {
            Glide.get(getContext()).clearMemory();
        }

        CategoryProvider categoryProvider = injector.getCategoryProvider(appContext);
        categoryProvider.fetchCategories(new CategoryReceiver() {
            @Override
            public void onCategoryReceived(Category category) {
                // Do nothing.
            }

            @Override
            public void doneFetchingCategories() {
                mCategory = (WallpaperCategory) categoryProvider.getCategory(
                        getArguments().getString(ARG_CATEGORY_COLLECTION_ID));
                if (mCategory == null) {
                    DiskBasedLogger.e(TAG, "Failed to find the category.", getContext());

                    // The absence of this category in the CategoryProvider indicates a broken
                    // state, see b/38030129. Hence, finish the activity and return.
                    getIndividualPickerFragmentHost().moveToPreviousFragment();
                    Toast.makeText(getContext(), R.string.collection_not_exist_msg,
                            Toast.LENGTH_SHORT).show();
                    return;
                }
                onCategoryLoaded();
            }
        }, false);
    }


    protected void onCategoryLoaded() {
        getIndividualPickerFragmentHost().setToolbarTitle(mCategory.getTitle());
        mWallpaperRotationInitializer = mCategory.getWallpaperRotationInitializer();
        // Avoids the "rotation" action is not shown correctly
        // in a rare case : onCategoryLoaded() is called after onBottomActionBarReady().
        if (isRotationEnabled() && mBottomActionBar != null
                && !mBottomActionBar.areActionsShown(ROTATION)) {
            mBottomActionBar.showActions(ROTATION);
        }
        fetchWallpapers(false);

        if (mCategory.supportsThirdParty()) {
            mAppStatusListener = (packageName, status) -> {
                if (status != PackageStatusNotifier.PackageStatus.REMOVED ||
                        mCategory.containsThirdParty(packageName)) {
                    fetchWallpapers(true);
                }
            };
            mPackageStatusNotifier.addListener(mAppStatusListener,
                    WallpaperService.SERVICE_INTERFACE);
        }

        maybeSetUpImageGrid();
    }

    void fetchWallpapers(boolean forceReload) {
        mWallpapers.clear();
        mIsWallpapersReceived = false;
        updateLoading();
        mCategory.fetchWallpapers(getActivity().getApplicationContext(), new WallpaperReceiver() {
            @Override
            public void onWallpapersReceived(List<WallpaperInfo> wallpapers) {
                mIsWallpapersReceived = true;
                updateLoading();
                for (WallpaperInfo wallpaper : wallpapers) {
                    mWallpapers.add(wallpaper);
                }

                // Wallpapers may load after the adapter is initialized, in which case we have
                // to explicitly notify that the data set has changed.
                if (mAdapter != null) {
                    mAdapter.notifyDataSetChanged();
                }

                if (mWallpapersUiContainer != null) {
                    mWallpapersUiContainer.onWallpapersReady();
                } else {
                    if (wallpapers.isEmpty()) {
                        // If there are no more wallpapers and we're on phone, just finish the
                        // Activity.
                        Activity activity = getActivity();
                        if (activity != null
                                && mFormFactor == FormFactorChecker.FORM_FACTOR_MOBILE) {
                            activity.finish();
                        }
                    }
                }
            }
        }, forceReload);
    }

    void updateLoading() {
        if (mLoading == null) {
            return;
        }

        if (mIsWallpapersReceived) {
            mLoading.hide();
        } else {
            mLoading.show();
        }
    }

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt(KEY_NIGHT_MODE,
                getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_individual_picker, container, false);

        mTileSizePx = SizeCalculator.getIndividualTileSize(getActivity());

        mImageGrid = (RecyclerView) view.findViewById(R.id.wallpaper_grid);
        if (mFormFactor == FormFactorChecker.FORM_FACTOR_DESKTOP) {
            int gridPaddingPx = getResources().getDimensionPixelSize(R.dimen.grid_padding_desktop);
            updateImageGridPadding(false /* addExtraBottomSpace */);
            mImageGrid.setScrollBarSize(gridPaddingPx);
        }
        mImageGrid.addItemDecoration(new GridPaddingDecoration(
                getResources().getDimensionPixelSize(R.dimen.grid_padding)));
        mImageGrid.setAccessibilityDelegateCompat(
                new WallpaperPickerRecyclerViewAccessibilityDelegate(
                        mImageGrid, (BottomSheetHost) getParentFragment(), getNumColumns()));
        mLoading = view.findViewById(R.id.loading_indicator);
        updateLoading();
        maybeSetUpImageGrid();
        setUpBottomSheet();
        return view;
    }

    @Override
    public void onClickTryAgain(@Destination int unused) {
        if (mPendingSetIndividualHolder != null) {
            mPendingSetIndividualHolder.setWallpaper();
        }
    }

    void updateImageGridPadding(boolean addExtraBottomSpace) {
        int gridPaddingPx = getResources().getDimensionPixelSize(R.dimen.grid_padding_desktop);
        int bottomSheetHeightPx = getResources().getDimensionPixelSize(
                R.dimen.current_wallpaper_bottom_sheet_layout_height);
        int paddingBottomPx = addExtraBottomSpace ? bottomSheetHeightPx : 0;
        // Only left and top may be set in order for the GridMarginDecoration to work properly.
        mImageGrid.setPadding(
                gridPaddingPx, gridPaddingPx, 0, paddingBottomPx);
    }

    private IndividualPickerFragmentHost getIndividualPickerFragmentHost() {
        return (IndividualPickerFragmentHost) getParentFragment();
    }

    private void maybeSetUpImageGrid() {
        // Skip if mImageGrid been initialized yet
        if (mImageGrid == null) {
            return;
        }
        // Skip if category hasn't loaded yet
        if (mCategory == null) {
            return;
        }
        // Skip if the adapter was already created
        if (mAdapter != null) {
            return;
        }
        setUpImageGrid();
    }

    /**
     * Create the adapter and assign it to mImageGrid.
     * Both mImageGrid and mCategory are guaranteed to not be null when this method is called.
     */
    void setUpImageGrid() {
        mAdapter = new IndividualAdapter(mWallpapers);
        mImageGrid.setAdapter(mAdapter);
        mImageGrid.setLayoutManager(new GridLayoutManager(getActivity(), getNumColumns()));
    }

    /**
     * Enables and populates the "Currently set" wallpaper BottomSheet.
     */
    void setUpBottomSheet() {
        mImageGrid.addOnScrollListener(new OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, final int dy) {
                if (mCurrentWallpaperBottomSheetPresenter == null) {
                    return;
                }

                if (mCurrentWallpaperBottomSheetExpandedRunnable != null) {
                    mHandler.removeCallbacks(mCurrentWallpaperBottomSheetExpandedRunnable);
                }
                mCurrentWallpaperBottomSheetExpandedRunnable = new Runnable() {
                    @Override
                    public void run() {
                        if (dy > 0) {
                            mCurrentWallpaperBottomSheetPresenter.setCurrentWallpapersExpanded(false);
                        } else {
                            mCurrentWallpaperBottomSheetPresenter.setCurrentWallpapersExpanded(true);
                        }
                    }
                };
                mHandler.postDelayed(mCurrentWallpaperBottomSheetExpandedRunnable, 100);
            }
        });
    }

    @Override
    protected void onBottomActionBarReady(BottomActionBar bottomActionBar) {
        mBottomActionBar = bottomActionBar;
        if (isRotationEnabled()) {
            mBottomActionBar.showActionsOnly(ROTATION);
        }
        mBottomActionBar.setActionClickListener(ROTATION, unused -> {
            DialogFragment startRotationDialogFragment = new StartRotationDialogFragment();
            startRotationDialogFragment.setTargetFragment(
                    IndividualPickerFragment.this, UNUSED_REQUEST_CODE);
            startRotationDialogFragment.show(getFragmentManager(), TAG_START_ROTATION_DIALOG);
        });
        mBottomActionBar.setActionClickListener(APPLY, unused -> {
            mBottomActionBar.disableActions();
            mWallpaperSetter.requestDestination(getActivity(), getFragmentManager(), this,
                    mSelectedWallpaperInfo instanceof LiveWallpaperInfo);
        });

        mWallpaperInfoView = (WallpaperInfoView) LayoutInflater.from(getContext())
                .inflate(R.layout.wallpaper_info_view, /* root= */ null);
        mBottomActionBar.attachViewToBottomSheetAndBindAction(mWallpaperInfoView, INFORMATION);
        mBottomActionBar.setActionClickListener(EDIT, unused -> {
            mWallpaperPersister.setWallpaperInfoInPreview(mSelectedWallpaperInfo);
            mSelectedWallpaperInfo.showPreview(getActivity(),
                    new PreviewActivity.PreviewActivityIntentFactory(),
                    PREVIEW_WALLPAPER_REQUEST_CODE);
        });
        mBottomActionBar.show();
    }

    @Override
    public void onResume() {
        super.onResume();

        WallpaperPreferences preferences = InjectorProvider.getInjector()
                .getPreferences(getActivity());
        preferences.setLastAppActiveTimestamp(new Date().getTime());

        // Reset Glide memory settings to a "normal" level of usage since it may have been lowered in
        // PreviewFragment.
        Glide.get(getActivity()).setMemoryCategory(MemoryCategory.NORMAL);

        // Show the staged 'start rotation' error dialog fragment if there is one that was unable to be
        // shown earlier when this fragment's hosting activity didn't allow committing fragment
        // transactions.
        if (mStagedStartRotationErrorDialogFragment != null) {
            mStagedStartRotationErrorDialogFragment.show(
                    getFragmentManager(), TAG_START_ROTATION_ERROR_DIALOG);
            mStagedStartRotationErrorDialogFragment = null;
        }

        // Show the staged 'load wallpaper' or 'set wallpaper' error dialog fragments if there is one
        // that was unable to be shown earlier when this fragment's hosting activity didn't allow
        // committing fragment transactions.
        if (mStagedSetWallpaperErrorDialogFragment != null) {
            mStagedSetWallpaperErrorDialogFragment.show(
                    getFragmentManager(), TAG_SET_WALLPAPER_ERROR_DIALOG_FRAGMENT);
            mStagedSetWallpaperErrorDialogFragment = null;
        }

        if (shouldShowRotationTile() && mWasUpdateRunnableRun && !mWallpapers.isEmpty()) {
            // Must be resuming from a previously stopped state, so re-schedule the update of the
            // daily wallpapers tile thumbnail.
            mUpdateDailyWallpaperThumbRunnable.run();
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        mHandler.removeCallbacks(mUpdateDailyWallpaperThumbRunnable);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mProgressDialog != null) {
            mProgressDialog.dismiss();
        }
        mWallpaperChangedNotifier.unregisterListener(mWallpaperChangedListener);
        if (mAppStatusListener != null) {
            mPackageStatusNotifier.removeListener(mAppStatusListener);
        }
        mWallpaperSetter.cleanUp();
    }

    @Override
    public void onStartRotationDialogDismiss(@NonNull DialogInterface dialog) {
        // TODO(b/159310028): Refactor fragment layer to make it able to restore from config change.
        // This is to handle config change with StartRotationDialog popup,  the StartRotationDialog
        // still holds a reference to the destroyed Fragment and is calling
        // onStartRotationDialogDismissed on that destroyed Fragment.
        if (mBottomActionBar != null) {
            mBottomActionBar.deselectAction(ROTATION);
        }
    }

    @Override
    public void retryStartRotation(@NetworkPreference int networkPreference) {
        startRotation(networkPreference);
    }

    @Override
    public boolean onBackPressed() {
        if (mSelectedWallpaperInfo != null) {
            onWallpaperSelected(null, 0);
            return true;
        }
        return false;
    }

    public void setCurrentWallpaperBottomSheetPresenter(
            CurrentWallpaperBottomSheetPresenter presenter) {
        mCurrentWallpaperBottomSheetPresenter = presenter;
    }

    public void setWallpapersUiContainer(WallpapersUiContainer uiContainer) {
        mWallpapersUiContainer = uiContainer;
    }

    public void setOnWallpaperSelectedListener(
            WallpaperSelectedListener wallpaperSelectedListener) {
        mWallpaperSelectedListener = wallpaperSelectedListener;
    }

    /**
     * Resizes the layout's height.
     */
    public void resizeLayout(int height) {
        mImageGrid.getLayoutParams().height = height;
        mImageGrid.requestLayout();
    }

    /**
     * Scrolls to the specific item.
     *
     * @param position the position of the item
     */
    public void scrollToPosition(int position) {
        ((GridLayoutManager) mImageGrid.getLayoutManager())
                .scrollToPositionWithOffset(position, /* offset= */ 0);
    }

    /**
     * Enable a test mode of operation -- in which certain UI features are disabled to allow for
     * UI tests to run correctly. Works around issue in ProgressDialog currently where the dialog
     * constantly keeps the UI thread alive and blocks a test forever.
     *
     * @param testingMode
     */
    void setTestingMode(boolean testingMode) {
        mTestingMode = testingMode;
    }

    @Override
    public void startRotation(@NetworkPreference final int networkPreference) {
        if (!isRotationEnabled()) {
            Log.e(TAG, "Rotation is not enabled for this category " + mCategory.getTitle());
            return;
        }

        // ProgressDialog endlessly updates the UI thread, keeping it from going idle which therefore
        // causes Espresso to hang once the dialog is shown.
        if (mFormFactor == FormFactorChecker.FORM_FACTOR_MOBILE && !mTestingMode) {
            int themeResId;
            if (VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) {
                themeResId = R.style.ProgressDialogThemePreL;
            } else {
                themeResId = R.style.LightDialogTheme;
            }
            mProgressDialog = new ProgressDialog(getActivity(), themeResId);

            mProgressDialog.setTitle(PROGRESS_DIALOG_NO_TITLE);
            mProgressDialog.setMessage(
                    getResources().getString(R.string.start_rotation_progress_message));
            mProgressDialog.setIndeterminate(PROGRESS_DIALOG_INDETERMINATE);
            mProgressDialog.show();
        }

        if (mFormFactor == FormFactorChecker.FORM_FACTOR_DESKTOP) {
            mAdapter.mPendingSelectedAdapterPosition = SPECIAL_FIXED_TILE_ADAPTER_POSITION;
        }

        final Context appContext = getActivity().getApplicationContext();

        mWallpaperRotationInitializer.setFirstWallpaperInRotation(
                appContext,
                networkPreference,
                new Listener() {
                    @Override
                    public void onFirstWallpaperInRotationSet() {
                        if (mProgressDialog != null) {
                            mProgressDialog.dismiss();
                        }

                        // The fragment may be detached from its containing activity if the user exits the
                        // app before the first wallpaper image in rotation finishes downloading.
                        Activity activity = getActivity();


                        if (mWallpaperRotationInitializer.startRotation(appContext)) {
                            if (activity != null
                                    && mFormFactor == FormFactorChecker.FORM_FACTOR_MOBILE) {
                                try {
                                    Toast.makeText(getActivity(),
                                            R.string.wallpaper_set_successfully_message,
                                            Toast.LENGTH_SHORT).show();
                                } catch (NotFoundException e) {
                                    Log.e(TAG, "Could not show toast " + e);
                                }

                                activity.setResult(Activity.RESULT_OK);
                                activity.finish();
                            } else if (mFormFactor == FormFactorChecker.FORM_FACTOR_DESKTOP) {
                                mAdapter.updateSelectedTile(SPECIAL_FIXED_TILE_ADAPTER_POSITION);
                            }
                        } else { // Failed to start rotation.
                            showStartRotationErrorDialog(networkPreference);

                            if (mFormFactor == FormFactorChecker.FORM_FACTOR_DESKTOP) {
                                DesktopRotationHolder rotationViewHolder =
                                        (DesktopRotationHolder)
                                                mImageGrid.findViewHolderForAdapterPosition(
                                                SPECIAL_FIXED_TILE_ADAPTER_POSITION);
                                rotationViewHolder.setSelectionState(
                                        SelectableHolder.SELECTION_STATE_DESELECTED);
                            }
                        }
                    }

                    @Override
                    public void onError() {
                        if (mProgressDialog != null) {
                            mProgressDialog.dismiss();
                        }

                        showStartRotationErrorDialog(networkPreference);

                        if (mFormFactor == FormFactorChecker.FORM_FACTOR_DESKTOP) {
                            DesktopRotationHolder rotationViewHolder =
                                    (DesktopRotationHolder) mImageGrid.findViewHolderForAdapterPosition(
                                            SPECIAL_FIXED_TILE_ADAPTER_POSITION);
                            rotationViewHolder.setSelectionState(SelectableHolder.SELECTION_STATE_DESELECTED);
                        }
                    }
                });
    }

    private void showStartRotationErrorDialog(@NetworkPreference int networkPreference) {
        BaseActivity activity = (BaseActivity) getActivity();
        if (activity != null) {
            StartRotationErrorDialogFragment startRotationErrorDialogFragment =
                    StartRotationErrorDialogFragment.newInstance(networkPreference);
            startRotationErrorDialogFragment.setTargetFragment(
                    IndividualPickerFragment.this, UNUSED_REQUEST_CODE);

            if (activity.isSafeToCommitFragmentTransaction()) {
                startRotationErrorDialogFragment.show(
                        getFragmentManager(), TAG_START_ROTATION_ERROR_DIALOG);
            } else {
                mStagedStartRotationErrorDialogFragment = startRotationErrorDialogFragment;
            }
        }
    }

    int getNumColumns() {
        Activity activity = getActivity();
        return activity == null ? 1 : SizeCalculator.getNumIndividualColumns(activity);
    }

    /**
     * Returns whether rotation is enabled for this category.
     */
    boolean isRotationEnabled() {
        return mWallpaperRotationInitializer != null;
    }

    @Override
    public void onCurrentWallpaperRefreshed() {
        mCurrentWallpaperBottomSheetPresenter.setCurrentWallpapersExpanded(true);
    }

    @Override
    public void onSet(int destination) {
        if (mSelectedWallpaperInfo == null) {
            Log.e(TAG, "Unable to set wallpaper since the selected wallpaper info is null");
            return;
        }

        mWallpaperPersister.setWallpaperInfoInPreview(mSelectedWallpaperInfo);
        if (mSelectedWallpaperInfo instanceof LiveWallpaperInfo) {
            mWallpaperSetter.setCurrentWallpaper(getActivity(), mSelectedWallpaperInfo, null,
                    destination, 0, null, mSetWallpaperCallback);
        } else {
            mWallpaperSetter.setCurrentWallpaper(
                    getActivity(), mSelectedWallpaperInfo, destination, mSetWallpaperCallback);
        }
        onWallpaperDestinationSet(destination);
    }

    private WallpaperPersister.SetWallpaperCallback mSetWallpaperCallback =
            new WallpaperPersister.SetWallpaperCallback() {
                @Override
                public void onSuccess(WallpaperInfo wallpaperInfo) {
                    mWallpaperPersister.onLiveWallpaperSet();
                    Toast.makeText(getActivity(), R.string.wallpaper_set_successfully_message,
                            Toast.LENGTH_SHORT).show();
                    getActivity().overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
                    getActivity().finish();
                }

                @Override
                public void onError(@Nullable Throwable throwable) {
                    Log.e(TAG, "Can't apply the wallpaper.");
                    mBottomActionBar.enableActions();
                }
            };

    @Override
    public void onDialogDismissed(boolean withItemSelected) {
        if (!withItemSelected) {
            mBottomActionBar.enableActions();
        }
    }

    /**
     * Shows a "set wallpaper" error dialog with a failure message and button to try again.
     */
    private void showSetWallpaperErrorDialog() {
        SetWallpaperErrorDialogFragment dialogFragment = SetWallpaperErrorDialogFragment.newInstance(
                R.string.set_wallpaper_error_message, WallpaperPersister.DEST_BOTH);
        dialogFragment.setTargetFragment(this, UNUSED_REQUEST_CODE);

        if (((BaseActivity) getActivity()).isSafeToCommitFragmentTransaction()) {
            dialogFragment.show(getFragmentManager(), TAG_SET_WALLPAPER_ERROR_DIALOG_FRAGMENT);
        } else {
            mStagedSetWallpaperErrorDialogFragment = dialogFragment;
        }
    }

    void updateBottomActions(boolean hasWallpaperSelected) {
        if (hasWallpaperSelected) {
            mBottomActionBar.showActionsOnly(INFORMATION, EDIT, APPLY);
        } else {
            mBottomActionBar.showActionsOnly(ROTATION);
        }
    }

    private void updateThumbnail(WallpaperInfo selectedWallpaperInfo) {
        ThumbnailUpdater thumbnailUpdater = (ThumbnailUpdater) getParentFragment();
        if (thumbnailUpdater == null) {
            return;
        }

        if (selectedWallpaperInfo != null) {
            thumbnailUpdater.updateThumbnail(selectedWallpaperInfo);
        } else {
            thumbnailUpdater.restoreThumbnails();
        }
    }

    private void onWallpaperDestinationSet(int destination) {
        WallpaperDestinationCallback wallpaperDestinationCallback =
                (WallpaperDestinationCallback) getParentFragment();
        if (wallpaperDestinationCallback == null) {
            return;
        }

        wallpaperDestinationCallback.onDestinationSet(destination);
    }

    void onWallpaperSelected(@Nullable WallpaperInfo newSelectedWallpaperInfo,
                                     int position) {
        if (mSelectedWallpaperInfo == newSelectedWallpaperInfo) {
            return;
        }
        // Update current wallpaper.
        updateActivatedStatus(mSelectedWallpaperInfo == null
                ? mAppliedWallpaperInfo : mSelectedWallpaperInfo, false);
        // Update new selected wallpaper.
        updateActivatedStatus(newSelectedWallpaperInfo == null
                ? mAppliedWallpaperInfo : newSelectedWallpaperInfo, true);

        mSelectedWallpaperInfo = newSelectedWallpaperInfo;
        updateBottomActions(mSelectedWallpaperInfo != null);
        updateThumbnail(mSelectedWallpaperInfo);
        // Populate wallpaper info into view.
        if (mSelectedWallpaperInfo != null && mWallpaperInfoView != null) {
            WallpaperInfoHelper.loadExploreIntent(
                    getContext(),
                    mSelectedWallpaperInfo,
                    (actionLabel, exploreIntent) ->
                            mWallpaperInfoView.populateWallpaperInfo(
                                    mSelectedWallpaperInfo, actionLabel, exploreIntent,
                                    v -> onExploreClicked(exploreIntent)));
        }

        if (mWallpaperSelectedListener != null) {
            mWallpaperSelectedListener.onWallpaperSelected(position);
        }
    }

    private void onExploreClicked(Intent exploreIntent) {
        if (getContext() == null) {
            return;
        }
        Context context = getContext();
        mUserEventLogger.logActionClicked(mSelectedWallpaperInfo.getCollectionId(context),
                mSelectedWallpaperInfo.getActionLabelRes(context));

        startActivity(exploreIntent);
    }

    private void updateActivatedStatus(WallpaperInfo wallpaperInfo, boolean isActivated) {
        if (wallpaperInfo == null) {
            return;
        }
        int index = mWallpapers.indexOf(wallpaperInfo);
        index = (shouldShowRotationTile() || mCategory.supportsCustomPhotos())
                ? index + 1 : index;
        ViewHolder holder = mImageGrid.findViewHolderForAdapterPosition(index);
        if (holder != null) {
            holder.itemView.setActivated(isActivated);
        } else {
            // Item is not visible, make sure the item is re-bound when it becomes visible.
            mAdapter.notifyItemChanged(index);
        }
    }

    private void updateAppliedStatus(WallpaperInfo wallpaperInfo, boolean isApplied) {
        if (wallpaperInfo == null) {
            return;
        }
        int index = mWallpapers.indexOf(wallpaperInfo);
        index = (shouldShowRotationTile() || mCategory.supportsCustomPhotos())
                ? index + 1 : index;
        ViewHolder holder = mImageGrid.findViewHolderForAdapterPosition(index);
        if (holder != null) {
            holder.itemView.findViewById(R.id.check_circle)
                    .setVisibility(isApplied ? View.VISIBLE : View.GONE);
        } else {
            // Item is not visible, make sure the item is re-bound when it becomes visible.
            mAdapter.notifyItemChanged(index);
        }
    }

    private void refreshAppliedWallpaper() {
        // Clear the check mark and blue border(if it shows) of the old applied wallpaper.
        showCheckMarkAndBorderForAppliedWallpaper(false);

        // Update to the new applied wallpaper.
        String appliedWallpaperId = getAppliedWallpaperId();
        Optional<WallpaperInfo> wallpaperInfoOptional = mWallpapers
                .stream()
                .filter(wallpaper -> wallpaper.getWallpaperId() != null)
                .filter(wallpaper -> wallpaper.getWallpaperId().equals(appliedWallpaperId))
                .findFirst();
        mAppliedWallpaperInfo = wallpaperInfoOptional.orElse(null);

        // Set the check mark and blue border(if user doesn't select) of the new applied wallpaper.
        showCheckMarkAndBorderForAppliedWallpaper(true);
    }

    private String getAppliedWallpaperId() {
        WallpaperPreferences prefs =
                InjectorProvider.getInjector().getPreferences(getContext());
        android.app.WallpaperInfo wallpaperInfo = mWallpaperManager.getWallpaperInfo();
        boolean isDestinationBoth =
                mWallpaperManager.getWallpaperId(WallpaperManager.FLAG_LOCK) < 0;

        if (isDestinationBoth || mWallpaperDestination == WallpaperPersister.DEST_HOME_SCREEN) {
            return wallpaperInfo != null
                    ? wallpaperInfo.getServiceName() : prefs.getHomeWallpaperRemoteId();
        } else {
            return prefs.getLockWallpaperRemoteId();
        }
    }

    private void showCheckMarkAndBorderForAppliedWallpaper(boolean show) {
        updateAppliedStatus(mAppliedWallpaperInfo, show);
        if (mSelectedWallpaperInfo == null) {
            updateActivatedStatus(mAppliedWallpaperInfo, show);
        }
    }

    private boolean shouldShowRotationTile() {
        return mFormFactor == FormFactorChecker.FORM_FACTOR_DESKTOP && isRotationEnabled();
    }

    /**
     * RecyclerView Adapter subclass for the wallpaper tiles in the RecyclerView.
     */
    class IndividualAdapter extends RecyclerView.Adapter<ViewHolder> {
        static final int ITEM_VIEW_TYPE_ROTATION = 1;
        static final int ITEM_VIEW_TYPE_INDIVIDUAL_WALLPAPER = 2;
        static final int ITEM_VIEW_TYPE_MY_PHOTOS = 3;

        private final List<WallpaperInfo> mWallpapers;

        private int mPendingSelectedAdapterPosition;
        private int mSelectedAdapterPosition;

        IndividualAdapter(List<WallpaperInfo> wallpapers) {
            mWallpapers = wallpapers;
            mPendingSelectedAdapterPosition = -1;
            mSelectedAdapterPosition = -1;
        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            switch (viewType) {
                case ITEM_VIEW_TYPE_ROTATION:
                    return createRotationHolder(parent);
                case ITEM_VIEW_TYPE_INDIVIDUAL_WALLPAPER:
                    return createIndividualHolder(parent);
                case ITEM_VIEW_TYPE_MY_PHOTOS:
                    return createMyPhotosHolder(parent);
                default:
                    Log.e(TAG, "Unsupported viewType " + viewType + " in IndividualAdapter");
                    return null;
            }
        }

        @Override
        public int getItemViewType(int position) {
            if (shouldShowRotationTile() && position == SPECIAL_FIXED_TILE_ADAPTER_POSITION) {
                return ITEM_VIEW_TYPE_ROTATION;
            }

            // A category cannot have both a "start rotation" tile and a "my photos" tile.
            if (mCategory.supportsCustomPhotos()
                    && !isRotationEnabled()
                    && position == SPECIAL_FIXED_TILE_ADAPTER_POSITION) {
                return ITEM_VIEW_TYPE_MY_PHOTOS;
            }

            return ITEM_VIEW_TYPE_INDIVIDUAL_WALLPAPER;
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            int viewType = getItemViewType(position);

            switch (viewType) {
                case ITEM_VIEW_TYPE_ROTATION:
                    onBindRotationHolder(holder, position);
                    break;
                case ITEM_VIEW_TYPE_INDIVIDUAL_WALLPAPER:
                    onBindIndividualHolder(holder, position);
                    break;
                case ITEM_VIEW_TYPE_MY_PHOTOS:
                    ((MyPhotosViewHolder) holder).bind();
                    break;
                default:
                    Log.e(TAG, "Unsupported viewType " + viewType + " in IndividualAdapter");
            }
        }

        @Override
        public int getItemCount() {
            return (shouldShowRotationTile() || mCategory.supportsCustomPhotos())
                    ? mWallpapers.size() + 1
                    : mWallpapers.size();
        }

        private ViewHolder createRotationHolder(ViewGroup parent) {
            LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
            View view = layoutInflater.inflate(R.layout.grid_item_rotation_desktop, parent, false);
            SelectionAnimator selectionAnimator =
                    new CheckmarkSelectionAnimator(getActivity(), view);
            return new DesktopRotationHolder(getActivity(), mTileSizePx.y, view, selectionAnimator,
                    IndividualPickerFragment.this);
        }

        private ViewHolder createIndividualHolder(ViewGroup parent) {
            LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
            View view = layoutInflater.inflate(R.layout.grid_item_image, parent, false);

            if (mFormFactor == FormFactorChecker.FORM_FACTOR_DESKTOP) {
                SelectionAnimator selectionAnimator =
                        new CheckmarkSelectionAnimator(getActivity(), view);
                return new SetIndividualHolder(
                        getActivity(), mTileSizePx.y, view,
                        selectionAnimator,
                        new OnSetListener() {
                            @Override
                            public void onPendingWallpaperSet(int adapterPosition) {
                                // Deselect and hide loading indicator for any previously pending tile.
                                if (mPendingSelectedAdapterPosition != -1) {
                                    ViewHolder oldViewHolder = mImageGrid.findViewHolderForAdapterPosition(
                                            mPendingSelectedAdapterPosition);
                                    if (oldViewHolder instanceof SelectableHolder) {
                                        ((SelectableHolder) oldViewHolder).setSelectionState(
                                                SelectableHolder.SELECTION_STATE_DESELECTED);
                                    }
                                }

                                if (mSelectedAdapterPosition != -1) {
                                    ViewHolder oldViewHolder = mImageGrid.findViewHolderForAdapterPosition(
                                            mSelectedAdapterPosition);
                                    if (oldViewHolder instanceof SelectableHolder) {
                                        ((SelectableHolder) oldViewHolder).setSelectionState(
                                                SelectableHolder.SELECTION_STATE_DESELECTED);
                                    }
                                }

                                mPendingSelectedAdapterPosition = adapterPosition;
                            }

                            @Override
                            public void onWallpaperSet(int adapterPosition) {
                                // No-op -- UI handles a new wallpaper being set by reacting to the
                                // WallpaperChangedNotifier.
                            }

                            @Override
                            public void onWallpaperSetFailed(SetIndividualHolder holder) {
                                showSetWallpaperErrorDialog();
                                mPendingSetIndividualHolder = holder;
                            }
                        });
            } else { // MOBILE
                return new PreviewIndividualHolder(getActivity(), mTileSizePx.y, view);
            }
        }

        private ViewHolder createMyPhotosHolder(ViewGroup parent) {
            LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
            View view = layoutInflater.inflate(R.layout.grid_item_my_photos, parent, false);

            return new MyPhotosViewHolder(getActivity(),
                    ((MyPhotosStarterProvider) getActivity()).getMyPhotosStarter(),
                    mTileSizePx.y, view);
        }

        /**
         * Marks the tile at the given position as selected with a visual indication. Also updates the
         * "currently selected" BottomSheet to reflect the newly selected tile.
         */
        private void updateSelectedTile(int newlySelectedPosition) {
            // Prevent multiple spinners from appearing with a user tapping several tiles in rapid
            // succession.
            if (mPendingSelectedAdapterPosition == mSelectedAdapterPosition) {
                return;
            }

            if (mCurrentWallpaperBottomSheetPresenter != null) {
                mCurrentWallpaperBottomSheetPresenter.refreshCurrentWallpapers(
                        IndividualPickerFragment.this);

                if (mCurrentWallpaperBottomSheetExpandedRunnable != null) {
                    mHandler.removeCallbacks(mCurrentWallpaperBottomSheetExpandedRunnable);
                }
                mCurrentWallpaperBottomSheetExpandedRunnable = new Runnable() {
                    @Override
                    public void run() {
                        mCurrentWallpaperBottomSheetPresenter.setCurrentWallpapersExpanded(true);
                    }
                };
                mHandler.postDelayed(mCurrentWallpaperBottomSheetExpandedRunnable, 100);
            }

            // User may have switched to another category, thus detaching this fragment, so check here.
            // NOTE: We do this check after updating the current wallpaper BottomSheet so that the update
            // still occurs in the UI after the user selects that other category.
            if (getActivity() == null) {
                return;
            }

            // Update the newly selected wallpaper ViewHolder and the old one so that if
            // selection UI state applies (desktop UI), it is updated.
            if (mSelectedAdapterPosition >= 0) {
                ViewHolder oldViewHolder = mImageGrid.findViewHolderForAdapterPosition(
                        mSelectedAdapterPosition);
                if (oldViewHolder instanceof SelectableHolder) {
                    ((SelectableHolder) oldViewHolder).setSelectionState(
                            SelectableHolder.SELECTION_STATE_DESELECTED);
                }
            }

            // Animate selection of newly selected tile.
            ViewHolder newViewHolder = mImageGrid
                    .findViewHolderForAdapterPosition(newlySelectedPosition);
            if (newViewHolder instanceof SelectableHolder) {
                ((SelectableHolder) newViewHolder).setSelectionState(
                        SelectableHolder.SELECTION_STATE_SELECTED);
            }

            mSelectedAdapterPosition = newlySelectedPosition;

            // If the tile was in the last row of the grid, add space below it so the user can scroll down
            // and up to see the BottomSheet without it fully overlapping the newly selected tile.
            int spanCount = ((GridLayoutManager) mImageGrid.getLayoutManager()).getSpanCount();
            int numRows = (int) Math.ceil((float) getItemCount() / spanCount);
            int rowOfNewlySelectedTile = newlySelectedPosition / spanCount;
            boolean isInLastRow = rowOfNewlySelectedTile == numRows - 1;

            updateImageGridPadding(isInLastRow /* addExtraBottomSpace */);
        }

        void onBindRotationHolder(ViewHolder holder, int position) {
            if (mFormFactor == FormFactorChecker.FORM_FACTOR_DESKTOP) {
                String collectionId = mCategory.getCollectionId();
                ((DesktopRotationHolder) holder).bind(collectionId);

                if (mWallpaperPreferences.getWallpaperPresentationMode()
                        == WallpaperPreferences.PRESENTATION_MODE_ROTATING
                        && collectionId.equals(mWallpaperPreferences.getHomeWallpaperCollectionId())) {
                    mSelectedAdapterPosition = position;
                }

                if (!mWasUpdateRunnableRun && !mWallpapers.isEmpty()) {
                    updateDesktopDailyRotationThumbnail((DesktopRotationHolder) holder);
                    mWasUpdateRunnableRun = true;
                }
            }
        }

        void onBindIndividualHolder(ViewHolder holder, int position) {
            int wallpaperIndex = (shouldShowRotationTile() || mCategory.supportsCustomPhotos())
                    ? position - 1 : position;
            WallpaperInfo wallpaper = mWallpapers.get(wallpaperIndex);
            ((IndividualHolder) holder).bindWallpaper(wallpaper);
            String appliedWallpaperId = getAppliedWallpaperId();
            boolean isWallpaperApplied = wallpaper.getWallpaperId().equals(appliedWallpaperId);
            boolean isWallpaperSelected = wallpaper.equals(mSelectedWallpaperInfo);
            boolean hasUserSelectedWallpaper = mSelectedWallpaperInfo != null;

            if (isWallpaperApplied) {
                mSelectedAdapterPosition = position;
                mAppliedWallpaperInfo = wallpaper;
            }

            holder.itemView.setActivated(
                    (isWallpaperApplied && !hasUserSelectedWallpaper) || isWallpaperSelected);
            holder.itemView.findViewById(R.id.check_circle).setVisibility(
                    isWallpaperApplied ? View.VISIBLE : View.GONE);
        }
    }

    private class GridPaddingDecoration extends RecyclerView.ItemDecoration {

        private int mPadding;

        GridPaddingDecoration(int padding) {
            mPadding = padding;
        }

        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
                                   RecyclerView.State state) {
            int position = parent.getChildAdapterPosition(view);
            if (position >= 0) {
                outRect.left = mPadding;
                outRect.right = mPadding;
            }
        }
    }
}
