/*
 * 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 static android.view.View.MeasureSpec.EXACTLY;
import static android.view.View.MeasureSpec.makeMeasureSpec;
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;

import static com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_COLLAPSED;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.graphics.RectF;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.service.wallpaper.WallpaperService;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.SurfaceControlViewHost;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.cardview.widget.CardView;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;

import com.android.wallpaper.R;
import com.android.wallpaper.model.Category;
import com.android.wallpaper.model.LiveWallpaperInfo;
import com.android.wallpaper.model.WallpaperInfo;
import com.android.wallpaper.module.CurrentWallpaperInfoFactory;
import com.android.wallpaper.module.CurrentWallpaperInfoFactory.WallpaperInfoCallback;
import com.android.wallpaper.module.InjectorProvider;
import com.android.wallpaper.module.UserEventLogger;
import com.android.wallpaper.module.WallpaperPersister;
import com.android.wallpaper.module.WallpaperPreferences;
import com.android.wallpaper.module.WallpaperPreferences.PresentationMode;
import com.android.wallpaper.picker.CategorySelectorFragment.CategorySelectorFragmentHost;
import com.android.wallpaper.picker.MyPhotosStarter.MyPhotosStarterProvider;
import com.android.wallpaper.picker.MyPhotosStarter.PermissionChangedListener;
import com.android.wallpaper.picker.individual.IndividualPickerFragment;
import com.android.wallpaper.picker.individual.IndividualPickerFragment.ThumbnailUpdater;
import com.android.wallpaper.picker.individual.IndividualPickerFragment.WallpaperDestinationCallback;
import com.android.wallpaper.util.SizeCalculator;
import com.android.wallpaper.util.WallpaperConnection;
import com.android.wallpaper.util.WallpaperConnection.WallpaperConnectionListener;
import com.android.wallpaper.widget.LiveTileOverlay;
import com.android.wallpaper.widget.LockScreenOverlayUpdater;
import com.android.wallpaper.widget.PreviewPager;
import com.android.wallpaper.widget.WallpaperColorsLoader;

import com.bumptech.glide.Glide;
import com.bumptech.glide.MemoryCategory;
import com.google.android.material.bottomsheet.BottomSheetBehavior;

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

/**
 * Displays the Main UI for picking a category of wallpapers to choose from.
 */
