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

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
import android.graphics.Point;
import android.graphics.PorterDuff.Mode;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.provider.Settings;
import android.service.wallpaper.WallpaperService;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.GridLayoutManager.SpanSizeLookup;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.android.wallpaper.R;
import com.android.wallpaper.asset.Asset;
import com.android.wallpaper.compat.ButtonDrawableSetterCompat;
import com.android.wallpaper.config.Flags;
import com.android.wallpaper.model.Category;
import com.android.wallpaper.model.ThirdPartyAppCategory;
import com.android.wallpaper.model.WallpaperCategory;
import com.android.wallpaper.model.WallpaperInfo;
import com.android.wallpaper.module.CurrentWallpaperInfoFactory;
import com.android.wallpaper.module.CurrentWallpaperInfoFactory.WallpaperInfoCallback;
import com.android.wallpaper.module.ExploreIntentChecker;
import com.android.wallpaper.module.Injector;
import com.android.wallpaper.module.InjectorProvider;
import com.android.wallpaper.module.LockWallpaperStatusChecker;
import com.android.wallpaper.module.PackageStatusNotifier;
import com.android.wallpaper.module.UserEventLogger;
import com.android.wallpaper.module.WallpaperPreferences;
import com.android.wallpaper.module.WallpaperPreferences.PresentationMode;
import com.android.wallpaper.module.WallpaperRotationRefresher;
import com.android.wallpaper.module.WallpaperRotationRefresher.Listener;
import com.android.wallpaper.picker.MyPhotosLauncher.PermissionChangedListener;
import com.android.wallpaper.util.DisplayMetricsRetriever;
import com.android.wallpaper.util.ScreenSizeCalculator;
import com.android.wallpaper.util.TileSizeCalculator;
import com.android.wallpaper.widget.GridMarginDecoration;
import com.bumptech.glide.Glide;
import com.bumptech.glide.MemoryCategory;

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

/**
 * Displays the Main UI for picking an category of wallpapers to choose from.
 */
public class CategoryPickerFragment extends Fragment {
    private static final String TAG = "CategoryPickerFragment";

    // The number of ViewHolders that don't pertain to category tiles.
    // Currently 2: one for the metadata section and one for the "Select wallpaper" header.
    private static final int NUM_NON_CATEGORY_VIEW_HOLDERS = 2;

    /**
     * The fixed RecyclerView.Adapter position of the ViewHolder for the initial item in the grid --
     * usually the wallpaper metadata, or a "permission needed" warning UI.
     */
    private static final int INITIAL_HOLDER_ADAPTER_POSITION = 0;

    private static final int SETTINGS_APP_INFO_REQUEST_CODE = 1;

    private static final String PERMISSION_READ_WALLPAPER_INTERNAL =
            "android.permission.READ_WALLPAPER_INTERNAL";

    private RecyclerView mImageGrid;
    private CategoryAdapter mAdapter;
    private ArrayList<Category> mCategories;
    private Point mTileSizePx;
    private boolean mAwaitingCategories;
    private ProgressDialog mRefreshWallpaperProgressDialog;
    private boolean mTestingMode;

