/*
 * Copyright (C) 2015 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.tv.guide;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.media.tv.TvContentRating;
import android.media.tv.TvInputInfo;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.RecycledViewPool;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.TextAppearanceSpan;
import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.common.util.CommonUtils;
import com.android.tv.data.Program;
import com.android.tv.data.Program.CriticScore;
import com.android.tv.data.api.Channel;
import com.android.tv.dvr.DvrDataManager;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.guide.ProgramManager.TableEntriesUpdatedListener;
import com.android.tv.parental.ParentalControlSettings;
import com.android.tv.ui.HardwareLayerAnimatorListenerAdapter;
import com.android.tv.util.TvInputManagerHelper;
import com.android.tv.util.Utils;
import com.android.tv.util.images.ImageCache;
import com.android.tv.util.images.ImageLoader;
import com.android.tv.util.images.ImageLoader.ImageLoaderCallback;
import com.android.tv.util.images.ImageLoader.LoadTvInputLogoTask;

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

/** Adapts the {@link ProgramListAdapter} list to the body of the program guide table. */
class ProgramTableAdapter extends RecyclerView.Adapter<ProgramTableAdapter.ProgramRowViewHolder>
        implements ProgramManager.TableEntryChangedListener {
    private static final String TAG = "ProgramTableAdapter";
    private static final boolean DEBUG = false;

    private final Context mContext;
    private final TvInputManagerHelper mTvInputManagerHelper;
    private final DvrManager mDvrManager;
    private final DvrDataManager mDvrDataManager;
    private final ProgramManager mProgramManager;
    private final AccessibilityManager mAccessibilityManager;
    private final ProgramGuide mProgramGuide;
    private final Handler mHandler = new Handler();
    private final List<ProgramListAdapter> mProgramListAdapters = new ArrayList<>();
    private final RecycledViewPool mRecycledViewPool;
    // views to be be reused when displaying critic scores
    private final List<LinearLayout> mCriticScoreViews;

    private final int mChannelLogoWidth;
    private final int mChannelLogoHeight;
    private final int mImageWidth;
    private final int mImageHeight;
    private final String mProgramTitleForNoInformation;
    private final String mProgramTitleForBlockedChannel;
    private final int mChannelTextColor;
    private final int mChannelBlockedTextColor;
    private final int mDetailTextColor;
    private final int mDetailGrayedTextColor;
    private final int mAnimationDuration;
    private final int mDetailPadding;
    private final TextAppearanceSpan mEpisodeTitleStyle;
    private final String mProgramRecordableText;
    private final String mRecordingScheduledText;
    private final String mRecordingConflictText;
    private final String mRecordingFailedText;
    private final String mRecordingInProgressText;
    private final int mDvrPaddingStartWithTrack;
    private final int mDvrPaddingStartWithOutTrack;

    private RecyclerView mRecyclerView;

    ProgramTableAdapter(Context context, ProgramGuide programGuide) {
        mContext = context;
        mAccessibilityManager =
                (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE);
        mTvInputManagerHelper = TvSingletons.getSingletons(context).getTvInputManagerHelper();
        if (CommonFeatures.DVR.isEnabled(context)) {
            mDvrManager = TvSingletons.getSingletons(context).getDvrManager();
            mDvrDataManager = TvSingletons.getSingletons(context).getDvrDataManager();
        } else {
            mDvrManager = null;
            mDvrDataManager = null;
        }
        mProgramGuide = programGuide;
        mProgramManager = programGuide.getProgramManager();

        Resources res = context.getResources();
        mChannelLogoWidth =
                res.getDimensionPixelSize(
                        R.dimen.program_guide_table_header_column_channel_logo_width);
        mChannelLogoHeight =
                res.getDimensionPixelSize(
                        R.dimen.program_guide_table_header_column_channel_logo_height);
        mImageWidth = res.getDimensionPixelSize(R.dimen.program_guide_table_detail_image_width);
        mImageHeight = res.getDimensionPixelSize(R.dimen.program_guide_table_detail_image_height);
        mProgramTitleForNoInformation = res.getString(R.string.program_title_for_no_information);
        mProgramTitleForBlockedChannel = res.getString(R.string.program_title_for_blocked_channel);
        mChannelTextColor =
                res.getColor(
                        R.color.program_guide_table_header_column_channel_number_text_color, null);
        mChannelBlockedTextColor =
                res.getColor(
                        R.color.program_guide_table_header_column_channel_number_blocked_text_color,
                        null);
        mDetailTextColor = res.getColor(R.color.program_guide_table_detail_title_text_color, null);
        mDetailGrayedTextColor =
                res.getColor(R.color.program_guide_table_detail_title_grayed_text_color, null);
        mAnimationDuration =
                res.getInteger(R.integer.program_guide_table_detail_fade_anim_duration);
        mDetailPadding = res.getDimensionPixelOffset(R.dimen.program_guide_table_detail_padding);
        mProgramRecordableText = res.getString(R.string.dvr_epg_program_recordable);
        mRecordingScheduledText = res.getString(R.string.dvr_epg_program_recording_scheduled);
        mRecordingConflictText = res.getString(R.string.dvr_epg_program_recording_conflict);
        mRecordingFailedText = res.getString(R.string.dvr_epg_program_recording_failed);
        mRecordingInProgressText = res.getString(R.string.dvr_epg_program_recording_in_progress);
        mDvrPaddingStartWithTrack =
                res.getDimensionPixelOffset(R.dimen.program_guide_table_detail_dvr_margin_start);
        mDvrPaddingStartWithOutTrack =
                res.getDimensionPixelOffset(
                        R.dimen.program_guide_table_detail_dvr_margin_start_without_track);

        int episodeTitleSize =
                res.getDimensionPixelSize(
                        R.dimen.program_guide_table_detail_episode_title_text_size);
        ColorStateList episodeTitleColor =
                ColorStateList.valueOf(
                        res.getColor(
                                R.color.program_guide_table_detail_episode_title_text_color, null));
        mEpisodeTitleStyle =
                new TextAppearanceSpan(null, 0, episodeTitleSize, episodeTitleColor, null);

        mCriticScoreViews = new ArrayList<>();
        mRecycledViewPool = new RecycledViewPool();
        mRecycledViewPool.setMaxRecycledViews(
                R.layout.program_guide_table_item,
                context.getResources().getInteger(R.integer.max_recycled_view_pool_epg_table_item));
        mProgramManager.addListener(
                new ProgramManager.ListenerAdapter() {
                    @Override
                    public void onChannelsUpdated() {
                        update();
                    }
                });
        update();
        mProgramManager.addTableEntryChangedListener(this);
    }

    private void update() {
        if (DEBUG) Log.d(TAG, "update " + mProgramManager.getChannelCount() + " channels");
        for (TableEntriesUpdatedListener listener : mProgramListAdapters) {
            mProgramManager.removeTableEntriesUpdatedListener(listener);
        }
        mProgramListAdapters.clear();
        for (int i = 0; i < mProgramManager.getChannelCount(); i++) {
            ProgramListAdapter listAdapter =
                    new ProgramListAdapter(mContext.getResources(), mProgramGuide, i);
            mProgramManager.addTableEntriesUpdatedListener(listAdapter);
            mProgramListAdapters.add(listAdapter);
        }
        if (mRecyclerView != null && mRecyclerView.isComputingLayout()) {
            // it means that RecyclerView is in a lockdown state and any attempt to update adapter
            // contents will result in an exception because adapter contents cannot be changed while
            // RecyclerView is trying to compute the layout
            // postpone the change using a Handler
            mHandler.post(this::notifyDataSetChanged);
        } else {
            notifyDataSetChanged();
        }
    }

    @Override
    public int getItemCount() {
        return mProgramListAdapters.size();
    }

    @Override
    public int getItemViewType(int position) {
        return R.layout.program_guide_table_row;
    }

    @Override
    public void onBindViewHolder(ProgramRowViewHolder holder, int position) {
        holder.onBind(position);
    }

    @Override
    public void onBindViewHolder(ProgramRowViewHolder holder, int position, List<Object> payloads) {
        if (!payloads.isEmpty()) {
            holder.updateDetailView();
        } else {
            super.onBindViewHolder(holder, position, payloads);
        }
    }

    @Override
    public ProgramRowViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
        ProgramRow programRow = (ProgramRow) itemView.findViewById(R.id.row);
        programRow.setRecycledViewPool(mRecycledViewPool);
        return new ProgramRowViewHolder(itemView);
    }

    @Override
    public void onTableEntryChanged(ProgramManager.TableEntry tableEntry) {
        int channelIndex = mProgramManager.getChannelIndex(tableEntry.channelId);
        int pos = mProgramManager.getProgramIdIndex(tableEntry.channelId, tableEntry.getId());
        if (DEBUG) Log.d(TAG, "update(" + channelIndex + ", " + pos + ")");
        if (channelIndex >= 0 && channelIndex < mProgramListAdapters.size()) {
            mProgramListAdapters.get(channelIndex).notifyItemChanged(pos, tableEntry);
            notifyItemChanged(channelIndex, true);
        }
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        mRecyclerView = recyclerView;
        super.onAttachedToRecyclerView(recyclerView);
    }

    @Override
    public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
        super.onDetachedFromRecyclerView(recyclerView);
        mRecyclerView = null;
    }

    class ProgramRowViewHolder extends RecyclerView.ViewHolder
            implements ProgramRow.ChildFocusListener {

        private final ViewGroup mContainer;
        private final ProgramRow mProgramRow;
        private ProgramManager.TableEntry mSelectedEntry;
        private Animator mDetailOutAnimator;
        private Animator mDetailInAnimator;
        private final Runnable mDetailInStarter =
                new Runnable() {
                    @Override
                    public void run() {
                        mProgramRow.removeOnScrollListener(mOnScrollListener);
                        if (mDetailInAnimator != null) {
                            mDetailInAnimator.start();
                        }
                    }
                };
        private final Runnable mUpdateDetailViewRunnable = this::updateDetailView;

        private final RecyclerView.OnScrollListener mOnScrollListener =
                new RecyclerView.OnScrollListener() {
                    @Override
                    public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                        onHorizontalScrolled();
                    }
                };

        private final ViewTreeObserver.OnGlobalFocusChangeListener mGlobalFocusChangeListener =
                new ViewTreeObserver.OnGlobalFocusChangeListener() {
                    @Override
                    public void onGlobalFocusChanged(View oldFocus, View newFocus) {
                        onChildFocus(
                                GuideUtils.isDescendant(mContainer, oldFocus) ? oldFocus : null,
                                GuideUtils.isDescendant(mContainer, newFocus) ? newFocus : null);
                    }
                };

        // Members of Program Details
        private final ViewGroup mDetailView;
        private final ImageView mImageView;
        private final ImageView mBlockView;
        private final TextView mTitleView;
        private final TextView mTimeView;
        private final LinearLayout mCriticScoresLayout;
        private final TextView mDescriptionView;
        private final TextView mAspectRatioView;
        private final TextView mResolutionView;
        private final ImageView mDvrIconView;
        private final TextView mDvrTextIconView;
        private final TextView mDvrStatusView;
        private final ViewGroup mDvrIndicator;

        // Members of Channel Header
        private Channel mChannel;
        private final View mChannelHeaderView;
        private final TextView mChannelNumberView;
        private final TextView mChannelNameView;
        private final ImageView mChannelLogoView;
        private final ImageView mChannelBlockView;
        private final ImageView mInputLogoView;

        private boolean mIsInputLogoVisible;
        private AccessibilityStateChangeListener mAccessibilityStateChangeListener =
                new AccessibilityManager.AccessibilityStateChangeListener() {
                    @Override
                    public void onAccessibilityStateChanged(boolean enable) {
                        enable &= !CommonUtils.isRunningInTest();
                        mChannelHeaderView.setFocusable(enable);
                    }
                };

        ProgramRowViewHolder(View itemView) {
            super(itemView);

            mContainer = (ViewGroup) itemView;
            mContainer.addOnAttachStateChangeListener(
                    new View.OnAttachStateChangeListener() {
                        @Override
                        public void onViewAttachedToWindow(View v) {
                            mContainer
                                    .getViewTreeObserver()
                                    .addOnGlobalFocusChangeListener(mGlobalFocusChangeListener);
                            mAccessibilityManager.addAccessibilityStateChangeListener(
                                    mAccessibilityStateChangeListener);
                        }

                        @Override
                        public void onViewDetachedFromWindow(View v) {
                            mContainer
                                    .getViewTreeObserver()
                                    .removeOnGlobalFocusChangeListener(mGlobalFocusChangeListener);
                            mAccessibilityManager.removeAccessibilityStateChangeListener(
                                    mAccessibilityStateChangeListener);
                        }
                    });
            mProgramRow = (ProgramRow) mContainer.findViewById(R.id.row);

            mDetailView = (ViewGroup) mContainer.findViewById(R.id.detail);
            mImageView = (ImageView) mDetailView.findViewById(R.id.image);
            mBlockView = (ImageView) mDetailView.findViewById(R.id.block);
            mTitleView = (TextView) mDetailView.findViewById(R.id.title);
            mTimeView = (TextView) mDetailView.findViewById(R.id.time);
            mDescriptionView = (TextView) mDetailView.findViewById(R.id.desc);
            mAspectRatioView = (TextView) mDetailView.findViewById(R.id.aspect_ratio);
            mResolutionView = (TextView) mDetailView.findViewById(R.id.resolution);
            mDvrIconView = (ImageView) mDetailView.findViewById(R.id.dvr_icon);
            mDvrTextIconView = (TextView) mDetailView.findViewById(R.id.dvr_text_icon);
            mDvrStatusView = (TextView) mDetailView.findViewById(R.id.dvr_status);
            mDvrIndicator = (ViewGroup) mContainer.findViewById(R.id.dvr_indicator);
            mCriticScoresLayout = (LinearLayout) mDetailView.findViewById(R.id.critic_scores);

            mChannelHeaderView = mContainer.findViewById(R.id.header_column);
            mChannelNumberView = (TextView) mContainer.findViewById(R.id.channel_number);
            mChannelNameView = (TextView) mContainer.findViewById(R.id.channel_name);
            mChannelLogoView = (ImageView) mContainer.findViewById(R.id.channel_logo);
            mChannelBlockView = (ImageView) mContainer.findViewById(R.id.channel_block);
            mInputLogoView = (ImageView) mContainer.findViewById(R.id.input_logo);

            boolean accessibilityEnabled =
                    mAccessibilityManager.isEnabled() && !CommonUtils.isRunningInTest();
            mChannelHeaderView.setFocusable(accessibilityEnabled);
        }

        public void onBind(int position) {
            onBindChannel(mProgramManager.getChannel(position));

            mProgramRow.swapAdapter(mProgramListAdapters.get(position), true);
            mProgramRow.setProgramGuide(mProgramGuide);
            mProgramRow.setChannel(mProgramManager.getChannel(position));
            mProgramRow.setChildFocusListener(this);
            mProgramRow.resetScroll(mProgramGuide.getTimelineRowScrollOffset());

            mDetailView.setVisibility(View.GONE);

            // The bottom-left of the last channel header view will have a rounded corner.
            mChannelHeaderView.setBackgroundResource(
                    (position < mProgramListAdapters.size() - 1)
                            ? R.drawable.program_guide_table_header_column_item_background
                            : R.drawable.program_guide_table_header_column_last_item_background);
        }

        private void onBindChannel(Channel channel) {
            if (DEBUG) Log.d(TAG, "onBindChannel " + channel);

            mChannel = channel;
            mInputLogoView.setVisibility(View.GONE);
            mIsInputLogoVisible = false;
            if (channel == null) {
                mChannelNumberView.setVisibility(View.GONE);
                mChannelNameView.setVisibility(View.GONE);
                mChannelLogoView.setVisibility(View.GONE);
                mChannelBlockView.setVisibility(View.GONE);
                return;
            }

            String displayNumber = channel.getDisplayNumber();
            if (displayNumber == null) {
                mChannelNumberView.setVisibility(View.GONE);
            } else {
                int size;
                if (displayNumber.length() <= 4) {
                    size = R.dimen.program_guide_table_header_column_channel_number_large_font_size;
                } else {
                    size = R.dimen.program_guide_table_header_column_channel_number_small_font_size;
                }
                mChannelNumberView.setTextSize(
                        TypedValue.COMPLEX_UNIT_PX,
                        mChannelNumberView.getContext().getResources().getDimension(size));
                mChannelNumberView.setText(displayNumber);
                mChannelNumberView.setVisibility(View.VISIBLE);
            }

            boolean isChannelLocked = isChannelLocked(channel);
            mChannelNumberView.setTextColor(
                    isChannelLocked ? mChannelBlockedTextColor : mChannelTextColor);

            mChannelLogoView.setImageBitmap(null);
            mChannelLogoView.setVisibility(View.GONE);
            if (isChannelLocked) {
                mChannelNameView.setVisibility(View.GONE);
                mChannelBlockView.setVisibility(View.VISIBLE);
            } else {
                mChannelNameView.setText(channel.getDisplayName());
                mChannelNameView.setVisibility(View.VISIBLE);
                mChannelBlockView.setVisibility(View.GONE);

                mChannel.loadBitmap(
                        itemView.getContext(),
                        Channel.LOAD_IMAGE_TYPE_CHANNEL_LOGO,
                        mChannelLogoWidth,
                        mChannelLogoHeight,
                        createChannelLogoLoadedCallback(this, channel.getId()));
            }
        }

        @Override
        public void onChildFocus(View oldFocus, View newFocus) {
            if (newFocus == null) {
                return;
            } // When the accessibility service is enabled, focus might be put on channel's header
            // or
            // detail view, besides program items.
            if (newFocus == mChannelHeaderView) {
                mSelectedEntry = ((ProgramItemView) mProgramRow.getChildAt(0)).getTableEntry();
            } else if (newFocus == mDetailView) {
                return;
            } else {
                mSelectedEntry = ((ProgramItemView) newFocus).getTableEntry();
            }
            if (oldFocus == null) {
                // Focus moved from other row.
                if (mProgramGuide.getProgramGrid().isInLayout()) {
                    // We need to post runnable to avoid updating detail view when
                    // the recycler view is in layout, which may cause detail view not
                    // laid out according to the updated contents.
                    mHandler.post(mUpdateDetailViewRunnable);
                } else {
                    updateDetailView();
                }
                return;
            }

            if (Program.isProgramValid(mSelectedEntry.program)) {
                Program program = mSelectedEntry.program;
                if (getProgramBlock(program) == null) {
                    program.prefetchPosterArt(itemView.getContext(), mImageWidth, mImageHeight);
                }
            }

            // -1 means the selection goes rightwards and 1 goes leftwards
            int direction = oldFocus.getLeft() < newFocus.getLeft() ? -1 : 1;
            View detailContentView = mDetailView.findViewById(R.id.detail_content);

            if (mDetailInAnimator == null) {
                mDetailOutAnimator =
                        ObjectAnimator.ofPropertyValuesHolder(
                                detailContentView,
                                PropertyValuesHolder.ofFloat(View.ALPHA, 1f, 0f),
                                PropertyValuesHolder.ofFloat(
                                        View.TRANSLATION_X, 0f, direction * mDetailPadding));
                mDetailOutAnimator.setDuration(mAnimationDuration);
                mDetailOutAnimator.addListener(
                        new HardwareLayerAnimatorListenerAdapter(detailContentView) {
                            @Override
                            public void onAnimationEnd(Animator animator) {
                                super.onAnimationEnd(animator);
                                mDetailOutAnimator = null;
                                mHandler.removeCallbacks(mDetailInStarter);
                                mHandler.postDelayed(mDetailInStarter, mAnimationDuration);
                            }
                        });

                mProgramRow.addOnScrollListener(mOnScrollListener);
                mDetailOutAnimator.start();
            } else {
                if (mDetailInAnimator.isStarted()) {
                    mDetailInAnimator.cancel();
                    detailContentView.setAlpha(0);
                }

                mHandler.removeCallbacks(mDetailInStarter);
                mHandler.postDelayed(mDetailInStarter, mAnimationDuration);
            }

            mDetailInAnimator =
                    ObjectAnimator.ofPropertyValuesHolder(
                            detailContentView,
                            PropertyValuesHolder.ofFloat(View.ALPHA, 0f, 1f),
                            PropertyValuesHolder.ofFloat(
                                    View.TRANSLATION_X, direction * -mDetailPadding, 0f));
            mDetailInAnimator.setDuration(mAnimationDuration);
            mDetailInAnimator.addListener(
                    new HardwareLayerAnimatorListenerAdapter(detailContentView) {
                        @Override
                        public void onAnimationStart(Animator animator) {
                            super.onAnimationStart(animator);
                            updateDetailView();
                        }

                        @Override
                        public void onAnimationEnd(Animator animator) {
                            super.onAnimationEnd(animator);
                            mDetailInAnimator = null;
                        }
                    });
        }

        private void updateDetailView() {
            if (mSelectedEntry == null) {
                // The view holder is never on focus before.
                return;
            }
            if (DEBUG) Log.d(TAG, "updateDetailView");
            mCriticScoresLayout.removeAllViews();
            if (Program.isProgramValid(mSelectedEntry.program)) {
                mTitleView.setTextColor(mDetailTextColor);
                Context context = itemView.getContext();
                Program program = mSelectedEntry.program;

                TvContentRating blockedRating = getProgramBlock(program);

                updatePosterArt(null);
                if (blockedRating == null) {
                    program.loadPosterArt(
                            context,
                            mImageWidth,
                            mImageHeight,
                            createProgramPosterArtCallback(this, program));
                }

                String episodeTitle = program.getEpisodeDisplayTitle(mContext);
                if (TextUtils.isEmpty(episodeTitle)) {
                    mTitleView.setText(program.getTitle());
                } else {
                    String title = program.getTitle();
                    String fullTitle = title + "  " + episodeTitle;

                    SpannableString text = new SpannableString(fullTitle);
                    text.setSpan(
                            mEpisodeTitleStyle,
                            fullTitle.length() - episodeTitle.length(),
                            fullTitle.length(),
                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    mTitleView.setText(text);
                }

                updateTextView(mTimeView, program.getDurationString(context));

                boolean trackMetaDataVisible =
                        updateTextView(
                                mAspectRatioView,
                                Utils.getAspectRatioString(
                                        program.getVideoWidth(), program.getVideoHeight()));

                int videoDefinitionLevel =
                        Utils.getVideoDefinitionLevelFromSize(
                                program.getVideoWidth(), program.getVideoHeight());
                trackMetaDataVisible |=
                        updateTextView(
                                mResolutionView,
                                Utils.getVideoDefinitionLevelString(context, videoDefinitionLevel));

                if (mDvrManager != null && mDvrManager.isProgramRecordable(program)) {
                    ScheduledRecording scheduledRecording =
                            mDvrDataManager.getScheduledRecordingForProgramId(program.getId());
                    String statusText = mProgramRecordableText;
                    int iconResId = 0;
                    if (scheduledRecording != null) {
                        if (mDvrManager.isConflicting(scheduledRecording)) {
                            iconResId = R.drawable.ic_warning_white_12dp;
                            statusText = mRecordingConflictText;
                        } else {
                            switch (scheduledRecording.getState()) {
                                case ScheduledRecording.STATE_RECORDING_IN_PROGRESS:
                                    iconResId = R.drawable.ic_recording_program;
                                    statusText = mRecordingInProgressText;
                                    break;
                                case ScheduledRecording.STATE_RECORDING_NOT_STARTED:
                                    iconResId = R.drawable.ic_scheduled_white;
                                    statusText = mRecordingScheduledText;
                                    break;
                                case ScheduledRecording.STATE_RECORDING_FAILED:
                                    iconResId = R.drawable.ic_warning_white_12dp;
                                    statusText = mRecordingFailedText;
                                    break;
                                default:
                                    iconResId = 0;
                            }
                        }
                    }
                    if (iconResId == 0) {
                        mDvrIconView.setVisibility(View.GONE);
                        mDvrTextIconView.setVisibility(View.VISIBLE);
                    } else {
                        mDvrTextIconView.setVisibility(View.GONE);
                        mDvrIconView.setImageResource(iconResId);
                        mDvrIconView.setVisibility(View.VISIBLE);
                    }
                    if (!trackMetaDataVisible) {
                        mDvrIndicator.setPaddingRelative(mDvrPaddingStartWithOutTrack, 0, 0, 0);
                    } else {
                        mDvrIndicator.setPaddingRelative(mDvrPaddingStartWithTrack, 0, 0, 0);
                    }
                    mDvrIndicator.setVisibility(View.VISIBLE);
                    mDvrStatusView.setText(statusText);
                } else {
                    mDvrIndicator.setVisibility(View.GONE);
                }

                if (blockedRating == null) {
                    mBlockView.setVisibility(View.GONE);
                    updateTextView(mDescriptionView, program.getDescription());
                } else {
                    mBlockView.setVisibility(View.VISIBLE);
                    updateTextView(mDescriptionView, getBlockedDescription(blockedRating));
                }
            } else {
                mTitleView.setTextColor(mDetailGrayedTextColor);
                if (mSelectedEntry.isBlocked()) {
                    updateTextView(mTitleView, mProgramTitleForBlockedChannel);
                } else {
                    updateTextView(mTitleView, mProgramTitleForNoInformation);
                }
                mImageView.setVisibility(View.GONE);
                mBlockView.setVisibility(View.GONE);
                mTimeView.setVisibility(View.GONE);
                mDvrIndicator.setVisibility(View.GONE);
                mDescriptionView.setVisibility(View.GONE);
                mAspectRatioView.setVisibility(View.GONE);
                mResolutionView.setVisibility(View.GONE);
            }
        }

        private TvContentRating getProgramBlock(Program program) {
            ParentalControlSettings parental = mTvInputManagerHelper.getParentalControlSettings();
            if (!parental.isParentalControlsEnabled()) {
                return null;
            }
            return parental.getBlockedRating(program.getContentRatings());
        }

        private boolean isChannelLocked(Channel channel) {
            return mTvInputManagerHelper.getParentalControlSettings().isParentalControlsEnabled()
                    && channel.isLocked();
        }

        private String getBlockedDescription(TvContentRating blockedRating) {
            String name =
                    mTvInputManagerHelper
                            .getContentRatingsManager()
                            .getDisplayNameForRating(blockedRating);
            if (TextUtils.isEmpty(name)) {
                return mContext.getString(R.string.program_guide_content_locked);
            } else {
                return TvContentRating.UNRATED.equals(blockedRating)
                        ? mContext.getString(R.string.program_guide_content_locked_unrated)
                        : mContext.getString(R.string.program_guide_content_locked_format, name);
            }
        }

        /**
         * Update tv input logo. It should be called when the visible child item in ProgramGrid
         * changed.
         */
        void updateInputLogo(int lastPosition, boolean forceShow) {
            if (mChannel == null) {
                mInputLogoView.setVisibility(View.GONE);
                mIsInputLogoVisible = false;
                return;
            }

            boolean showLogo = forceShow;
            if (!showLogo) {
                Channel lastChannel = mProgramManager.getChannel(lastPosition);
                if (lastChannel == null
                        || !mChannel.getInputId().equals(lastChannel.getInputId())) {
                    showLogo = true;
                }
            }

            if (showLogo) {
                if (!mIsInputLogoVisible) {
                    mIsInputLogoVisible = true;
                    TvInputInfo info = mTvInputManagerHelper.getTvInputInfo(mChannel.getInputId());
                    if (info != null) {
                        LoadTvInputLogoTask task =
                                new LoadTvInputLogoTask(
                                        itemView.getContext(), ImageCache.getInstance(), info);
                        ImageLoader.loadBitmap(createTvInputLogoLoadedCallback(info, this), task);
                    }
                }
            } else {
                mInputLogoView.setVisibility(View.GONE);
                mInputLogoView.setImageDrawable(null);
                mIsInputLogoVisible = false;
            }
        }

        // The return value of this method will indicate the target view is visible (true)
        // or gone (false).
        private boolean updateTextView(TextView textView, String text) {
            if (!TextUtils.isEmpty(text)) {
                textView.setVisibility(View.VISIBLE);
                textView.setText(text);
                return true;
            } else {
                textView.setVisibility(View.GONE);
                return false;
            }
        }

        private void updatePosterArt(@Nullable Bitmap posterArt) {
            mImageView.setImageBitmap(posterArt);
            mImageView.setVisibility(posterArt == null ? View.GONE : View.VISIBLE);
        }

        private void updateChannelLogo(@Nullable Bitmap logo) {
            mChannelLogoView.setImageBitmap(logo);
            mChannelNameView.setVisibility(View.GONE);
            mChannelLogoView.setVisibility(View.VISIBLE);
        }

        private void updateInputLogoInternal(@NonNull Bitmap tvInputLogo) {
            if (!mIsInputLogoVisible) {
                return;
            }
            mInputLogoView.setImageBitmap(tvInputLogo);
            mInputLogoView.setVisibility(View.VISIBLE);
        }

        private void updateCriticScoreView(
                ProgramRowViewHolder holder,
                final long programId,
                CriticScore criticScore,
                View view) {
            TextView criticScoreSource = (TextView) view.findViewById(R.id.critic_score_source);
            TextView criticScoreText = (TextView) view.findViewById(R.id.critic_score_score);
            ImageView criticScoreLogo = (ImageView) view.findViewById(R.id.critic_score_logo);

            // set the appropriate information in the views
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
                criticScoreSource.setText(
                        Html.fromHtml(criticScore.source, Html.FROM_HTML_MODE_LEGACY));
            } else {
                criticScoreSource.setText(Html.fromHtml(criticScore.source));
            }
            criticScoreText.setText(criticScore.score);
            criticScoreSource.setVisibility(View.VISIBLE);
            criticScoreText.setVisibility(View.VISIBLE);
            ImageLoader.loadBitmap(
                    mContext,
                    criticScore.logoUrl,
                    createCriticScoreLogoCallback(holder, programId, criticScoreLogo));
        }

        private void onHorizontalScrolled() {
            if (mDetailInAnimator != null) {
                mHandler.removeCallbacks(mDetailInStarter);
                mHandler.postDelayed(mDetailInStarter, mAnimationDuration);
            }
        }
    }

    private static ImageLoaderCallback<ProgramRowViewHolder> createCriticScoreLogoCallback(
            ProgramRowViewHolder holder, final long programId, ImageView logoView) {
        return new ImageLoaderCallback<ProgramRowViewHolder>(holder) {
            @Override
            public void onBitmapLoaded(ProgramRowViewHolder holder, @Nullable Bitmap logoImage) {
                if (logoImage == null
                        || holder.mSelectedEntry == null
                        || holder.mSelectedEntry.program == null
                        || holder.mSelectedEntry.program.getId() != programId) {
                    logoView.setVisibility(View.GONE);
                } else {
                    logoView.setImageBitmap(logoImage);
                    logoView.setVisibility(View.VISIBLE);
                }
            }
        };
    }

    private static ImageLoaderCallback<ProgramRowViewHolder> createProgramPosterArtCallback(
            ProgramRowViewHolder holder, final Program program) {
        return new ImageLoaderCallback<ProgramRowViewHolder>(holder) {
            @Override
            public void onBitmapLoaded(ProgramRowViewHolder holder, @Nullable Bitmap posterArt) {
                if (posterArt == null
                        || holder.mSelectedEntry == null
                        || holder.mSelectedEntry.program == null) {
                    return;
                }
                String posterArtUri = holder.mSelectedEntry.program.getPosterArtUri();
                if (posterArtUri == null || !posterArtUri.equals(program.getPosterArtUri())) {
                    return;
                }
                holder.updatePosterArt(posterArt);
            }
        };
    }

    private static ImageLoaderCallback<ProgramRowViewHolder> createChannelLogoLoadedCallback(
            ProgramRowViewHolder holder, final long channelId) {
        return new ImageLoaderCallback<ProgramRowViewHolder>(holder) {
            @Override
            public void onBitmapLoaded(ProgramRowViewHolder holder, @Nullable Bitmap logo) {
                if (logo == null
                        || holder.mChannel == null
                        || holder.mChannel.getId() != channelId) {
                    return;
                }
                holder.updateChannelLogo(logo);
            }
        };
    }

    private static ImageLoaderCallback<ProgramRowViewHolder> createTvInputLogoLoadedCallback(
            final TvInputInfo info, ProgramRowViewHolder holder) {
        return new ImageLoaderCallback<ProgramRowViewHolder>(holder) {
            @Override
            public void onBitmapLoaded(ProgramRowViewHolder holder, @Nullable Bitmap logo) {
                if (logo != null
                        && holder.mChannel != null
                        && info.getId().equals(holder.mChannel.getInputId())) {
                    holder.updateInputLogoInternal(logo);
                }
            }
        };
    }
}
