/*
 * 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 android.annotation.MenuRes;
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.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;

import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.cardview.widget.CardView;
import androidx.core.widget.ContentLoadingProgressBar;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment;
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.AppbarFragment;
import com.android.wallpaper.picker.BaseActivity;
import com.android.wallpaper.picker.CurrentWallpaperBottomSheetPresenter;
import com.android.wallpaper.picker.FragmentTransactionChecker;
import com.android.wallpaper.picker.MyPhotosStarter.MyPhotosStarterProvider;
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.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;
import java.util.Set;

/**
 * Displays the Main UI for picking an individual wallpaper image.
 */
public class IndividualPickerFragment extends AppbarFragment
        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";

    protected static final int MAX_CAPACITY_IN_FEWER_COLUMN_LAYOUT = 8;

    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(or an Activity) hosting
     * a {@link IndividualPickerFragment}.
     */
    public interface IndividualPickerFragmentHost {
        /**
         * Indicates if the host has toolbar to show the title. If it does, we should set the title
         * there.
         */
        boolean isHostToolbarShown();

        /**
         * Sets the title in the host's toolbar.
         */
        void setToolbarTitle(CharSequence title);

        /**
         * Configures the menu in the toolbar.
         *
         * @param menuResId the resource id of the menu
         */
        void setToolbarMenu(@MenuRes int menuResId);

        /**
         * Removes the menu in the toolbar.
         */
        void removeToolbarMenu();

        /**
         * 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;
    WallpaperInfoView mWallpaperInfoView;
    @Nullable WallpaperInfo mSelectedWallpaperInfo;

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

    /**
     * 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;
    private Set<String> mAppliedWallpaperIds;

    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();
        }

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

            @Override
            public void doneFetchingCategories() {
                Category category = mCategoryProvider.getCategory(
                        getArguments().getString(ARG_CATEGORY_COLLECTION_ID));
                if (category != null && !(category instanceof WallpaperCategory)) {
                    return;
                }
                mCategory = (WallpaperCategory) category;
                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() {
        if (getIndividualPickerFragmentHost() == null) {
            return;
        }
        if (getIndividualPickerFragmentHost().isHostToolbarShown()) {
            getIndividualPickerFragmentHost().setToolbarTitle(mCategory.getTitle());
        } else {
            setTitle(mCategory.getTitle());
        }
        mWallpaperRotationInitializer = mCategory.getWallpaperRotationInitializer();
        if (mToolbar != null && isRotationEnabled()) {
            setUpToolbarMenu(R.menu.individual_picker_menu);
        }
        fetchWallpapers(false);

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

    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);
                }
                maybeSetUpImageGrid();

                // 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);
        if (getIndividualPickerFragmentHost().isHostToolbarShown()) {
            view.findViewById(R.id.header_bar).setVisibility(View.GONE);
            setUpArrowEnabled(/* upArrow= */ true);
            if (isRotationEnabled()) {
                getIndividualPickerFragmentHost().setToolbarMenu(R.menu.individual_picker_menu);
            }
        } else {
            setUpToolbar(view);
            if (isRotationEnabled()) {
                setUpToolbarMenu(R.menu.individual_picker_menu);
            }
            if (mCategory != null) {
                setTitle(mCategory.getTitle());
            }
        }

        mAppliedWallpaperIds = getAppliedWallpaperIds();

        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);
        }
        mLoading = view.findViewById(R.id.loading_indicator);
        updateLoading();
        maybeSetUpImageGrid();
        setUpBottomSheet();
        // For nav bar edge-to-edge effect.
        view.setOnApplyWindowInsetsListener((v, windowInsets) -> {
            // For status bar height.
            v.setPadding(
                    v.getPaddingLeft(),
                    windowInsets.getSystemWindowInsetTop(),
                    v.getPaddingRight(),
                    v.getPaddingBottom());

            View gridView = v.findViewById(R.id.wallpaper_grid);
            gridView.setPadding(
                    gridView.getPaddingLeft(),
                    gridView.getPaddingTop(),
                    gridView.getPaddingRight(),
                    windowInsets.getSystemWindowInsetBottom());
            return windowInsets.consumeSystemWindowInsets();
        });
        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() {
        Fragment parentFragment = getParentFragment();
        if (parentFragment != null) {
            return (IndividualPickerFragmentHost) parentFragment;
        } else {
            return (IndividualPickerFragmentHost) getActivity();
        }
    }

    protected void maybeSetUpImageGrid() {
        // Skip if mImageGrid been initialized yet
        if (mImageGrid == null) {
            return;
        }
        // Skip if category hasn't loaded yet
        if (mCategory == null) {
            return;
        }
        if (getContext() == null) {
            return;
        }

        // Wallpaper count could change, so we may need to change the layout(2 or 3 columns layout)
        GridLayoutManager gridLayoutManager = (GridLayoutManager) mImageGrid.getLayoutManager();
        boolean needUpdateLayout =
                gridLayoutManager != null && gridLayoutManager.getSpanCount() != getNumColumns();

        // Skip if the adapter was already created and don't need to change the layout
        if (mAdapter != null && !needUpdateLayout) {
            return;
        }

        // Clear the old decoration
        int decorationCount = mImageGrid.getItemDecorationCount();
        for (int i = 0; i < decorationCount; i++) {
            mImageGrid.removeItemDecorationAt(i);
        }

        mImageGrid.addItemDecoration(new GridPaddingDecoration(getGridItemPaddingHorizontal(),
                getGridItemPaddingBottom()));
        int edgePadding = getEdgePadding();
        mImageGrid.setPadding(edgePadding, mImageGrid.getPaddingTop(), edgePadding,
                mImageGrid.getPaddingBottom());
        mTileSizePx = isFewerColumnLayout()
                ? SizeCalculator.getFeaturedIndividualTileSize(getActivity())
                : SizeCalculator.getIndividualTileSize(getActivity());
        setUpImageGrid();
        mImageGrid.setAccessibilityDelegateCompat(
                new WallpaperPickerRecyclerViewAccessibilityDelegate(
                        mImageGrid, (BottomSheetHost) getParentFragment(), getNumColumns()));
    }

    boolean isFewerColumnLayout() {
        return mWallpapers != null && mWallpapers.size() <= MAX_CAPACITY_IN_FEWER_COLUMN_LAYOUT;
    }

    private int getGridItemPaddingHorizontal() {
        return isFewerColumnLayout()
                ? getResources().getDimensionPixelSize(
                R.dimen.grid_item_featured_individual_padding_horizontal)
                : getResources().getDimensionPixelSize(
                        R.dimen.grid_item_individual_padding_horizontal);
    }

    private int getGridItemPaddingBottom() {
        return isFewerColumnLayout()
                ? getResources().getDimensionPixelSize(
                R.dimen.grid_item_featured_individual_padding_bottom)
                : getResources().getDimensionPixelSize(R.dimen.grid_item_individual_padding_bottom);
    }

    private int getEdgePadding() {
        return isFewerColumnLayout()
                ? getResources().getDimensionPixelSize(R.dimen.featured_wallpaper_grid_edge_space)
                : getResources().getDimensionPixelSize(R.dimen.wallpaper_grid_edge_space);
    }

    /**
     * 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
    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 onDestroyView() {
        super.onDestroyView();
        getIndividualPickerFragmentHost().removeToolbarMenu();
    }

    @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.
    }

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

    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) {
        FragmentTransactionChecker activity = (FragmentTransactionChecker) 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();
        if (activity == null) {
            return 1;
        }
        return isFewerColumnLayout()
                ? SizeCalculator.getNumFeaturedIndividualColumns(activity)
                : 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, 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.");
                }
            };

    @Override
    public boolean onMenuItemClick(MenuItem item) {
        if (item.getItemId() == R.id.daily_rotation) {
            showRotationDialog();
            return true;
        }
        return super.onMenuItemClick(item);
    }

    /**
     * Popups a daily rotation dialog for the uses to confirm.
     */
    public void showRotationDialog() {
        DialogFragment startRotationDialogFragment = new StartRotationDialogFragment();
        startRotationDialogFragment.setTargetFragment(
                IndividualPickerFragment.this, UNUSED_REQUEST_CODE);
        startRotationDialogFragment.show(getFragmentManager(), TAG_START_ROTATION_DIALOG);
    }

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

    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;
        updateThumbnail(mSelectedWallpaperInfo);
        // Populate wallpaper info into view.
        if (mSelectedWallpaperInfo != null && mWallpaperInfoView != null) {
            WallpaperInfoHelper.loadExploreIntent(
                    getContext(),
                    mSelectedWallpaperInfo,
                    (actionLabel, exploreIntent) ->
                            mWallpaperInfoView.populateWallpaperInfo(
                                    mSelectedWallpaperInfo,
                                    actionLabel,
                                    WallpaperInfoHelper.shouldShowExploreButton(
                                            getContext(), 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);
    }

    // TODO: Dead code. Should remove this method in the future.
    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);
        }
    }

    // TODO: Dead code. Should remove this method in the future.
    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) {
            mAdapter.showBadge(holder, R.drawable.wallpaper_check_circle_24dp, isApplied);
        } 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 Set<String> getAppliedWallpaperIds() {
        WallpaperPreferences prefs =
                InjectorProvider.getInjector().getPreferences(getContext());
        android.app.WallpaperInfo wallpaperInfo = mWallpaperManager.getWallpaperInfo();
        Set<String> appliedWallpaperIds = new ArraySet<>();

        String homeWallpaperId = wallpaperInfo != null ? wallpaperInfo.getServiceName()
                : prefs.getHomeWallpaperRemoteId();
        if (!TextUtils.isEmpty(homeWallpaperId)) {
            appliedWallpaperIds.add(homeWallpaperId);
        }

        boolean isLockWallpaperApplied =
                mWallpaperManager.getWallpaperId(WallpaperManager.FLAG_LOCK) >= 0;
        String lockWallpaperId = prefs.getLockWallpaperRemoteId();
        if (isLockWallpaperApplied && !TextUtils.isEmpty(lockWallpaperId)) {
            appliedWallpaperIds.add(lockWallpaperId);
        }

        return appliedWallpaperIds;
    }

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

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

    class EmptySelectionAnimator implements SelectionAnimator{
        EmptySelectionAnimator() {}

        public boolean isSelected() {
            return false;
        }

        /**
         * Sets the UI to selected immediately with no animation.
         */
        public void selectImmediately() {}

        /**
         * Sets the UI to deselected immediately with no animation.
         */
        public void deselectImmediately() {}

        /**
         * Sets the UI to selected with a smooth animation.
         */
        public void animateSelected() {}

        /**
         * Sets the UI to deselected with a smooth animation.
         */
        public void animateDeselected() {}

        /**
         * Sets the UI to show a loading indicator.
         */
        public void showLoading() {}

        /**
         * Sets the UI to hide the loading indicator.
         */
        public void showNotLoading() {}

    }

    /**
     * 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 EmptySelectionAnimator();
            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 EmptySelectionAnimator();
                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);
            wallpaper.computePlaceholderColor(holder.itemView.getContext());
            ((IndividualHolder) holder).bindWallpaper(wallpaper);
            boolean isWallpaperApplied = isWallpaperApplied(wallpaper);

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

            CardView container = holder.itemView.findViewById(R.id.wallpaper_container);
            int radiusId = isFewerColumnLayout() ? R.dimen.grid_item_all_radius
                    : R.dimen.grid_item_all_radius_small;
            container.setRadius(getResources().getDimension(radiusId));
            showBadge(holder, R.drawable.wallpaper_check_circle_24dp, isWallpaperApplied);
        }

        protected boolean isWallpaperApplied(WallpaperInfo wallpaper) {
            return mAppliedWallpaperIds.contains(wallpaper.getWallpaperId());
        }

        protected void showBadge(ViewHolder holder, @DrawableRes int icon, boolean show) {
            ImageView badge = holder.itemView.findViewById(R.id.indicator_icon);
            if (show) {
                final float margin = isFewerColumnLayout() ? getResources().getDimension(
                        R.dimen.grid_item_badge_margin) : getResources().getDimension(
                        R.dimen.grid_item_badge_margin_small);
                final RelativeLayout.LayoutParams layoutParams =
                        (RelativeLayout.LayoutParams) badge.getLayoutParams();
                layoutParams.setMargins(/* left= */ (int) margin, /* top= */ (int) margin,
                        /* right= */ (int) margin, /* bottom= */ (int) margin);
                badge.setLayoutParams(layoutParams);
                badge.setBackgroundResource(icon);
                badge.setVisibility(View.VISIBLE);
            } else {
                badge.setVisibility(View.GONE);
            }
        }
    }

    private class GridPaddingDecoration extends RecyclerView.ItemDecoration {

        private final int mPaddingHorizontal;
        private final int mPaddingBottom;

        GridPaddingDecoration(int paddingHorizontal, int paddingBottom) {
            mPaddingHorizontal = paddingHorizontal;
            mPaddingBottom = paddingBottom;
        }

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