    public CategoryPickerFragment() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mCategories = new ArrayList<>();
        mAdapter = new CategoryAdapter(mCategories);
    }

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

        mImageGrid = (RecyclerView) view.findViewById(R.id.category_grid);
        GridMarginDecoration.applyTo(mImageGrid);

        mTileSizePx = TileSizeCalculator.getCategoryTileSize(getActivity());

        if (LockWallpaperStatusChecker.isLockWallpaperSet(getContext())) {
            mAdapter.setNumMetadataCards(CategoryAdapter.METADATA_VIEW_TWO_CARDS);
        } else {
            mAdapter.setNumMetadataCards(CategoryAdapter.METADATA_VIEW_SINGLE_CARD);
        }
        mImageGrid.setAdapter(mAdapter);

        GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), getNumColumns());
        gridLayoutManager.setSpanSizeLookup(new CategorySpanSizeLookup(mAdapter));
        mImageGrid.setLayoutManager(gridLayoutManager);

        return view;
    }

    @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);

        // Refresh metadata since it may have changed since the activity was paused.
        ViewHolder initialViewHolder =
                mImageGrid.findViewHolderForAdapterPosition(INITIAL_HOLDER_ADAPTER_POSITION);
        MetadataHolder metadataHolder = null;
        if (initialViewHolder instanceof MetadataHolder) {
            metadataHolder = (MetadataHolder) initialViewHolder;
        }

        // The wallpaper may have been set while this fragment was paused, so force refresh the current
        // wallpapers and presentation mode.
        refreshCurrentWallpapers(metadataHolder, true /* forceRefresh */);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mRefreshWallpaperProgressDialog != null) {
            mRefreshWallpaperProgressDialog.dismiss();
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == SETTINGS_APP_INFO_REQUEST_CODE) {
            mAdapter.notifyDataSetChanged();
        }
    }

    /**
     * Inserts the given category into the categories list in priority order.
     */
    public void addCategory(Category category, boolean loading) {
        // If not previously waiting for categories, enter the waiting state by showing the loading
        // indicator.
        if (loading && !mAwaitingCategories) {
            mAdapter.notifyItemChanged(getNumColumns());
            mAdapter.notifyItemInserted(getNumColumns());
            mAwaitingCategories = true;
        }

        int priority = category.getPriority();

        int index = 0;
        while (index < mCategories.size() && priority >= mCategories.get(index).getPriority()) {
            index++;
        }

        mCategories.add(index, category);
        if (mAdapter != null) {
            // Offset the index because of the static metadata element at beginning of RecyclerView.
            mAdapter.notifyItemInserted(index + NUM_NON_CATEGORY_VIEW_HOLDERS);
        }
    }

    public void removeCategory(Category category) {
        int index = mCategories.indexOf(category);
        if (index >= 0) {
            mCategories.remove(index);
            mAdapter.notifyItemRemoved(index + NUM_NON_CATEGORY_VIEW_HOLDERS);
        }
    }

    public void updateCategory(Category category) {
        int index = mCategories.indexOf(category);
        if (index >= 0) {
            mCategories.remove(index);
            mCategories.add(index, category);
            mAdapter.notifyItemChanged(index + NUM_NON_CATEGORY_VIEW_HOLDERS);
        }
    }

    public void clearCategories() {
        mCategories.clear();
        mAdapter.notifyDataSetChanged();
    }

    /**
     * Notifies the CategoryPickerFragment that no further categories are expected so it may hide
     * the loading indicator.
     */
    public void doneFetchingCategories() {
        if (mAwaitingCategories) {
            mAdapter.notifyItemRemoved(mAdapter.getItemCount() - 1);
            mAwaitingCategories = false;
        }
    }

    /**
     * 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.
     */
    void setTestingMode(boolean testingMode) {
        mTestingMode = testingMode;
    }

    private boolean canShowCurrentWallpaper() {
        TopLevelPickerActivity activity = (TopLevelPickerActivity) getActivity();
        PackageManager packageManager = activity.getPackageManager();
        String packageName = activity.getPackageName();

        boolean hasReadWallpaperInternal = packageManager.checkPermission(
                PERMISSION_READ_WALLPAPER_INTERNAL, packageName) == PackageManager.PERMISSION_GRANTED;
        return hasReadWallpaperInternal || activity.isReadExternalStoragePermissionGranted();
    }

    /**
     * Obtains the {@link WallpaperInfo} object(s) representing the wallpaper(s) currently set to the
     * device from the {@link CurrentWallpaperInfoFactory} and binds them to the provided
     * {@link MetadataHolder}.
     */
    private void refreshCurrentWallpapers(@Nullable final MetadataHolder holder,
                                          boolean forceRefresh) {
        CurrentWallpaperInfoFactory factory = InjectorProvider.getInjector()
                .getCurrentWallpaperFactory(getActivity().getApplicationContext());

        factory.createCurrentWallpaperInfos(new WallpaperInfoCallback() {
            @Override
            public void onWallpaperInfoCreated(
                    final WallpaperInfo homeWallpaper,
                    @Nullable final WallpaperInfo lockWallpaper,
                    @PresentationMode final int presentationMode) {

                // Update the metadata displayed on screen. Do this in a Handler so it is scheduled at the
                // end of the message queue. This is necessary to ensure we do not remove or add data from
                // the adapter while the layout is being computed. RecyclerView documentation therefore
                // recommends performing such changes in a Handler.
                new android.os.Handler().post(new Runnable() {
                    @Override
                    public void run() {
                        // A config change may have destroyed the activity since the refresh started, so check
                        // for that.
                        if (getActivity() == null) {
                            return;
                        }

                        int numMetadataCards = (lockWallpaper == null)
                                ? CategoryAdapter.METADATA_VIEW_SINGLE_CARD
                                : CategoryAdapter.METADATA_VIEW_TWO_CARDS;
                        mAdapter.setNumMetadataCards(numMetadataCards);

                        // The MetadataHolder may be null if the RecyclerView has not yet created the view
                        // holder.
                        if (holder != null) {
                            holder.bindWallpapers(homeWallpaper, lockWallpaper, presentationMode);
                        }
                    }
                });
            }
        }, forceRefresh);
    }

    private int getNumColumns() {
        return TileSizeCalculator.getNumCategoryColumns(getActivity());
    }

    /**
     * Returns the width to use for the home screen wallpaper in the "single metadata" configuration.
     */
    private int getSingleWallpaperImageWidth() {
        Point screenSize = ScreenSizeCalculator.getInstance()
                .getScreenSize(getActivity().getWindowManager().getDefaultDisplay());

        int height = getResources().getDimensionPixelSize(R.dimen.single_metadata_card_layout_height);
        return height * screenSize.x / screenSize.y;
    }

    /**
     * Refreshes the current wallpaper in a daily wallpaper rotation.
     */
    private void refreshDailyWallpaper() {
        // ProgressDialog endlessly updates the UI thread, keeping it from going idle which therefore
        // causes Espresso to hang once the dialog is shown.
        if (!mTestingMode) {
            int themeResId;
            if (VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) {
                themeResId = R.style.ProgressDialogThemePreL;
            } else {
                themeResId = R.style.LightDialogTheme;
            }
            mRefreshWallpaperProgressDialog = new ProgressDialog(getActivity(), themeResId);
            mRefreshWallpaperProgressDialog.setTitle(null);
            mRefreshWallpaperProgressDialog.setMessage(
                    getResources().getString(R.string.refreshing_daily_wallpaper_dialog_message));
            mRefreshWallpaperProgressDialog.setIndeterminate(true);
            mRefreshWallpaperProgressDialog.setCancelable(false);
            mRefreshWallpaperProgressDialog.show();
        }

        WallpaperRotationRefresher wallpaperRotationRefresher =
                InjectorProvider.getInjector().getWallpaperRotationRefresher();
        wallpaperRotationRefresher.refreshWallpaper(getContext(), new Listener() {
            @Override
            public void onRefreshed() {
                // If the fragment is detached from the activity there's nothing to do here and the UI will
                // update when the fragment is resumed.
                if (getActivity() == null) {
                    return;
                }

                if (mRefreshWallpaperProgressDialog != null) {
                    mRefreshWallpaperProgressDialog.dismiss();
                }

                ViewHolder initialViewHolder =
                        mImageGrid.findViewHolderForAdapterPosition(INITIAL_HOLDER_ADAPTER_POSITION);
                if (initialViewHolder instanceof MetadataHolder) {
                    MetadataHolder metadataHolder = (MetadataHolder) initialViewHolder;
                    // Update the metadata pane since we know now the UI there is stale.
                    refreshCurrentWallpapers(metadataHolder, true /* forceRefresh */);
                }
            }

            @Override
            public void onError() {
                if (getActivity() == null) {
                    return;
                }

                if (mRefreshWallpaperProgressDialog != null) {
                    mRefreshWallpaperProgressDialog.dismiss();
                }

                AlertDialog errorDialog = new AlertDialog.Builder(getActivity(), R.style.LightDialogTheme)
                        .setMessage(R.string.refresh_daily_wallpaper_failed_message)
                        .setPositiveButton(android.R.string.ok, null /* onClickListener */)
                        .create();
                errorDialog.show();
            }
        });
    }

    /**
     * Returns the width to use for the home and lock screen wallpapers in the "both metadata"
     * configuration.
     */
    private int getBothWallpaperImageWidth() {
        DisplayMetrics metrics = DisplayMetricsRetriever.getInstance().getDisplayMetrics(getResources(),
                getActivity().getWindowManager().getDefaultDisplay());

        // In the "both metadata" configuration, wallpaper images minus the gutters account for the full
        // width of the device's screen.
        return metrics.widthPixels - (3 * getResources().getDimensionPixelSize(R.dimen.grid_padding));
    }

    private interface MetadataHolder {
        /**
         * Binds {@link WallpaperInfo} objects representing the currently-set wallpapers to the
         * ViewHolder layout.
         */
        void bindWallpapers(WallpaperInfo homeWallpaper, WallpaperInfo lockWallpaper,
                            @PresentationMode int presentationMode);
    }

    private static class SelectWallpaperHeaderHolder extends RecyclerView.ViewHolder {
        public SelectWallpaperHeaderHolder(View headerView) {
            super(headerView);
        }
    }

    /**
     * SpanSizeLookup subclass which provides that the item in the first position spans the number of
     * columns in the RecyclerView and all other items only take up a single span.
     */
    private class CategorySpanSizeLookup extends SpanSizeLookup {
        CategoryAdapter mAdapter;

        public CategorySpanSizeLookup(CategoryAdapter adapter) {
            mAdapter = adapter;
        }

        @Override
        public int getSpanSize(int position) {
            if (position < NUM_NON_CATEGORY_VIEW_HOLDERS
                    || mAdapter.getItemViewType(position)
                    == CategoryAdapter.ITEM_VIEW_TYPE_LOADING_INDICATOR) {
                return getNumColumns();
            }

            return 1;
        }
    }

    /**
     * ViewHolder subclass for a metadata "card" at the beginning of the RecyclerView.
     */
    private class SingleWallpaperMetadataHolder extends RecyclerView.ViewHolder
            implements MetadataHolder {
        private WallpaperInfo mWallpaperInfo;
        private ImageView mWallpaperImage;
        private TextView mWallpaperPresentationMode;
        private TextView mWallpaperTitle;
        private TextView mWallpaperSubtitle;
        private ViewGroup mWallpaperExploreSection;
        private Button mWallpaperExploreButton;
        private ImageButton mWallpaperExploreButtonNoText;
        private ImageButton mSkipWallpaperButton;

        public SingleWallpaperMetadataHolder(View metadataView) {
            super(metadataView);

            mWallpaperImage = (ImageView) metadataView.findViewById(R.id.wallpaper_image);
            mWallpaperImage.getLayoutParams().width = getSingleWallpaperImageWidth();

            mWallpaperPresentationMode =
                    (TextView) metadataView.findViewById(R.id.wallpaper_presentation_mode);
            mWallpaperTitle = (TextView) metadataView.findViewById(R.id.wallpaper_title);
            mWallpaperSubtitle = (TextView) metadataView.findViewById(R.id.wallpaper_subtitle);

            mWallpaperExploreSection =
                    (ViewGroup) metadataView.findViewById(R.id.wallpaper_explore_section);
            mWallpaperExploreButton =
                    (Button) metadataView.findViewById(R.id.wallpaper_explore_button);
            mWallpaperExploreButtonNoText = (ImageButton)
                    metadataView.findViewById(R.id.wallpaper_explore_button_notext);

            mSkipWallpaperButton = (ImageButton) metadataView.findViewById(R.id.skip_wallpaper_button);

            if (Flags.skipDailyWallpaperButtonEnabled) {
                Drawable exploreButtonDrawable = getContext().getDrawable(
                        R.drawable.ic_explore_24px);
                // This Drawable's state is shared across the app, so make a copy of it before applying a
                // color tint as not to affect other clients elsewhere in the app.
                exploreButtonDrawable = exploreButtonDrawable.getConstantState().newDrawable().mutate();
                exploreButtonDrawable.setColorFilter(
                        getResources().getColor(R.color.currently_set_explore_button_color), Mode.SRC_IN);
                ButtonDrawableSetterCompat.setDrawableToButtonStart(
                        mWallpaperExploreButton, exploreButtonDrawable);
            }
        }

        /**
         * Binds home screen wallpaper to the ViewHolder layout.
         */
        @Override
        public void bindWallpapers(WallpaperInfo homeWallpaper, WallpaperInfo lockWallpaper,
                                   @PresentationMode int presentationMode) {
            mWallpaperInfo = homeWallpaper;

            bindWallpaperAsset();
            bindWallpaperText(presentationMode);
            bindWallpaperActionButtons(presentationMode);
        }

        private void bindWallpaperAsset() {
            final UserEventLogger eventLogger =
                    InjectorProvider.getInjector().getUserEventLogger(getActivity());

            mWallpaperInfo.getThumbAsset(getActivity().getApplicationContext()).loadDrawable(
                    getActivity(), mWallpaperImage, getResources().getColor(R.color.secondary_color));

            mWallpaperImage.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    ((TopLevelPickerActivity) getActivity()).showViewOnlyPreview(mWallpaperInfo);
                    eventLogger.logCurrentWallpaperPreviewed();
                }
            });
        }

        private void bindWallpaperText(@PresentationMode int presentationMode) {
            Context appContext = getActivity().getApplicationContext();

            mWallpaperPresentationMode.setText(
                    AttributionFormatter.getHumanReadableWallpaperPresentationMode(
                            appContext, presentationMode));

            List<String> attributions = mWallpaperInfo.getAttributions(appContext);
            if (!attributions.isEmpty()) {
                mWallpaperTitle.setText(attributions.get(0));
            }
            String subtitleText =
                    AttributionFormatter.formatWallpaperSubtitle(appContext, mWallpaperInfo);
            if (!TextUtils.isEmpty(subtitleText)) {
                mWallpaperSubtitle.setText(subtitleText);
                mWallpaperSubtitle.setVisibility(View.VISIBLE);
            } else {
                mWallpaperSubtitle.setVisibility(View.GONE);
            }
        }

        private void bindWallpaperActionButtons(@PresentationMode int presentationMode) {
            final Context appContext = getActivity().getApplicationContext();

            final String actionUrl = mWallpaperInfo.getActionUrl(appContext);
            if (actionUrl != null && !actionUrl.isEmpty()) {

                Uri exploreUri = Uri.parse(actionUrl);

                ExploreIntentChecker intentChecker =
                        InjectorProvider.getInjector().getExploreIntentChecker(appContext);
                intentChecker.fetchValidActionViewIntent(exploreUri, (@Nullable Intent exploreIntent) -> {
                    if (getActivity() == null) {
                        return;
                    }

                    updateExploreSectionVisibility(presentationMode, exploreIntent);
                });
            } else {
                updateExploreSectionVisibility(presentationMode, null /* exploreIntent */);
            }
        }

        /**
         * Shows or hides appropriate elements in the "Explore section" (containing the Explore button
         * and the Next Wallpaper button) depending on the current wallpaper.
         *
         * @param presentationMode The presentation mode of the current wallpaper.
         * @param exploreIntent    An optional explore intent for the current wallpaper.
         */
        private void updateExploreSectionVisibility(
                @PresentationMode int presentationMode, @Nullable Intent exploreIntent) {

            final Context appContext = getActivity().getApplicationContext();
            final UserEventLogger eventLogger =
                    InjectorProvider.getInjector().getUserEventLogger(appContext);

            boolean showSkipWallpaperButton = Flags.skipDailyWallpaperButtonEnabled
                    && presentationMode == WallpaperPreferences.PRESENTATION_MODE_ROTATING;

            if (exploreIntent != null || showSkipWallpaperButton) {
                mWallpaperExploreSection.setVisibility(View.VISIBLE);

                if (exploreIntent != null) {
                    View exploreButton;

                    if (showSkipWallpaperButton) {
                        exploreButton = mWallpaperExploreButtonNoText;
                        mWallpaperExploreButtonNoText.setImageDrawable(getContext().getDrawable(
                                mWallpaperInfo.getActionIconRes(appContext)));
                        mWallpaperExploreButtonNoText.setContentDescription(
                                getString(mWallpaperInfo.getActionLabelRes(appContext)));
                        mWallpaperExploreButtonNoText.setColorFilter(
                                getResources().getColor(R.color.currently_set_explore_button_color),
                                Mode.SRC_IN);
                        mWallpaperExploreButton.setVisibility(View.GONE);
                    } else {
                        exploreButton = mWallpaperExploreButton;

                        Drawable drawable = getContext().getDrawable(
                                mWallpaperInfo.getActionIconRes(appContext)).getConstantState()
                                .newDrawable().mutate();
                        // Color the "compass" icon with the accent color.
                        drawable.setColorFilter(
                                getResources().getColor(R.color.accent_color), Mode.SRC_IN);
                        ButtonDrawableSetterCompat.setDrawableToButtonStart(
                                mWallpaperExploreButton, drawable);
                        mWallpaperExploreButton.setText(
                                mWallpaperInfo.getActionLabelRes(appContext));
                        mWallpaperExploreButtonNoText.setVisibility(View.GONE);
                    }
                    exploreButton.setVisibility(View.VISIBLE);
                    exploreButton.setOnClickListener((View view) -> {
                        eventLogger.logActionClicked(mWallpaperInfo.getCollectionId(appContext),
                                mWallpaperInfo.getActionLabelRes(appContext));
                        startActivity(exploreIntent);
                    });
                }

                if (showSkipWallpaperButton) {
                    mSkipWallpaperButton.setVisibility(View.VISIBLE);
                    mSkipWallpaperButton.setColorFilter(
                            getResources().getColor(R.color.currently_set_explore_button_color), Mode.SRC_IN);
                    mSkipWallpaperButton.setOnClickListener((View view) -> refreshDailyWallpaper());
                }
            } else {
                mWallpaperExploreSection.setVisibility(View.GONE);
            }
        }
    }

    /**
     * ViewHolder subclass for a metadata "card" at the beginning of the RecyclerView that shows
     * both home screen and lock screen wallpapers.
     */
    private class TwoWallpapersMetadataHolder extends RecyclerView.ViewHolder
            implements MetadataHolder {
        private WallpaperInfo mHomeWallpaperInfo;
        private FrameLayout mHomeWallpaperSection;
        private ImageView mHomeWallpaperImage;
        private LinearLayout mHomeWallpaperTopSection;
        private TextView mHomeWallpaperPresentationMode;
        private TextView mHomeWallpaperTitle;
        private TextView mHomeWallpaperSubtitle1;
        private TextView mHomeWallpaperSubtitle2;

        private ImageButton mHomeWallpaperExploreButtonLegacy;
        private ImageButton mHomeWallpaperExploreButton;
        private ImageButton mSkipWallpaperButton;

        private FrameLayout mLockWallpaperSection;
        private WallpaperInfo mLockWallpaperInfo;
        private ImageView mLockWallpaperImage;
        private LinearLayout mLockWallpaperTopSection;
        private TextView mLockWallpaperPresentationMode;
        private TextView mLockWallpaperTitle;
        private TextView mLockWallpaperSubtitle1;
        private TextView mLockWallpaperSubtitle2;

        private ImageButton mLockWallpaperExploreButtonLegacy;
        private ImageButton mLockWallpaperExploreButton;

        public TwoWallpapersMetadataHolder(View metadataView) {
            super(metadataView);

            // Set the min width of the metadata panel to be the screen width minus space for the
            // 2 gutters on the sides. This ensures the RecyclerView's GridLayoutManager gives it
            // a wide-enough initial width to fill up the width of the grid prior to the view being
            // fully populated.
            final Display display = getActivity().getWindowManager().getDefaultDisplay();
            Point screenSize = ScreenSizeCalculator.getInstance().getScreenSize(display);
            metadataView.setMinimumWidth(
                    screenSize.x - 2 * getResources().getDimensionPixelSize(R.dimen.grid_padding));

            int bothWallpaperImageWidth = getBothWallpaperImageWidth();

            mHomeWallpaperSection = (FrameLayout) metadataView.findViewById(R.id.home_wallpaper_section);
            mHomeWallpaperSection.setMinimumWidth(bothWallpaperImageWidth);
            mHomeWallpaperImage = (ImageView) metadataView.findViewById(R.id.home_wallpaper_image);
            mHomeWallpaperTopSection =
                    (LinearLayout) metadataView.findViewById(R.id.home_wallpaper_top_section);
            mHomeWallpaperPresentationMode =
                    (TextView) metadataView.findViewById(R.id.home_wallpaper_presentation_mode);
            mHomeWallpaperTitle = (TextView) metadataView.findViewById(R.id.home_wallpaper_title);
            mHomeWallpaperSubtitle1 = (TextView) metadataView.findViewById(R.id.home_wallpaper_subtitle1);
            mHomeWallpaperSubtitle2 = (TextView) metadataView.findViewById(R.id.home_wallpaper_subtitle2);
            mHomeWallpaperExploreButtonLegacy =
                    (ImageButton) metadataView.findViewById(R.id.home_wallpaper_explore_button_legacy);
            mHomeWallpaperExploreButton =
                    (ImageButton) metadataView.findViewById(R.id.home_wallpaper_explore_button);
            mSkipWallpaperButton = (ImageButton) metadataView.findViewById(R.id.skip_home_wallpaper);

            mLockWallpaperSection = (FrameLayout) metadataView.findViewById(R.id.lock_wallpaper_section);
            mLockWallpaperSection.setMinimumWidth(bothWallpaperImageWidth);
            mLockWallpaperImage = (ImageView) metadataView.findViewById(R.id.lock_wallpaper_image);
            mLockWallpaperTopSection =
                    (LinearLayout) metadataView.findViewById(R.id.lock_wallpaper_top_section);
            mLockWallpaperPresentationMode =
                    (TextView) metadataView.findViewById(R.id.lock_wallpaper_presentation_mode);
            mLockWallpaperTitle = (TextView) metadataView.findViewById(R.id.lock_wallpaper_title);
            mLockWallpaperSubtitle1 = (TextView) metadataView.findViewById(R.id.lock_wallpaper_subtitle1);
            mLockWallpaperSubtitle2 = (TextView) metadataView.findViewById(R.id.lock_wallpaper_subtitle2);
            mLockWallpaperExploreButtonLegacy =
                    (ImageButton) metadataView.findViewById(R.id.lock_wallpaper_explore_button_legacy);
            mLockWallpaperExploreButton =
                    (ImageButton) metadataView.findViewById(R.id.lock_wallpaper_explore_button);
        }

        @Override
        public void bindWallpapers(WallpaperInfo homeWallpaper, WallpaperInfo lockWallpaper,
                                   @PresentationMode int presentationMode) {
            bindHomeWallpaper(homeWallpaper, presentationMode);
            bindLockWallpaper(lockWallpaper);
        }

        private void bindHomeWallpaper(WallpaperInfo homeWallpaper,
                                       @PresentationMode int presentationMode) {
            final Context appContext = getActivity().getApplicationContext();
            final UserEventLogger eventLogger =
                    InjectorProvider.getInjector().getUserEventLogger(appContext);

            mHomeWallpaperInfo = homeWallpaper;

            homeWallpaper.getThumbAsset(appContext).loadDrawable(
                    getActivity(), mHomeWallpaperImage, getResources().getColor(R.color.secondary_color));
            mHomeWallpaperTopSection.setVisibility(View.VISIBLE);
            mHomeWallpaperPresentationMode.setText(
                    AttributionFormatter.getHumanReadableWallpaperPresentationMode(
                            appContext, presentationMode));

            List<String> attributions = homeWallpaper.getAttributions(appContext);
            if (!attributions.isEmpty()) {
                mHomeWallpaperTitle.setText(attributions.get(0));
            }
            if (attributions.size() > 1) {
                mHomeWallpaperSubtitle1.setText(attributions.get(1));
            }
            if (attributions.size() > 2) {
                mHomeWallpaperSubtitle2.setText(attributions.get(2));
            }

            final String homeActionUrl = homeWallpaper.getActionUrl(appContext);

            ImageButton exploreButton = Flags.skipDailyWallpaperButtonEnabled
                    ? mHomeWallpaperExploreButton
                    : mHomeWallpaperExploreButtonLegacy;
            if (homeActionUrl != null && !homeActionUrl.isEmpty()) {
                Uri homeExploreUri = Uri.parse(homeActionUrl);

                ExploreIntentChecker intentChecker =
                        InjectorProvider.getInjector().getExploreIntentChecker(appContext);

                intentChecker.fetchValidActionViewIntent(
                        homeExploreUri, (@Nullable Intent exploreIntent) -> {
                            if (exploreIntent == null || getActivity() == null) {
                                return;
                            }

                            exploreButton.setVisibility(View.VISIBLE);
                            exploreButton.setImageDrawable(getContext().getDrawable(
                                    homeWallpaper.getActionIconRes(appContext)));
                            exploreButton.setContentDescription(getString(homeWallpaper
                                    .getActionLabelRes(appContext)));
                            exploreButton.setColorFilter(
                                    getResources().getColor(R.color.currently_set_explore_button_color), Mode.SRC_IN);
                            exploreButton.setOnClickListener(new OnClickListener() {
                                @Override
                                public void onClick(View v) {
                                    eventLogger.logActionClicked(
                                            mHomeWallpaperInfo.getCollectionId(appContext),
                                            mHomeWallpaperInfo.getActionLabelRes(appContext));
                                    startActivity(exploreIntent);
                                }
                            });
                        });
            } else {
                exploreButton.setVisibility(View.GONE);
            }

            if (Flags.skipDailyWallpaperButtonEnabled
                    && presentationMode == WallpaperPreferences.PRESENTATION_MODE_ROTATING) {
                mSkipWallpaperButton.setVisibility(View.VISIBLE);
                mSkipWallpaperButton.setColorFilter(
                        getResources().getColor(R.color.currently_set_explore_button_color), Mode.SRC_IN);
                mSkipWallpaperButton.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        refreshDailyWallpaper();
                    }
                });
            } else {
                mSkipWallpaperButton.setVisibility(View.GONE);
            }

            mHomeWallpaperImage.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    eventLogger.logCurrentWallpaperPreviewed();
                    ((TopLevelPickerActivity) getActivity()).showViewOnlyPreview(mHomeWallpaperInfo);
                }
            });
        }

        private void bindLockWallpaper(WallpaperInfo lockWallpaper) {
            if (lockWallpaper == null) {
                Log.e(TAG, "TwoWallpapersMetadataHolder bound without a lock screen wallpaper.");
                return;
            }

            final Context appContext = getActivity().getApplicationContext();
            final UserEventLogger eventLogger =
                    InjectorProvider.getInjector().getUserEventLogger(getActivity());

            mLockWallpaperInfo = lockWallpaper;

            lockWallpaper.getThumbAsset(appContext).loadDrawable(
                    getActivity(), mLockWallpaperImage, getResources().getColor(R.color.secondary_color));
            mLockWallpaperTopSection.setVisibility(View.VISIBLE);

            // Daily wallpaper rotation can't be in effect on only the lock screen, so if there's a
            // separate lock screen, it must be presented as "Currently set".
            mLockWallpaperPresentationMode.setText(
                    AttributionFormatter.getHumanReadableWallpaperPresentationMode(
                            appContext, WallpaperPreferences.PRESENTATION_MODE_STATIC));

            List<String> lockAttributions = lockWallpaper.getAttributions(appContext);
            if (!lockAttributions.isEmpty()) {
                mLockWallpaperTitle.setText(lockAttributions.get(0));
            }
            if (lockAttributions.size() > 1) {
                mLockWallpaperSubtitle1.setText(lockAttributions.get(1));
            }
            if (lockAttributions.size() > 2) {
                mLockWallpaperSubtitle2.setText(lockAttributions.get(2));
            }

            final String lockActionUrl = lockWallpaper.getActionUrl(appContext);

            ImageButton exploreButton = Flags.skipDailyWallpaperButtonEnabled
                    ? mLockWallpaperExploreButton
                    : mLockWallpaperExploreButtonLegacy;
            if (lockActionUrl != null && !lockActionUrl.isEmpty()) {
                Uri lockExploreUri = Uri.parse(lockActionUrl);

                ExploreIntentChecker intentChecker =
                        InjectorProvider.getInjector().getExploreIntentChecker(appContext);
                intentChecker.fetchValidActionViewIntent(
                        lockExploreUri, (@Nullable Intent exploreIntent) -> {
                            if (exploreIntent == null || getActivity() == null) {
                                return;
                            }
                            exploreButton.setImageDrawable(getContext().getDrawable(
                                    lockWallpaper.getActionIconRes(appContext)));
                            exploreButton.setContentDescription(getString(
                                    lockWallpaper.getActionLabelRes(appContext)));
                            exploreButton.setVisibility(View.VISIBLE);
                            exploreButton.setColorFilter(
                                    getResources().getColor(
                                            R.color.currently_set_explore_button_color),
                                    Mode.SRC_IN);
                            exploreButton.setOnClickListener(new OnClickListener() {
                                @Override
                                public void onClick(View v) {
                                    eventLogger.logActionClicked(
                                            mLockWallpaperInfo.getCollectionId(appContext),
                                            mLockWallpaperInfo.getActionLabelRes(appContext));
                                    startActivity(exploreIntent);
                                }
                            });
                        });
            } else {
                exploreButton.setVisibility(View.GONE);
            }

            mLockWallpaperImage.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    eventLogger.logCurrentWallpaperPreviewed();
                    ((TopLevelPickerActivity) getActivity()).showViewOnlyPreview(mLockWallpaperInfo);
                }
            });
        }
    }

    /**
     * ViewHolder subclass for a category tile in the RecyclerView.
     */
    private class CategoryHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        private Category mCategory;
        private RelativeLayout mTileLayout;
        private ImageView mImageView;
        private ImageView mOverlayIconView;
        private TextView mTitleView;

        public CategoryHolder(View itemView) {
            super(itemView);
            itemView.setOnClickListener(this);

            mTileLayout = (RelativeLayout) itemView.findViewById(R.id.tile);
            mImageView = (ImageView) itemView.findViewById(R.id.image);
            mOverlayIconView = (ImageView) itemView.findViewById(R.id.overlay_icon);
            mTitleView = (TextView) itemView.findViewById(R.id.category_title);

            mTileLayout.getLayoutParams().height = mTileSizePx.y;
        }

        @Override
        public void onClick(View view) {
            final UserEventLogger eventLogger =
                    InjectorProvider.getInjector().getUserEventLogger(getActivity());
            eventLogger.logCategorySelected(mCategory.getCollectionId());

            if (mCategory.supportsCustomPhotos()) {
                ((MyPhotosLauncher) getActivity()).requestCustomPhotoPicker(
                        new PermissionChangedListener() {
                            @Override
                            public void onPermissionsGranted() {
                                drawThumbnailAndOverlayIcon();
                            }

                            @Override
                            public void onPermissionsDenied(boolean dontAskAgain) {
                                // No-op
                            }
                        });
                return;
            }

            ((TopLevelPickerActivity) getActivity()).show(mCategory.getCollectionId());
        }

        /**
         * Binds the given category to this CategoryHolder.
         */
        public void bindCategory(Category category) {
            mCategory = category;
            mTitleView.setText(category.getTitle());
            drawThumbnailAndOverlayIcon();
        }

        /**
         * Draws the CategoryHolder's thumbnail and overlay icon.
         */
        public void drawThumbnailAndOverlayIcon() {
            mOverlayIconView.setImageDrawable(mCategory.getOverlayIcon(
                    getActivity().getApplicationContext()));

            // Size the overlay icon according to the category.
            int overlayIconDimenDp = mCategory.getOverlayIconSizeDp();
            DisplayMetrics metrics = DisplayMetricsRetriever.getInstance().getDisplayMetrics(
                    getResources(), getActivity().getWindowManager().getDefaultDisplay());
            int overlayIconDimenPx = (int) (overlayIconDimenDp * metrics.density);
            mOverlayIconView.getLayoutParams().width = overlayIconDimenPx;
            mOverlayIconView.getLayoutParams().height = overlayIconDimenPx;

            Asset thumbnail = mCategory.getThumbnail(getActivity().getApplicationContext());
            if (thumbnail != null) {
                thumbnail.loadDrawable(getActivity(), mImageView,
                        getResources().getColor(R.color.secondary_color));
            } else {
                // TODO(orenb): Replace this workaround for b/62584914 with a proper way of unloading the
                // ImageView such that no incorrect image is improperly loaded upon rapid scroll.
                Object nullObj = null;
                Glide.with(getActivity())
                        .asDrawable()
                        .load(nullObj)
                        .into(mImageView);

                mTitleView.setBackgroundColor(getResources().getColor(
                        R.color.category_title_scrim_color_no_thumbnail));
            }
        }
    }

    /**
     * ViewHolder subclass for the loading indicator ("spinner") shown when categories are being
     * fetched.
     */
    private class LoadingIndicatorHolder extends RecyclerView.ViewHolder {
        public LoadingIndicatorHolder(View view) {
            super(view);
            ProgressBar progressBar = (ProgressBar) view.findViewById(R.id.loading_indicator);
            progressBar.getIndeterminateDrawable().setColorFilter(
                    getResources().getColor(R.color.accent_color), Mode.SRC_IN);
        }
    }

    /**
     * ViewHolder subclass for a "card" at the beginning of the RecyclerView showing the app needs the
     * user to grant the storage permission to show the currently set wallpaper.
     */
    private class PermissionNeededHolder extends RecyclerView.ViewHolder {
        private Button mAllowAccessButton;

        public PermissionNeededHolder(View view) {
            super(view);

            mAllowAccessButton =
                    (Button) view.findViewById(R.id.permission_needed_allow_access_button);
            mAllowAccessButton.setOnClickListener((View v) -> {
                ((TopLevelPickerActivity) getActivity()).requestExternalStoragePermission(mAdapter);
            });

            // Replace explanation text with text containing the Wallpapers app name which replaces the
            // placeholder.
            String appName = getString(R.string.app_name);
            String explanation = getString(R.string.permission_needed_explanation, appName);
            TextView explanationTextView =
                    (TextView) view.findViewById(R.id.permission_needed_explanation);
            explanationTextView.setText(explanation);
        }
    }

    /**
     * RecyclerView Adapter subclass for the category tiles in the RecyclerView.
     */
    private class CategoryAdapter extends RecyclerView.Adapter<ViewHolder>
            implements PermissionChangedListener {
        public static final int METADATA_VIEW_SINGLE_CARD = 1;
        public static final int METADATA_VIEW_TWO_CARDS = 2;
        private static final int ITEM_VIEW_TYPE_METADATA = 1;
        private static final int ITEM_VIEW_TYPE_SELECT_WALLPAPER_HEADER = 2;
        private static final int ITEM_VIEW_TYPE_CATEGORY = 3;
        private static final int ITEM_VIEW_TYPE_LOADING_INDICATOR = 4;
        private static final int ITEM_VIEW_TYPE_PERMISSION_NEEDED = 5;
        private List<Category> mCategories;
        private int mNumMetadataCards;

        public CategoryAdapter(List<Category> categories) {
            mCategories = categories;
            mNumMetadataCards = METADATA_VIEW_SINGLE_CARD;
        }

        /**
         * Sets the number of metadata cards to be shown in the metadata view holder. Updates the UI
         * to reflect any changes in that number (e.g., a lock screen wallpaper has been set so we now
         * need to show two cards).
         */
        public void setNumMetadataCards(int numMetadataCards) {
            if (numMetadataCards != mNumMetadataCards && getItemCount() > 0) {
                notifyItemChanged(0);
            }

            mNumMetadataCards = numMetadataCards;
        }

        @Override
        public int getItemViewType(int position) {
            if (position == 0) {
                if (canShowCurrentWallpaper()) {
                    return ITEM_VIEW_TYPE_METADATA;
                } else {
                    return ITEM_VIEW_TYPE_PERMISSION_NEEDED;
                }
            } else if (position == 1) {
                return ITEM_VIEW_TYPE_SELECT_WALLPAPER_HEADER;
            } else if (mAwaitingCategories && position == getItemCount() - 1) {
                return ITEM_VIEW_TYPE_LOADING_INDICATOR;
            }

            return ITEM_VIEW_TYPE_CATEGORY;
        }

        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
            View view;

            switch (viewType) {
                case ITEM_VIEW_TYPE_METADATA:
                    if (mNumMetadataCards == METADATA_VIEW_SINGLE_CARD) {
                        view = layoutInflater.inflate(
                                R.layout.grid_item_single_metadata, parent, /* attachToRoot */ false);
                        return new SingleWallpaperMetadataHolder(view);
                    } else { // TWO_CARDS
                        view = layoutInflater.inflate(
                                R.layout.grid_item_both_metadata, parent, /* attachToRoot */ false);
                        return new TwoWallpapersMetadataHolder(view);
                    }
                case ITEM_VIEW_TYPE_SELECT_WALLPAPER_HEADER:
                    view = layoutInflater.inflate(
                            R.layout.grid_item_select_wallpaper_header, parent, /* attachToRoot */ false);
                    return new SelectWallpaperHeaderHolder(view);
                case ITEM_VIEW_TYPE_LOADING_INDICATOR:
                    view = layoutInflater.inflate(
                            R.layout.grid_item_loading_indicator, parent, /* attachToRoot */ false);
                    return new LoadingIndicatorHolder(view);
                case ITEM_VIEW_TYPE_CATEGORY:
                    view = layoutInflater.inflate(
                            R.layout.grid_item_category, parent, /* attachToRoot */ false);
                    return new CategoryHolder(view);
                case ITEM_VIEW_TYPE_PERMISSION_NEEDED:
                    view = layoutInflater.inflate(
                            R.layout.grid_item_permission_needed, parent, /* attachToRoot */ false);
                    return new PermissionNeededHolder(view);
                default:
                    Log.e(TAG, "Unsupported viewType " + viewType + " in CategoryAdapter");
                    return null;
            }
        }

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

            switch (viewType) {
                case ITEM_VIEW_TYPE_METADATA:
                    refreshCurrentWallpapers((MetadataHolder) holder, false /* forceRefresh */);
                    break;
                case ITEM_VIEW_TYPE_SELECT_WALLPAPER_HEADER:
                    // No op.
                    break;
                case ITEM_VIEW_TYPE_CATEGORY:
                    // Offset position to get category index to account for the non-category view holders.
                    Category category = mCategories.get(position - NUM_NON_CATEGORY_VIEW_HOLDERS);
                    ((CategoryHolder) holder).bindCategory(category);
                    break;
                case ITEM_VIEW_TYPE_LOADING_INDICATOR:
                case ITEM_VIEW_TYPE_PERMISSION_NEEDED:
                    // No op.
                    break;
                default:
                    Log.e(TAG, "Unsupported viewType " + viewType + " in CategoryAdapter");
            }
        }

        @Override
        public int getItemCount() {
            // Add to size of categories to account for the metadata related views.
            // Add 1 more for the loading indicator if not yet done loading.
            int size = mCategories.size() + NUM_NON_CATEGORY_VIEW_HOLDERS;
            if (mAwaitingCategories) {
                size += 1;
            }

            return size;
        }

        @Override
        public void onPermissionsGranted() {
            notifyDataSetChanged();
        }

        @Override
        public void onPermissionsDenied(boolean dontAskAgain) {
            if (!dontAskAgain) {
                return;
            }

            String permissionNeededMessage =
                    getString(R.string.permission_needed_explanation_go_to_settings);
            AlertDialog dialog = new AlertDialog.Builder(getActivity(), R.style.LightDialogTheme)
                    .setMessage(permissionNeededMessage)
                    .setPositiveButton(android.R.string.ok, null /* onClickListener */)
                    .setNegativeButton(
                            R.string.settings_button_label,
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialogInterface, int i) {
                                    Intent appInfoIntent = new Intent();
                                    appInfoIntent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                    Uri uri = Uri.fromParts(
                                            "package", getActivity().getPackageName(), null /* fragment */);
                                    appInfoIntent.setData(uri);
                                    startActivityForResult(appInfoIntent, SETTINGS_APP_INFO_REQUEST_CODE);
                                }
                            })
                    .create();
            dialog.show();
        }
    }
}
