/*
 * Copyright 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.car.media;

import static android.car.media.CarMediaManager.MEDIA_SOURCE_MODE_BROWSE;

import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.os.Bundle;
import android.util.Log;
import android.util.Size;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.RecyclerView;

import com.android.car.apps.common.BackgroundImageView;
import com.android.car.apps.common.imaging.ImageBinder;
import com.android.car.apps.common.imaging.ImageBinder.PlaceholderType;
import com.android.car.apps.common.imaging.ImageViewBinder;
import com.android.car.apps.common.util.ViewUtils;
import com.android.car.media.common.MediaItemMetadata;
import com.android.car.media.common.MetadataController;
import com.android.car.media.common.PlaybackControlsActionBar;
import com.android.car.media.common.playback.PlaybackViewModel;
import com.android.car.media.common.source.MediaSourceViewModel;
import com.android.car.media.widgets.AppBarController;
import com.android.car.ui.recyclerview.ContentLimiting;
import com.android.car.ui.recyclerview.ScrollingLimitedViewHolder;
import com.android.car.ui.toolbar.MenuItem;
import com.android.car.ui.toolbar.Toolbar;
import com.android.car.ui.utils.DirectManipulationHelper;
import com.android.car.uxr.LifeCycleObserverUxrContentLimiter;
import com.android.car.uxr.UxrContentLimiterImpl;

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


/**
 * A {@link Fragment} that implements both the playback and the content forward browsing experience.
 * It observes a {@link PlaybackViewModel} and updates its information depending on the currently
 * playing media source through the {@link android.media.session.MediaSession} API.
 */
public class PlaybackFragment extends Fragment {
    private static final String TAG = "PlaybackFragment";

    private LifeCycleObserverUxrContentLimiter mUxrContentLimiter;
    private ImageBinder<MediaItemMetadata.ArtworkRef> mAlbumArtBinder;
    private AppBarController mAppBarController;
    private BackgroundImageView mAlbumBackground;
    private View mBackgroundScrim;
    private View mControlBarScrim;
    private PlaybackControlsActionBar mPlaybackControls;
    private QueueItemsAdapter mQueueAdapter;
    private RecyclerView mQueue;
    private ViewGroup mSeekBarContainer;
    private SeekBar mSeekBar;
    private List<View> mViewsToHideForCustomActions;
    private List<View> mViewsToHideWhenQueueIsVisible;
    private List<View> mViewsToShowWhenQueueIsVisible;
    private List<View> mViewsToHideImmediatelyWhenQueueIsVisible;
    private List<View> mViewsToShowImmediatelyWhenQueueIsVisible;

    private DefaultItemAnimator mItemAnimator;

    private MetadataController mMetadataController;

    private PlaybackFragmentListener mListener;

    private PlaybackViewModel.PlaybackController mController;
    private Long mActiveQueueItemId;

    private boolean mHasQueue;
    private boolean mQueueIsVisible;
    private boolean mShowTimeForActiveQueueItem;
    private boolean mShowIconForActiveQueueItem;
    private boolean mShowThumbnailForQueueItem;
    private boolean mShowSubtitleForQueueItem;

    private boolean mShowLinearProgressBar;

    private int mFadeDuration;

    private MediaActivity.ViewModel mViewModel;

    private MenuItem mQueueMenuItem;

    /**
     * PlaybackFragment listener
     */
    public interface PlaybackFragmentListener {
        /**
         * Invoked when the user clicks on the collapse button
         */
        void onCollapse();
    }

    public class QueueViewHolder extends RecyclerView.ViewHolder {

        private final View mView;
        private final ViewGroup mThumbnailContainer;
        private final ImageView mThumbnail;
        private final View mSpacer;
        private final TextView mTitle;
        private final TextView mSubtitle;
        private final TextView mCurrentTime;
        private final TextView mMaxTime;
        private final TextView mTimeSeparator;
        private final ImageView mActiveIcon;

        private final ImageViewBinder<MediaItemMetadata.ArtworkRef> mThumbnailBinder;