public class CategoryFragment extends AppbarFragment
        implements CategorySelectorFragmentHost, ThumbnailUpdater, WallpaperDestinationCallback {

    private final Rect mPreviewLocalRect = new Rect();
    private final Rect mPreviewGlobalRect = new Rect();
    private final int[] mLivePreviewLocation = new int[2];

    /**
     * Interface to be implemented by an Activity hosting a {@link CategoryFragment}
     */
    public interface CategoryFragmentHost extends MyPhotosStarterProvider {

        void requestExternalStoragePermission(PermissionChangedListener listener);

        boolean isReadExternalStoragePermissionGranted();

        void showViewOnlyPreview(WallpaperInfo wallpaperInfo);
    }

    public static CategoryFragment newInstance(CharSequence title) {
        CategoryFragment fragment = new CategoryFragment();
        fragment.setArguments(AppbarFragment.createArguments(title));
        return fragment;
    }

    private static final String TAG = "CategoryFragment";

    private static final int SETTINGS_APP_INFO_REQUEST_CODE = 1;

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

    private ImageView mHomePreview;
    private SurfaceView mWorkspaceSurface;
    private WorkspaceSurfaceHolderCallback mWorkspaceSurfaceCallback;
    private SurfaceView mWallpaperSurface;
    private ImageView mLockscreenPreview;
    private PreviewPager mPreviewPager;
    private List<View> mWallPaperPreviews;
    private WallpaperConnection mWallpaperConnection;
    private CategorySelectorFragment mCategorySelectorFragment;
    private IndividualPickerFragment mIndividualPickerFragment;
    private boolean mShowSelectedWallpaper;
    private BottomSheetBehavior<View> mBottomSheetBehavior;
    private int mSelectedPreviewPage;

    // The wallpaper information which is currently shown on the home preview.
    private WallpaperInfo mHomePreviewWallpaperInfo;
    // The wallpaper information which is currently shown on the lock preview.
    private WallpaperInfo mLockPreviewWallpaperInfo;

    // Home workspace surface is behind the app window, and so must the home image wallpaper like
    // the live wallpaper. This view is rendered on mWallpaperSurface for home image wallpaper.
    private ImageView mHomeImageWallpaper;
    private boolean mIsCollapsingByUserSelecting;
    private LockScreenOverlayUpdater mLockScreenOverlayUpdater;

    public CategoryFragment() {
        mCategorySelectorFragment = new CategorySelectorFragment();
    }

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

        mWallPaperPreviews = new ArrayList<>();
        CardView homePreviewCard = (CardView) inflater.inflate(
                R.layout.wallpaper_preview_card, null);
        mHomePreview = homePreviewCard.findViewById(R.id.wallpaper_preview_image);
        mWorkspaceSurface = homePreviewCard.findViewById(R.id.workspace_surface);
        mWorkspaceSurfaceCallback = new WorkspaceSurfaceHolderCallback(
                mWorkspaceSurface, getContext());
        mWallpaperSurface = homePreviewCard.findViewById(R.id.wallpaper_surface);
        mWallPaperPreviews.add(homePreviewCard);

        CardView lockscreenPreviewCard = (CardView) inflater.inflate(
                R.layout.wallpaper_preview_card, null);
        mLockscreenPreview = lockscreenPreviewCard.findViewById(R.id.wallpaper_preview_image);
        lockscreenPreviewCard.findViewById(R.id.workspace_surface).setVisibility(View.GONE);
        lockscreenPreviewCard.findViewById(R.id.wallpaper_surface).setVisibility(View.GONE);
        View lockOverlay = lockscreenPreviewCard.findViewById(R.id.lock_overlay);
        lockOverlay.setVisibility(View.VISIBLE);
        mLockScreenOverlayUpdater = new LockScreenOverlayUpdater(
                getContext(), lockOverlay, getLifecycle());
        mWallPaperPreviews.add(lockscreenPreviewCard);

        mPreviewPager = view.findViewById(R.id.wallpaper_preview_pager);
        if (mPreviewPager.isRtl()) {
            Collections.reverse(mWallPaperPreviews);
        }
        mPreviewPager.setAdapter(new PreviewPagerAdapter(mWallPaperPreviews));
        mPreviewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset,
                    int positionOffsetPixels) {
                // For live wallpaper, show its thumbnail when scrolling.
                if (mWallpaperConnection != null && mWallpaperConnection.isEngineReady()
                        && mHomePreviewWallpaperInfo instanceof LiveWallpaperInfo) {
                    if (positionOffset == 0.0f) {
                        // The page is not moved. Show live wallpaper.
                        mWallpaperSurface.setZOrderMediaOverlay(false);
                    } else {
                        // The page is moving. Show live wallpaper's thumbnail.
                        mWallpaperSurface.setZOrderMediaOverlay(true);
                    }
                }

                if (mWallpaperConnection != null && mWallpaperConnection.isEngineReady()
                        && mLockPreviewWallpaperInfo instanceof LiveWallpaperInfo) {
                    if (positionOffset == 0.0f) {
                        // The page is not moved. Show live wallpaper.
                        LiveTileOverlay.INSTANCE.attach(mLockscreenPreview.getOverlay());
                    } else {
                        // The page is moving. Show live wallpaper's thumbnail.
                        LiveTileOverlay.INSTANCE.detach(mLockscreenPreview.getOverlay());
                    }
                } else {
                    LiveTileOverlay.INSTANCE.detach(mLockscreenPreview.getOverlay());
                }
            }

            @Override
            public void onPageSelected(int i) {
                mSelectedPreviewPage = i;
                if (mIndividualPickerFragment != null && mIndividualPickerFragment.isVisible()) {
                    mIndividualPickerFragment.highlightAppliedWallpaper(i);
                }
            }

            @Override
            public void onPageScrollStateChanged(int i) {
            }
        });
        setupCurrentWallpaperPreview(view);

        ViewGroup fragmentContainer = view.findViewById(R.id.category_fragment_container);
        mBottomSheetBehavior = BottomSheetBehavior.from(fragmentContainer);
        mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
            @Override
            public void onStateChanged(@NonNull View bottomSheet, int newState) {
                if (mIsCollapsingByUserSelecting) {
                    mIsCollapsingByUserSelecting = newState != STATE_COLLAPSED;
                    return;
                }

                if (mIndividualPickerFragment != null && mIndividualPickerFragment.isVisible()) {
                    mIndividualPickerFragment.resizeLayout(newState == STATE_COLLAPSED
                            ? mBottomSheetBehavior.getPeekHeight() : MATCH_PARENT);
                }
            }

            @Override
            public void onSlide(@NonNull View bottomSheet, float slideOffset) {

            }
        });
        fragmentContainer.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View containerView, int left, int top, int right,
                    int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                int minimumHeight = containerView.getHeight() - mPreviewPager.getMeasuredHeight();
                mBottomSheetBehavior.setPeekHeight(minimumHeight);
                containerView.setMinimumHeight(minimumHeight);
                ((CardView) mHomePreview.getParent())
                        .setRadius(SizeCalculator.getPreviewCornerRadius(
                                getActivity(), homePreviewCard.getMeasuredWidth()));
                if (mLockscreenPreview != null) {
                    ((CardView) mLockscreenPreview.getParent())
                            .setRadius(SizeCalculator.getPreviewCornerRadius(
                                    getActivity(), mLockscreenPreview.getMeasuredWidth()));
                }
            }});
        fragmentContainer.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
            @Override
            public void onChildViewAdded(View parent, View child) {
                child.requestApplyInsets();
            }

            @Override
            public void onChildViewRemoved(View parent, View child) {
            }
        });

        setUpToolbar(view);

        getChildFragmentManager()
                .beginTransaction()
                .replace(R.id.category_fragment_container, mCategorySelectorFragment)
                .commitNow();
        return view;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        updateWallpaperSurface();
        updateWorkspaceSurface();
    }

    @Override
    public CharSequence getDefaultTitle() {
        return getContext().getString(R.string.app_name);
    }

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

        // The wallpaper may have been set while this fragment was paused, so force refresh the current
        // wallpapers and presentation mode.
        if (!mShowSelectedWallpaper) {
            refreshCurrentWallpapers(/* forceRefresh= */ true);
        }
        if (mWallpaperConnection != null) {
            mWallpaperConnection.setVisibility(true);
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mWallpaperConnection != null) {
            mWallpaperConnection.setVisibility(false);
        }
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        LiveTileOverlay.INSTANCE.detach(mHomePreview.getOverlay());
        LiveTileOverlay.INSTANCE.detach(mLockscreenPreview.getOverlay());
        if (mWallpaperConnection != null) {
            mWallpaperConnection.disconnect();
            mWallpaperConnection = null;
        }
    }

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

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

    @Override
    public void requestCustomPhotoPicker(PermissionChangedListener listener) {
        getFragmentHost().getMyPhotosStarter().requestCustomPhotoPicker(listener);
    }

    @Override
    public void show(String collectionId) {
        mIndividualPickerFragment =
                InjectorProvider.getInjector().getIndividualPickerFragment(collectionId);
        mIndividualPickerFragment.highlightAppliedWallpaper(mSelectedPreviewPage);
        mIndividualPickerFragment.setOnWallpaperSelectedListener(position -> {
            // Scroll to the selected wallpaper and collapse the sheet if needed.
            // Resize and scroll here because we want to let the RecyclerView's scrolling and
            // BottomSheet's collapsing can be executed together instead of scrolling
            // the RecyclerView after the BottomSheet is collapsed.
            mIndividualPickerFragment.resizeLayout(mBottomSheetBehavior.getPeekHeight());
            mIndividualPickerFragment.scrollToPosition(position);
            if (mBottomSheetBehavior.getState() != STATE_COLLAPSED) {
                mIsCollapsingByUserSelecting = true;
                mBottomSheetBehavior.setState(STATE_COLLAPSED);
            }
        });
        getChildFragmentManager()
                .beginTransaction()
                .replace(R.id.category_fragment_container, mIndividualPickerFragment)
                .addToBackStack(null)
                .commit();
        getChildFragmentManager().executePendingTransactions();
    }

    @Override
    public void setToolbarTitle(CharSequence title) {
        setTitle(title);
    }

    @Override
    public void updateThumbnail(WallpaperInfo wallpaperInfo) {
        new android.os.Handler().post(() -> {
            // A config change may have destroyed the activity since the refresh started, so check
            // for that.
            if (getActivity() == null) {
                return;
            }

            mHomePreviewWallpaperInfo = wallpaperInfo;
            mLockPreviewWallpaperInfo = wallpaperInfo;
            updateThumbnail(mHomePreviewWallpaperInfo, mHomePreview, true);
            updateThumbnail(mLockPreviewWallpaperInfo, mLockscreenPreview, false);
            mShowSelectedWallpaper = true;
        });
    }

    @Override
    public void restoreThumbnails() {
        refreshCurrentWallpapers(/* forceRefresh= */ true);
        mShowSelectedWallpaper = false;
    }

    @Override
    public void onDestinationSet(@WallpaperPersister.Destination int destination) {
        if (destination == WallpaperPersister.DEST_BOTH) {
            return;
        }
        mPreviewPager.switchPreviewPage(destination);
    }

    @Override
    public boolean onBackPressed() {
        Fragment childFragment = getChildFragmentManager().findFragmentById(
                R.id.category_fragment_container);
        return childFragment instanceof BottomActionBarFragment
                && ((BottomActionBarFragment) childFragment).onBackPressed();
    }

    /**
     * Pops the child fragment from the stack if {@link CategoryFragment} is visible to the users.
     *
     * @return {@code true} if the child fragment is popped, {@code false} otherwise.
     */
    public boolean popChildFragment() {
        return isVisible() && getChildFragmentManager().popBackStackImmediate();
    }

    /**
     * Inserts the given category into the categories list in priority order.
     */
    void addCategory(Category category, boolean loading) {
        mCategorySelectorFragment.addCategory(category, loading);
    }

    void removeCategory(Category category) {
        mCategorySelectorFragment.removeCategory(category);
    }

    void updateCategory(Category category) {
        mCategorySelectorFragment.updateCategory(category);
    }

    void clearCategories() {
        mCategorySelectorFragment.clearCategories();
    }

    /**
     * Notifies the CategoryFragment that no further categories are expected so it may hide
     * the loading indicator.
     */
    void doneFetchingCategories() {
        mCategorySelectorFragment.doneFetchingCategories();
    }

    private boolean canShowCurrentWallpaper() {
        Activity activity = getActivity();
        CategoryFragmentHost host = getFragmentHost();
        PackageManager packageManager = activity.getPackageManager();
        String packageName = activity.getPackageName();

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

    private void showCurrentWallpaper(View rootView, boolean show) {
        rootView.findViewById(R.id.wallpaper_preview_pager)
                .setVisibility(show ? View.VISIBLE : View.GONE);
        rootView.findViewById(R.id.permission_needed)
                .setVisibility(show ? View.GONE : View.VISIBLE);
    }

    private void setupCurrentWallpaperPreview(View rootView) {
        if (canShowCurrentWallpaper()) {
            showCurrentWallpaper(rootView, true);
        } else {
            showCurrentWallpaper(rootView, false);

            Button mAllowAccessButton = rootView
                    .findViewById(R.id.permission_needed_allow_access_button);
            mAllowAccessButton.setOnClickListener(view ->
                    getFragmentHost().requestExternalStoragePermission(
                            new PermissionChangedListener() {

                                @Override
                                public void onPermissionsGranted() {
                                    showCurrentWallpaper(rootView, true);
                                    mCategorySelectorFragment.notifyDataSetChanged();
                                }

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

            // 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 explanationView = rootView.findViewById(R.id.permission_needed_explanation);
            explanationView.setText(explanation);
        }
    }

    private void showPermissionNeededDialog() {
        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, /* onClickListener= */ null)
                .setNegativeButton(
                        R.string.settings_button_label,
                        (dialogInterface, i) -> {
                            Intent appInfoIntent = new Intent();
                            appInfoIntent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                            Uri uri = Uri.fromParts("package",
                                    getActivity().getPackageName(), /* fragment= */ null);
                            appInfoIntent.setData(uri);
                            startActivityForResult(appInfoIntent, SETTINGS_APP_INFO_REQUEST_CODE);
                        })
                .create();
        dialog.show();
    }

    private CategoryFragmentHost getFragmentHost() {
        return (CategoryFragmentHost) getActivity();
    }

    private Intent getWallpaperIntent(android.app.WallpaperInfo info) {
        return new Intent(WallpaperService.SERVICE_INTERFACE)
                .setClassName(info.getPackageName(), info.getServiceName());
    }

    /**
     * Obtains the {@link WallpaperInfo} object(s) representing the wallpaper(s) currently set to
     * the device from the {@link CurrentWallpaperInfoFactory}.
     */
    private void refreshCurrentWallpapers(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() {
                        final Activity activity = getActivity();
                        // A config change may have destroyed the activity since the refresh
                        // started, so check for that.
                        if (activity == null) {
                            return;
                        }

                        mHomePreviewWallpaperInfo = homeWallpaper;
                        mLockPreviewWallpaperInfo =
                                lockWallpaper == null ? homeWallpaper : lockWallpaper;
                        updateThumbnail(mHomePreviewWallpaperInfo, mHomePreview, true);
                        updateThumbnail(mLockPreviewWallpaperInfo, mLockscreenPreview, false);
                    }
                });
            }
        }, forceRefresh);
    }

    private void setUpLiveWallpaperPreview(WallpaperInfo homeWallpaper) {
        Activity activity = getActivity();
        if (activity == null) {
            return;
        }
        if (mWallpaperConnection != null) {
            mWallpaperConnection.disconnect();
        }
        ImageView previewView = mSelectedPreviewPage == 0 ? mHomePreview : mLockscreenPreview;
        previewView.getLocationOnScreen(mLivePreviewLocation);
        mPreviewGlobalRect.set(0, 0, previewView.getMeasuredWidth(),
                previewView.getMeasuredHeight());
        mPreviewLocalRect.set(mPreviewGlobalRect);
        mPreviewGlobalRect.offset(mLivePreviewLocation[0], mLivePreviewLocation[1]);

        mWallpaperConnection = new WallpaperConnection(
                getWallpaperIntent(homeWallpaper.getWallpaperComponent()), activity,
                new WallpaperConnectionListener() {
                    @Override
                    public void onEngineShown() {

                    }
                }, mPreviewGlobalRect);

        LiveTileOverlay.INSTANCE.update(new RectF(mPreviewLocalRect),
                ((CardView) previewView.getParent()).getRadius());

        mWallpaperConnection.setVisibility(true);
        previewView.post(() -> {
            if (!mWallpaperConnection.connect()) {
                mWallpaperConnection = null;
                LiveTileOverlay.INSTANCE.detach(previewView.getOverlay());
            }
        });
    }

    private void updateThumbnail(WallpaperInfo wallpaperInfo, ImageView thumbnailView,
                                 boolean isHomeWallpaper) {
        if (wallpaperInfo == null) {
            return;
        }

        if (thumbnailView == null) {
            return;
        }

        Activity activity = getActivity();
        if (activity == null) {
            return;
        }

        UserEventLogger eventLogger = InjectorProvider.getInjector().getUserEventLogger(activity);

        boolean renderInImageWallpaperSurface =
                !(wallpaperInfo instanceof LiveWallpaperInfo) && isHomeWallpaper;
        wallpaperInfo.getThumbAsset(activity.getApplicationContext())
                .loadPreviewImage(activity,
                        renderInImageWallpaperSurface ? mHomeImageWallpaper : thumbnailView,
                        getResources().getColor(R.color.secondary_color));
        if (isHomeWallpaper) {
            LiveTileOverlay.INSTANCE.detach(thumbnailView.getOverlay());
            if (wallpaperInfo instanceof LiveWallpaperInfo) {
                wallpaperInfo.getThumbAsset(activity.getApplicationContext()).loadPreviewImage(
                        activity, mHomeImageWallpaper,
                        getResources().getColor(R.color.secondary_color));
                setUpLiveWallpaperPreview(wallpaperInfo);
            } else {
                if (mWallpaperConnection != null) {
                    mWallpaperConnection.disconnect();
                    mWallpaperConnection = null;
                }
            }
        } else {
            // lock screen wallpaper
            if (wallpaperInfo instanceof LiveWallpaperInfo) {
                LiveTileOverlay.INSTANCE.attach(thumbnailView.getOverlay());
            } else {
                LiveTileOverlay.INSTANCE.detach(thumbnailView.getOverlay());
            }

            WallpaperColorsLoader.getWallpaperColors(
                    getContext(),
                    wallpaperInfo.getThumbAsset(getContext()),
                    thumbnailView.getMeasuredWidth(),
                    thumbnailView.getMeasuredHeight(),
                    mLockScreenOverlayUpdater::setColor);
        }

        thumbnailView.setOnClickListener(view -> {
            getFragmentHost().showViewOnlyPreview(wallpaperInfo);
            eventLogger.logCurrentWallpaperPreviewed();
        });
    }

    private void updateWallpaperSurface() {
        mWallpaperSurface.getHolder().addCallback(mWallpaperSurfaceCallback);
    }

    private void updateWorkspaceSurface() {
        mWorkspaceSurface.setZOrderMediaOverlay(true);
        mWorkspaceSurface.getHolder().addCallback(mWorkspaceSurfaceCallback);
    }

    private final SurfaceHolder.Callback mWallpaperSurfaceCallback = new SurfaceHolder.Callback() {

        private Surface mLastSurface;

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            if (mLastSurface != holder.getSurface()) {
                mLastSurface = holder.getSurface();
                mHomeImageWallpaper = new ImageView(getContext());
                mHomeImageWallpaper.setBackgroundColor(
                        ContextCompat.getColor(getContext(), R.color.primary_color));
                mHomeImageWallpaper.measure(makeMeasureSpec(mHomePreview.getWidth(), EXACTLY),
                        makeMeasureSpec(mHomePreview.getHeight(), EXACTLY));
                mHomeImageWallpaper.layout(0, 0, mHomePreview.getWidth(), mHomePreview.getHeight());

                SurfaceControlViewHost host = new SurfaceControlViewHost(getContext(),
                        getContext().getDisplay(), mWallpaperSurface.getHostToken());
                host.setView(mHomeImageWallpaper, mHomeImageWallpaper.getWidth(),
                        mHomeImageWallpaper.getHeight());
                mWallpaperSurface.setChildSurfacePackage(host.getSurfacePackage());
            }
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) { }
    };

    private class PreviewPagerAdapter extends PagerAdapter {

        private List<View> mPages;

        PreviewPagerAdapter(List<View> pages) {
            mPages = pages;
        }

        @Override
        public void destroyItem(@NonNull ViewGroup container, int position,
                                @NonNull Object object) {
            container.removeView((View) object);
        }

        @NonNull
        @Override
        public Object instantiateItem(@NonNull ViewGroup container, int position) {
            View view = mPages.get(position);
            container.addView(view);
            return view;
        }

        @Override
        public int getCount() {
            return mPages.size();
        }

        @Override
        public boolean isViewFromObject(@NonNull View view, @NonNull Object o) {
            return view == o;
        }
    }
}