        QueueViewHolder(View itemView) {
            super(itemView);
            mView = itemView;
            mThumbnailContainer = itemView.findViewById(R.id.thumbnail_container);
            mThumbnail = itemView.findViewById(R.id.thumbnail);
            mSpacer = itemView.findViewById(R.id.spacer);
            mTitle = itemView.findViewById(R.id.queue_list_item_title);
            mSubtitle = itemView.findViewById(R.id.queue_list_item_subtitle);
            mCurrentTime = itemView.findViewById(R.id.current_time);
            mMaxTime = itemView.findViewById(R.id.max_time);
            mTimeSeparator = itemView.findViewById(R.id.separator);
            mActiveIcon = itemView.findViewById(R.id.now_playing_icon);

            Size maxArtSize = MediaAppConfig.getMediaItemsBitmapMaxSize(itemView.getContext());
            mThumbnailBinder = new ImageViewBinder<>(maxArtSize, mThumbnail);
        }

        void bind(MediaItemMetadata item) {
            mView.setOnClickListener(v -> onQueueItemClicked(item));

            ViewUtils.setVisible(mThumbnailContainer, mShowThumbnailForQueueItem);
            if (mShowThumbnailForQueueItem) {
                Context context = mView.getContext();
                mThumbnailBinder.setImage(context, item != null ? item.getArtworkKey() : null);
            }

            ViewUtils.setVisible(mSpacer, !mShowThumbnailForQueueItem);

            mTitle.setText(item.getTitle());

            boolean active = mActiveQueueItemId != null && Objects.equals(mActiveQueueItemId,
                    item.getQueueId());
            if (active) {
                mCurrentTime.setText(mQueueAdapter.getCurrentTime());
                mMaxTime.setText(mQueueAdapter.getMaxTime());
            }
            boolean shouldShowTime =
                    mShowTimeForActiveQueueItem && active && mQueueAdapter.getTimeVisible();
            ViewUtils.setVisible(mCurrentTime, shouldShowTime);
            ViewUtils.setVisible(mMaxTime, shouldShowTime);
            ViewUtils.setVisible(mTimeSeparator, shouldShowTime);

            mView.setSelected(active);

            boolean shouldShowIcon = mShowIconForActiveQueueItem && active;
            ViewUtils.setVisible(mActiveIcon, shouldShowIcon);

            if (mShowSubtitleForQueueItem) {
                mSubtitle.setText(item.getSubtitle());
            }
        }

        void onViewAttachedToWindow() {
            if (mShowThumbnailForQueueItem) {
                Context context = mView.getContext();
                mThumbnailBinder.maybeRestartLoading(context);
            }
        }

        void onViewDetachedFromWindow() {
            if (mShowThumbnailForQueueItem) {
                Context context = mView.getContext();
                mThumbnailBinder.maybeCancelLoading(context);
            }
        }
    }


    private class QueueItemsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
            implements ContentLimiting {

        private static final int CLAMPED_MESSAGE_VIEW_TYPE = -1;
        private static final int QUEUE_ITEM_VIEW_TYPE = 0;

        private UxrPivotFilter mUxrPivotFilter;
        private List<MediaItemMetadata> mQueueItems = Collections.emptyList();
        private String mCurrentTimeText = "";
        private String mMaxTimeText = "";
        /** Index in {@link #mQueueItems}. */
        private Integer mActiveItemIndex;
        private boolean mTimeVisible;
        private Integer mScrollingLimitedMessageResId;

        QueueItemsAdapter() {
            mUxrPivotFilter = UxrPivotFilter.PASS_THROUGH;
        }

        @Override
        public void setMaxItems(int maxItems) {
            if (maxItems >= 0) {
                mUxrPivotFilter = new UxrPivotFilterImpl(this, maxItems);
            } else {
                mUxrPivotFilter = UxrPivotFilter.PASS_THROUGH;
            }
            applyFilterToQueue();
        }

        @Override
        public void setScrollingLimitedMessageResId(int resId) {
            if (mScrollingLimitedMessageResId == null || mScrollingLimitedMessageResId != resId) {
                mScrollingLimitedMessageResId = resId;
                mUxrPivotFilter.invalidateMessagePositions();
            }
        }

        @Override
        public int getConfigurationId() {
            return R.id.playback_fragment_now_playing_list_uxr_config;
        }

        void setItems(@Nullable List<MediaItemMetadata> items) {
            List<MediaItemMetadata> newQueueItems =
                new ArrayList<>(items != null ? items : Collections.emptyList());
            if (newQueueItems.equals(mQueueItems)) {
                return;
            }
            mQueueItems = newQueueItems;
            updateActiveItem(/* listIsNew */ true);
        }

        private int getActiveItemIndex() {
            return mActiveItemIndex != null ? mActiveItemIndex : 0;
        }

        private int getQueueSize() {
            return (mQueueItems != null) ? mQueueItems.size() : 0;
        }


        /**
         * Returns the position of the active item if there is one, otherwise returns
         * @link UxrPivotFilter#INVALID_POSITION}.
         */
        private int getActiveItemPosition() {
            if (mActiveItemIndex == null) {
                return UxrPivotFilter.INVALID_POSITION;
            }
            return mUxrPivotFilter.indexToPosition(mActiveItemIndex);
        }

        private void invalidateActiveItemPosition() {
            int position = getActiveItemPosition();
            if (position != UxrPivotFilterImpl.INVALID_POSITION) {
                notifyItemChanged(position);
            }
        }

        private void scrollToActiveItemPosition() {
            int position = getActiveItemPosition();
            if (position != UxrPivotFilterImpl.INVALID_POSITION) {
                mQueue.scrollToPosition(position);
            }
        }

        private void applyFilterToQueue() {
            mUxrPivotFilter.recompute(getQueueSize(), getActiveItemIndex());
            notifyDataSetChanged();
        }

        // Updates mActiveItemPos, then scrolls the queue to mActiveItemPos.
        // It should be called when the active item (mActiveQueueItemId) changed or
        // the queue items (mQueueItems) changed.
        void updateActiveItem(boolean listIsNew) {
            if (mQueueItems == null || mActiveQueueItemId == null) {
                mActiveItemIndex = null;
                applyFilterToQueue();
                return;
            }
            Integer activeItemPos = null;
            for (int i = 0; i < mQueueItems.size(); i++) {
                if (Objects.equals(mQueueItems.get(i).getQueueId(), mActiveQueueItemId)) {
                    activeItemPos = i;
                    break;
                }
            }

            // Invalidate the previous active item so it gets redrawn as a normal one.
            invalidateActiveItemPosition();

            mActiveItemIndex = activeItemPos;
            if (listIsNew) {
                applyFilterToQueue();
            } else {
                mUxrPivotFilter.updatePivotIndex(getActiveItemIndex());
            }

            scrollToActiveItemPosition();
            invalidateActiveItemPosition();
        }

        void setCurrentTime(String currentTime) {
            if (!mCurrentTimeText.equals(currentTime)) {
                mCurrentTimeText = currentTime;
                invalidateActiveItemPosition();
            }
        }

        void setMaxTime(String maxTime) {
            if (!mMaxTimeText.equals(maxTime)) {
                mMaxTimeText = maxTime;
                invalidateActiveItemPosition();
            }
        }

        void setTimeVisible(boolean visible) {
            if (mTimeVisible != visible) {
                mTimeVisible = visible;
                invalidateActiveItemPosition();
            }
        }

        String getCurrentTime() {
            return mCurrentTimeText;
        }

        String getMaxTime() {
            return mMaxTimeText;
        }

        boolean getTimeVisible() {
            return mTimeVisible;
        }

        @Override
        public final int getItemViewType(int position) {
            if (mUxrPivotFilter.positionToIndex(position) == UxrPivotFilterImpl.INVALID_INDEX) {
                return CLAMPED_MESSAGE_VIEW_TYPE;
            } else {
                return QUEUE_ITEM_VIEW_TYPE;
            }
        }

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            if (viewType == CLAMPED_MESSAGE_VIEW_TYPE) {
                return ScrollingLimitedViewHolder.create(parent);
            }
            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            return new QueueViewHolder(inflater.inflate(R.layout.queue_list_item, parent, false));
        }

        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder vh, int position) {
            if (vh instanceof QueueViewHolder) {
                int index = mUxrPivotFilter.positionToIndex(position);
                if (index != UxrPivotFilterImpl.INVALID_INDEX) {
                    int size = mQueueItems.size();
                    if (0 <= index && index < size) {
                        QueueViewHolder holder = (QueueViewHolder) vh;
                        holder.bind(mQueueItems.get(index));
                    } else {
                        Log.e(TAG, "onBindViewHolder pos: " + position + " gave index: " + index +
                                " out of bounds size: " + size + " " + mUxrPivotFilter.toString());
                    }
                } else {
                    Log.e(TAG, "onBindViewHolder invalid position " + position + " " +
                            mUxrPivotFilter.toString());
                }
            } else if (vh instanceof ScrollingLimitedViewHolder) {
                ScrollingLimitedViewHolder holder = (ScrollingLimitedViewHolder) vh;
                holder.bind(mScrollingLimitedMessageResId);
            } else {
                throw new IllegalArgumentException("unknown holder class " + vh.getClass());
            }
        }

        @Override
        public void onViewAttachedToWindow(@NonNull RecyclerView.ViewHolder vh) {
            super.onViewAttachedToWindow(vh);
            if (vh instanceof QueueViewHolder) {
                QueueViewHolder holder = (QueueViewHolder) vh;
                holder.onViewAttachedToWindow();
            }
        }

        @Override
        public void onViewDetachedFromWindow(@NonNull RecyclerView.ViewHolder vh) {
            super.onViewDetachedFromWindow(vh);
            if (vh instanceof QueueViewHolder) {
                QueueViewHolder holder = (QueueViewHolder) vh;
                holder.onViewDetachedFromWindow();
            }
        }

        @Override
        public int getItemCount() {
            return mUxrPivotFilter.getFilteredCount();
        }

        @Override
        public long getItemId(int position) {
            int index = mUxrPivotFilter.positionToIndex(position);
            if (index != UxrPivotFilterImpl.INVALID_INDEX) {
                return mQueueItems.get(position).getQueueId();
            } else {
                return RecyclerView.NO_ID;
            }
        }
    }

    private static class QueueTopItemDecoration extends RecyclerView.ItemDecoration {
        int mHeight;
        int mDecorationPosition;

        QueueTopItemDecoration(int height, int decorationPosition) {
            mHeight = height;
            mDecorationPosition = decorationPosition;
        }

        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
                RecyclerView.State state) {
            super.getItemOffsets(outRect, view, parent, state);
            if (parent.getChildAdapterPosition(view) == mDecorationPosition) {
                outRect.top = mHeight;
            }
        }
    }

    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, final ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_playback, container, false);
        mAlbumBackground = view.findViewById(R.id.playback_background);
        mQueue = view.findViewById(R.id.queue_list);
        mSeekBarContainer = view.findViewById(R.id.seek_bar_container);
        mSeekBar = view.findViewById(R.id.seek_bar);
        DirectManipulationHelper.setSupportsRotateDirectly(mSeekBar, true);
        mAppBarController = new AppBarController(view);

        mAppBarController.setTitle(R.string.fragment_playback_title);
        mAppBarController.setBackgroundShown(false);
        mAppBarController.setNavButtonMode(Toolbar.NavButtonMode.DOWN);
        mAppBarController.setState(Toolbar.State.SUBPAGE);

        // Update toolbar's logo
        MediaSourceViewModel mediaSourceViewModel = getMediaSourceViewModel();
        mediaSourceViewModel.getPrimaryMediaSource().observe(this, mediaSource ->
                mAppBarController.setLogo(mediaSource != null
                    ? new BitmapDrawable(getResources(), mediaSource.getCroppedPackageIcon())
                    : null));

        mBackgroundScrim = view.findViewById(R.id.background_scrim);
        ViewUtils.setVisible(mBackgroundScrim, false);
        mControlBarScrim = view.findViewById(R.id.control_bar_scrim);
        if (mControlBarScrim != null) {
            ViewUtils.setVisible(mControlBarScrim, false);
            mControlBarScrim.setOnClickListener(scrim -> mPlaybackControls.close());
            mControlBarScrim.setClickable(false);
        }

        Resources res = getResources();
        mShowTimeForActiveQueueItem = res.getBoolean(
                R.bool.show_time_for_now_playing_queue_list_item);
        mShowIconForActiveQueueItem = res.getBoolean(
                R.bool.show_icon_for_now_playing_queue_list_item);
        mShowThumbnailForQueueItem = getContext().getResources().getBoolean(
                R.bool.show_thumbnail_for_queue_list_item);
        mShowLinearProgressBar = getContext().getResources().getBoolean(
                R.bool.show_linear_progress_bar);
        mShowSubtitleForQueueItem = getContext().getResources().getBoolean(
            R.bool.show_subtitle_for_queue_list_item);

        if (mSeekBar != null) {
            if (mShowLinearProgressBar) {
                boolean useMediaSourceColor = res.getBoolean(
                        R.bool.use_media_source_color_for_progress_bar);
                int defaultColor = res.getColor(R.color.progress_bar_highlight, null);
                if (useMediaSourceColor) {
                    getPlaybackViewModel().getMediaSourceColors().observe(getViewLifecycleOwner(),
                            sourceColors -> {
                                int color = sourceColors != null
                                        ? sourceColors.getAccentColor(defaultColor)
                                        : defaultColor;
                                setSeekBarColor(color);
                            });
                } else {
                    setSeekBarColor(defaultColor);
                }
            } else {
                mSeekBar.setVisibility(View.GONE);
            }
        }

        mViewModel = ViewModelProviders.of(requireActivity()).get(MediaActivity.ViewModel.class);

        getPlaybackViewModel().getPlaybackController().observe(getViewLifecycleOwner(),
                controller -> mController = controller);
        initPlaybackControls(view.findViewById(R.id.playback_controls));
        initMetadataController(view);
        initQueue();

        // Don't update the visibility of seekBar if show_linear_progress_bar is false.
        ViewUtils.Filter ignoreSeekBarFilter =
            (viewToFilter) -> mShowLinearProgressBar || viewToFilter != mSeekBarContainer;

        mViewsToHideForCustomActions = ViewUtils.getViewsById(view, res,
            R.array.playback_views_to_hide_when_showing_custom_actions, ignoreSeekBarFilter);
        mViewsToHideWhenQueueIsVisible = ViewUtils.getViewsById(view, res,
            R.array.playback_views_to_hide_when_queue_is_visible, ignoreSeekBarFilter);
        mViewsToShowWhenQueueIsVisible = ViewUtils.getViewsById(view, res,
            R.array.playback_views_to_show_when_queue_is_visible, null);
        mViewsToHideImmediatelyWhenQueueIsVisible = ViewUtils.getViewsById(view, res,
            R.array.playback_views_to_hide_immediately_when_queue_is_visible, ignoreSeekBarFilter);
        mViewsToShowImmediatelyWhenQueueIsVisible = ViewUtils.getViewsById(view, res,
            R.array.playback_views_to_show_immediately_when_queue_is_visible, null);

        mAlbumArtBinder = new ImageBinder<>(
                PlaceholderType.BACKGROUND,
                MediaAppConfig.getMediaItemsBitmapMaxSize(getContext()),
                drawable -> mAlbumBackground.setBackgroundDrawable(drawable));

        getPlaybackViewModel().getMetadata().observe(getViewLifecycleOwner(),
                item -> mAlbumArtBinder.setImage(PlaybackFragment.this.getContext(),
                        item != null ? item.getArtworkKey() : null));

        new GuidelinesUpdater(requireActivity(), view);

        mUxrContentLimiter = new LifeCycleObserverUxrContentLimiter(
                new UxrContentLimiterImpl(getContext(), R.xml.uxr_config));
        mUxrContentLimiter.setAdapter(mQueueAdapter);
        getLifecycle().addObserver(mUxrContentLimiter);

        return view;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
    }

    @Override
    public void onDetach() {
        super.onDetach();
    }

    private void initPlaybackControls(PlaybackControlsActionBar playbackControls) {
        mPlaybackControls = playbackControls;
        mPlaybackControls.setModel(getPlaybackViewModel(), getViewLifecycleOwner());
        mPlaybackControls.registerExpandCollapseCallback((expanding) -> {
            Resources res = getContext().getResources();
            int millis = expanding ? res.getInteger(R.integer.control_bar_expand_anim_duration) :
                res.getInteger(R.integer.control_bar_collapse_anim_duration);

            if (mControlBarScrim != null) {
                mControlBarScrim.setClickable(expanding);
            }

            if (expanding) {
                if (mControlBarScrim != null) {
                    ViewUtils.showViewAnimated(mControlBarScrim, millis);
                }
            } else {
                if (mControlBarScrim != null) {
                    ViewUtils.hideViewAnimated(mControlBarScrim, millis);
                }
            }

            if (!mQueueIsVisible) {
                for (View view : mViewsToHideForCustomActions) {
                    if (expanding) {
                        ViewUtils.hideViewAnimated(view, millis);
                    } else {
                        ViewUtils.showViewAnimated(view, millis);
                    }
                }
            }
        });
    }

    private void initQueue() {
        mFadeDuration = getResources().getInteger(
                R.integer.fragment_playback_queue_fade_duration_ms);

        int decorationHeight = getResources().getDimensionPixelSize(
                R.dimen.playback_queue_list_padding_top);
        // Put the decoration above the first item.
        int decorationPosition = 0;
        mQueue.addItemDecoration(new QueueTopItemDecoration(decorationHeight, decorationPosition));

        mQueue.setVerticalFadingEdgeEnabled(
                getResources().getBoolean(R.bool.queue_fading_edge_length_enabled));
        mQueueAdapter = new QueueItemsAdapter();

        getPlaybackViewModel().getPlaybackStateWrapper().observe(getViewLifecycleOwner(),
                state -> {
                    Long itemId = (state != null) ? state.getActiveQueueItemId() : null;
                    if (!Objects.equals(mActiveQueueItemId, itemId)) {
                        mActiveQueueItemId = itemId;
                        mQueueAdapter.updateActiveItem(/* listIsNew */ false);
                    }
                });
        mQueue.setAdapter(mQueueAdapter);

        // Disable item changed animation.
        mItemAnimator = new DefaultItemAnimator();
        mItemAnimator.setSupportsChangeAnimations(false);
        mQueue.setItemAnimator(mItemAnimator);

        // Make sure the AppBar menu reflects the initial state of playback fragment.
        updateAppBarMenu(mHasQueue);
        if (mQueueMenuItem != null) {
            mQueueMenuItem.setActivated(mQueueIsVisible);
        }

        getPlaybackViewModel().getQueue().observe(this, this::setQueue);

        getPlaybackViewModel().hasQueue().observe(getViewLifecycleOwner(), hasQueue -> {
            boolean enableQueue = (hasQueue != null) && hasQueue;
            boolean isQueueVisible = enableQueue && mViewModel.getQueueVisible();

            setQueueState(enableQueue, isQueueVisible);
        });
        getPlaybackViewModel().getProgress().observe(getViewLifecycleOwner(),
                playbackProgress ->
                {
                    mQueueAdapter.setCurrentTime(playbackProgress.getCurrentTimeText().toString());
                    mQueueAdapter.setMaxTime(playbackProgress.getMaxTimeText().toString());
                    mQueueAdapter.setTimeVisible(playbackProgress.hasTime());
                });
    }

    private void setQueue(List<MediaItemMetadata> queueItems) {
        mQueueAdapter.setItems(queueItems);
    }

    private void initMetadataController(View view) {
        ImageView albumArt = view.findViewById(R.id.album_art);
        TextView title = view.findViewById(R.id.title);
        TextView artist = view.findViewById(R.id.artist);
        TextView albumTitle = view.findViewById(R.id.album_title);
        TextView outerSeparator = view.findViewById(R.id.outer_separator);
        TextView curTime = view.findViewById(R.id.current_time);
        TextView innerSeparator = view.findViewById(R.id.inner_separator);
        TextView maxTime = view.findViewById(R.id.max_time);
        SeekBar seekbar = mShowLinearProgressBar ? mSeekBar : null;

        Size maxArtSize = MediaAppConfig.getMediaItemsBitmapMaxSize(view.getContext());
        mMetadataController = new MetadataController(getViewLifecycleOwner(),
                getPlaybackViewModel(), title, artist, albumTitle, outerSeparator,
                curTime, innerSeparator, maxTime, seekbar, albumArt, maxArtSize);
    }

    /**
     * Hides or shows the playback queue when the user clicks the queue button.
     */
    private void toggleQueueVisibility() {
        boolean updatedQueueVisibility = !mQueueIsVisible;
        setQueueState(mHasQueue, updatedQueueVisibility);

        // When the visibility of queue is changed by the user, save the visibility into ViewModel
        // so that we can restore PlaybackFragment properly when needed. If it's changed by media
        // source change (media source changes -> hasQueue becomes false -> queue is hidden), don't
        // save it.
        mViewModel.setQueueVisible(updatedQueueVisibility);
    }

    private void updateAppBarMenu(boolean hasQueue) {
        if (hasQueue && mQueueMenuItem == null) {
            mQueueMenuItem = MenuItem.builder(getContext())
                    .setIcon(R.drawable.ic_queue_button)
                    .setActivatable()
                    .setOnClickListener(button -> toggleQueueVisibility())
                    .build();
        }
        mAppBarController.setMenuItems(
                hasQueue ? Collections.singletonList(mQueueMenuItem) : Collections.emptyList());
    }

    private void setQueueState(boolean hasQueue, boolean visible) {
        if (mHasQueue != hasQueue) {
            mHasQueue = hasQueue;
            updateAppBarMenu(hasQueue);
        }
        if (mQueueMenuItem != null) {
            mQueueMenuItem.setActivated(visible);
        }

        if (mQueueIsVisible != visible) {
            mQueueIsVisible = visible;
            if (mQueueIsVisible) {
                ViewUtils.showViewsAnimated(mViewsToShowWhenQueueIsVisible, mFadeDuration);
                ViewUtils.hideViewsAnimated(mViewsToHideWhenQueueIsVisible, mFadeDuration);
            } else {
                ViewUtils.hideViewsAnimated(mViewsToShowWhenQueueIsVisible, mFadeDuration);
                ViewUtils.showViewsAnimated(mViewsToHideWhenQueueIsVisible, mFadeDuration);
            }
            ViewUtils.setVisible(mViewsToShowImmediatelyWhenQueueIsVisible, mQueueIsVisible);
            ViewUtils.setVisible(mViewsToHideImmediatelyWhenQueueIsVisible, !mQueueIsVisible);
        }
    }

    private void onQueueItemClicked(MediaItemMetadata item) {
        if (mController != null) {
            mController.skipToQueueItem(item.getQueueId());
        }
        boolean switchToPlayback = getResources().getBoolean(
                R.bool.switch_to_playback_view_when_playable_item_is_clicked);
        if (switchToPlayback) {
            toggleQueueVisibility();
        }
    }

    /**
     * Collapses the playback controls.
     */
    public void closeOverflowMenu() {
        mPlaybackControls.close();
    }

    // TODO(b/151174811): Use appropriate modes, instead of just MEDIA_SOURCE_MODE_BROWSE
    private PlaybackViewModel getPlaybackViewModel() {
        return PlaybackViewModel.get(getActivity().getApplication(), MEDIA_SOURCE_MODE_BROWSE);
    }

    private MediaSourceViewModel getMediaSourceViewModel() {
        return MediaSourceViewModel.get(getActivity().getApplication(), MEDIA_SOURCE_MODE_BROWSE);
    }

    private void setSeekBarColor(int color) {
        mSeekBar.setProgressTintList(ColorStateList.valueOf(color));

        // If the thumb drawable consists of a center drawable, only change the color of the center
        // drawable. Otherwise change the color of the entire thumb drawable.
        Drawable thumb = mSeekBar.getThumb();
        if (thumb instanceof LayerDrawable) {
            LayerDrawable thumbDrawable = (LayerDrawable) thumb;
            Drawable thumbCenter = thumbDrawable.findDrawableByLayerId(R.id.thumb_center);
            if (thumbCenter != null) {
                thumbCenter.setColorFilter(color, PorterDuff.Mode.SRC);
                thumbDrawable.setDrawableByLayerId(R.id.thumb_center, thumbCenter);
                return;
            }
        }
        mSeekBar.setThumbTintList(ColorStateList.valueOf(color));
    }

    /**
     * Sets a listener of this PlaybackFragment events. In order to avoid memory leaks, consumers
     * must reset this reference by setting the listener to null.
     */
    public void setListener(PlaybackFragmentListener listener) {
        mListener = listener;
    }
}
