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

import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.media.tv.TvContentRating;
import android.media.tv.TvInputInfo;
import android.support.annotation.Nullable;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.style.TextAppearanceSpan;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityManager.AccessibilityStateChangeListener;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.android.tv.MainActivity;
import com.android.tv.R;
import com.android.tv.TvSingletons;
import com.android.tv.common.SoftPreconditions;
import com.android.tv.common.feature.CommonFeatures;
import com.android.tv.data.Program;
import com.android.tv.data.StreamInfo;
import com.android.tv.data.api.Channel;
import com.android.tv.dvr.DvrManager;
import com.android.tv.dvr.data.ScheduledRecording;
import com.android.tv.parental.ContentRatingsManager;
import com.android.tv.ui.TvTransitionManager.TransitionLayout;
import com.android.tv.ui.hideable.AutoHideScheduler;
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;

/** A view to render channel banner. */
public class ChannelBannerView extends FrameLayout
        implements TransitionLayout, AccessibilityStateChangeListener {
    private static final String TAG = "ChannelBannerView";
    private static final boolean DEBUG = false;

    /** Show all information at the channel banner. */
    public static final int LOCK_NONE = 0;

    /**
     * Lock program details at the channel banner. This is used when a content is locked so we don't
     * want to show program details including program description text and poster art.
     */
    public static final int LOCK_PROGRAM_DETAIL = 1;

    /**
     * Lock channel information at the channel banner. This is used when a channel is locked so we
     * only want to show input information.
     */
    public static final int LOCK_CHANNEL_INFO = 2;

    private static final int DISPLAYED_CONTENT_RATINGS_COUNT = 3;

    private static final String EMPTY_STRING = "";

    private Program mNoProgram;
    private Program mLockedChannelProgram;
    private static String sClosedCaptionMark;

    private final MainActivity mMainActivity;
    private final Resources mResources;
    private View mChannelView;

    private TextView mChannelNumberTextView;
    private ImageView mChannelLogoImageView;
    private TextView mProgramTextView;
    private ImageView mTvInputLogoImageView;
    private TextView mChannelNameTextView;
    private TextView mProgramTimeTextView;
    private ProgressBar mRemainingTimeView;
    private TextView mRecordingIndicatorView;
    private TextView mClosedCaptionTextView;
    private TextView mAspectRatioTextView;
    private TextView mResolutionTextView;
    private TextView mAudioChannelTextView;
    private TextView[] mContentRatingsTextViews = new TextView[DISPLAYED_CONTENT_RATINGS_COUNT];
    private TextView mProgramDescriptionTextView;
    private String mProgramDescriptionText;
    private View mAnchorView;
    private Channel mCurrentChannel;
    private boolean mCurrentChannelLogoExists;
    private Program mLastUpdatedProgram;
    private final AutoHideScheduler mAutoHideScheduler;
    private final DvrManager mDvrManager;
    private ContentRatingsManager mContentRatingsManager;
    private TvContentRating mBlockingContentRating;

    private int mLockType;
    private boolean mUpdateOnTune;

    private Animator mResizeAnimator;
    private int mCurrentHeight;
    private boolean mProgramInfoUpdatePendingByResizing;

    private final Animator mProgramDescriptionFadeInAnimator;
    private final Animator mProgramDescriptionFadeOutAnimator;

    private final long mShowDurationMillis;
    private final int mChannelLogoImageViewWidth;
    private final int mChannelLogoImageViewHeight;
    private final int mChannelLogoImageViewMarginStart;
    private final int mProgramDescriptionTextViewWidth;
    private final int mChannelBannerTextColor;
    private final int mChannelBannerDimTextColor;
    private final int mResizeAnimDuration;
    private final int mRecordingIconPadding;
    private final Interpolator mResizeInterpolator;

    private final AnimatorListenerAdapter mResizeAnimatorListener =
            new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animator) {
                    mProgramInfoUpdatePendingByResizing = false;
                }

                @Override
                public void onAnimationEnd(Animator animator) {
                    mProgramDescriptionTextView.setAlpha(1f);
                    mResizeAnimator = null;
                    if (mProgramInfoUpdatePendingByResizing) {
                        mProgramInfoUpdatePendingByResizing = false;
                        updateProgramInfo(mLastUpdatedProgram);
                    }
                }
            };

    public ChannelBannerView(Context context) {
        this(context, null);
    }

    public ChannelBannerView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ChannelBannerView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mResources = getResources();
        mMainActivity = (MainActivity) context;

        mShowDurationMillis = mResources.getInteger(R.integer.channel_banner_show_duration);
        mChannelLogoImageViewWidth =
                mResources.getDimensionPixelSize(R.dimen.channel_banner_channel_logo_width);
        mChannelLogoImageViewHeight =
                mResources.getDimensionPixelSize(R.dimen.channel_banner_channel_logo_height);
        mChannelLogoImageViewMarginStart =
                mResources.getDimensionPixelSize(R.dimen.channel_banner_channel_logo_margin_start);
        mProgramDescriptionTextViewWidth =
                mResources.getDimensionPixelSize(R.dimen.channel_banner_program_description_width);
        mChannelBannerTextColor = mResources.getColor(R.color.channel_banner_text_color, null);
        mChannelBannerDimTextColor =
                mResources.getColor(R.color.channel_banner_dim_text_color, null);
        mResizeAnimDuration = mResources.getInteger(R.integer.channel_banner_fast_anim_duration);
        mRecordingIconPadding =
                mResources.getDimensionPixelOffset(R.dimen.channel_banner_recording_icon_padding);

        mResizeInterpolator =
                AnimationUtils.loadInterpolator(context, android.R.interpolator.linear_out_slow_in);

        mProgramDescriptionFadeInAnimator =
                AnimatorInflater.loadAnimator(
                        mMainActivity, R.animator.channel_banner_program_description_fade_in);
        mProgramDescriptionFadeOutAnimator =
                AnimatorInflater.loadAnimator(
                        mMainActivity, R.animator.channel_banner_program_description_fade_out);

        if (CommonFeatures.DVR.isEnabled(mMainActivity)) {
            mDvrManager = TvSingletons.getSingletons(mMainActivity).getDvrManager();
        } else {
            mDvrManager = null;
        }
        mContentRatingsManager =
                TvSingletons.getSingletons(getContext())
                        .getTvInputManagerHelper()
                        .getContentRatingsManager();

        mNoProgram =
                new Program.Builder()
                        .setTitle(context.getString(R.string.channel_banner_no_title))
                        .setDescription(EMPTY_STRING)
                        .build();
        mLockedChannelProgram =
                new Program.Builder()
                        .setTitle(context.getString(R.string.channel_banner_locked_channel_title))
                        .setDescription(EMPTY_STRING)
                        .build();
        if (sClosedCaptionMark == null) {
            sClosedCaptionMark = context.getString(R.string.closed_caption);
        }
        mAutoHideScheduler = new AutoHideScheduler(context, this::hide);
        context.getSystemService(AccessibilityManager.class)
                .addAccessibilityStateChangeListener(mAutoHideScheduler);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        mChannelView = findViewById(R.id.channel_banner_view);

        mChannelNumberTextView = (TextView) findViewById(R.id.channel_number);
        mChannelLogoImageView = (ImageView) findViewById(R.id.channel_logo);
        mProgramTextView = (TextView) findViewById(R.id.program_text);
        mTvInputLogoImageView = (ImageView) findViewById(R.id.tvinput_logo);
        mChannelNameTextView = (TextView) findViewById(R.id.channel_name);
        mProgramTimeTextView = (TextView) findViewById(R.id.program_time_text);
        mRemainingTimeView = (ProgressBar) findViewById(R.id.remaining_time);
        mRecordingIndicatorView = (TextView) findViewById(R.id.recording_indicator);
        mClosedCaptionTextView = (TextView) findViewById(R.id.closed_caption);
        mAspectRatioTextView = (TextView) findViewById(R.id.aspect_ratio);
        mResolutionTextView = (TextView) findViewById(R.id.resolution);
        mAudioChannelTextView = (TextView) findViewById(R.id.audio_channel);
        mContentRatingsTextViews[0] = (TextView) findViewById(R.id.content_ratings_0);
        mContentRatingsTextViews[1] = (TextView) findViewById(R.id.content_ratings_1);
        mContentRatingsTextViews[2] = (TextView) findViewById(R.id.content_ratings_2);
        mProgramDescriptionTextView = (TextView) findViewById(R.id.program_description);
        mAnchorView = findViewById(R.id.anchor);

        mProgramDescriptionFadeInAnimator.setTarget(mProgramDescriptionTextView);
        mProgramDescriptionFadeOutAnimator.setTarget(mProgramDescriptionTextView);
        mProgramDescriptionFadeOutAnimator.addListener(
                new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animator) {
                        mProgramDescriptionTextView.setText(mProgramDescriptionText);
                    }
                });
    }

    @Override
    public void onEnterAction(boolean fromEmptyScene) {
        resetAnimationEffects();
        if (fromEmptyScene) {
            ViewUtils.setTransitionAlpha(mChannelView, 1f);
        }
        mAutoHideScheduler.schedule(mShowDurationMillis);
    }

    @Override
    public void onExitAction() {
        mCurrentHeight = 0;
        mAutoHideScheduler.cancel();
    }

    private void resetAnimationEffects() {
        setAlpha(1f);
        setScaleX(1f);
        setScaleY(1f);
        setTranslationX(0);
        setTranslationY(0);
    }

    /**
     * Set new lock type.
     *
     * @param lockType Any of LOCK_NONE, LOCK_PROGRAM_DETAIL, or LOCK_CHANNEL_INFO.
     * @return the previous lock type of the channel banner.
     * @throws IllegalArgumentException if lockType is invalid.
     */
    public int setLockType(int lockType) {
        if (lockType != LOCK_NONE
                && lockType != LOCK_CHANNEL_INFO
                && lockType != LOCK_PROGRAM_DETAIL) {
            throw new IllegalArgumentException("No such lock type " + lockType);
        }
        int previousLockType = mLockType;
        mLockType = lockType;
        return previousLockType;
    }

    /**
     * Sets the content rating that blocks the current watched channel for displaying it in the
     * channel banner.
     */
    public void setBlockingContentRating(TvContentRating rating) {
        mBlockingContentRating = rating;
        updateProgramRatings(mMainActivity.getCurrentProgram());
    }

    /**
     * Update channel banner view.
     *
     * @param updateOnTune {@false} denotes the channel banner is updated due to other reasons than
     *     tuning. The channel info will not be updated in this case.
     */
    public void updateViews(boolean updateOnTune) {
        resetAnimationEffects();
        mChannelView.setVisibility(VISIBLE);
        mUpdateOnTune = updateOnTune;
        if (mUpdateOnTune) {
            if (isShown()) {
                mAutoHideScheduler.schedule(mShowDurationMillis);
            }
            mBlockingContentRating = null;
            mCurrentChannel = mMainActivity.getCurrentChannel();
            mCurrentChannelLogoExists =
                    mCurrentChannel != null && mCurrentChannel.channelLogoExists();
            updateStreamInfo(null);
            updateChannelInfo();
        }
        updateProgramInfo(mMainActivity.getCurrentProgram());
        mUpdateOnTune = false;
    }

    private void hide() {
        mCurrentHeight = 0;
        mMainActivity
                .getOverlayManager()
                .hideOverlays(
                        TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_DIALOG
                                | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_SIDE_PANELS
                                | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_PROGRAM_GUIDE
                                | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_MENU
                                | TvOverlayManager.FLAG_HIDE_OVERLAYS_KEEP_FRAGMENT);
    }

    /**
     * Update channel banner view with stream info.
     *
     * @param info A StreamInfo that includes stream information.
     */
    public void updateStreamInfo(StreamInfo info) {
        // Update stream information in a channel.
        if (mLockType != LOCK_CHANNEL_INFO && info != null) {
            updateText(
                    mClosedCaptionTextView,
                    info.hasClosedCaption() ? sClosedCaptionMark : EMPTY_STRING);
            updateText(
                    mAspectRatioTextView,
                    Utils.getAspectRatioString(info.getVideoDisplayAspectRatio()));
            updateText(
                    mResolutionTextView,
                    Utils.getVideoDefinitionLevelString(
                            mMainActivity, info.getVideoDefinitionLevel()));
            updateText(
                    mAudioChannelTextView,
                    Utils.getAudioChannelString(mMainActivity, info.getAudioChannelCount()));
        } else {
            // Channel change has been requested. But, StreamInfo hasn't been updated yet.
            mClosedCaptionTextView.setVisibility(View.GONE);
            mAspectRatioTextView.setVisibility(View.GONE);
            mResolutionTextView.setVisibility(View.GONE);
            mAudioChannelTextView.setVisibility(View.GONE);
        }
    }

    private void updateChannelInfo() {
        // Update static information for a channel.
        String displayNumber = EMPTY_STRING;
        String displayName = EMPTY_STRING;
        if (mCurrentChannel != null) {
            displayNumber = mCurrentChannel.getDisplayNumber();
            if (displayNumber == null) {
                displayNumber = EMPTY_STRING;
            }
            displayName = mCurrentChannel.getDisplayName();
            if (displayName == null) {
                displayName = EMPTY_STRING;
            }
        }

        if (displayNumber.isEmpty()) {
            mChannelNumberTextView.setVisibility(GONE);
        } else {
            mChannelNumberTextView.setVisibility(VISIBLE);
        }
        if (displayNumber.length() <= 3) {
            updateTextView(
                    mChannelNumberTextView,
                    R.dimen.channel_banner_channel_number_large_text_size,
                    R.dimen.channel_banner_channel_number_large_margin_top);
        } else if (displayNumber.length() <= 4) {
            updateTextView(
                    mChannelNumberTextView,
                    R.dimen.channel_banner_channel_number_medium_text_size,
                    R.dimen.channel_banner_channel_number_medium_margin_top);
        } else {
            updateTextView(
                    mChannelNumberTextView,
                    R.dimen.channel_banner_channel_number_small_text_size,
                    R.dimen.channel_banner_channel_number_small_margin_top);
        }
        mChannelNumberTextView.setText(displayNumber);
        mChannelNameTextView.setText(displayName);
        TvInputInfo info =
                mMainActivity.getTvInputManagerHelper().getTvInputInfo(getCurrentInputId());
        if (info == null
                || !ImageLoader.loadBitmap(
                        createTvInputLogoLoaderCallback(info, this),
                        new LoadTvInputLogoTask(getContext(), ImageCache.getInstance(), info))) {
            mTvInputLogoImageView.setVisibility(View.GONE);
            mTvInputLogoImageView.setImageDrawable(null);
        }
        mChannelLogoImageView.setImageBitmap(null);
        mChannelLogoImageView.setVisibility(View.GONE);
        if (mCurrentChannel != null && mCurrentChannelLogoExists) {
            mCurrentChannel.loadBitmap(
                    getContext(),
                    Channel.LOAD_IMAGE_TYPE_CHANNEL_LOGO,
                    mChannelLogoImageViewWidth,
                    mChannelLogoImageViewHeight,
                    createChannelLogoCallback(this, mCurrentChannel));
        }
    }

    private String getCurrentInputId() {
        Channel channel = mMainActivity.getCurrentChannel();
        return channel != null ? channel.getInputId() : null;
    }

    private void updateTvInputLogo(Bitmap bitmap) {
        mTvInputLogoImageView.setVisibility(View.VISIBLE);
        mTvInputLogoImageView.setImageBitmap(bitmap);
    }

    private static ImageLoaderCallback<ChannelBannerView> createTvInputLogoLoaderCallback(
            final TvInputInfo info, ChannelBannerView channelBannerView) {
        return new ImageLoaderCallback<ChannelBannerView>(channelBannerView) {
            @Override
            public void onBitmapLoaded(ChannelBannerView channelBannerView, Bitmap bitmap) {
                if (bitmap != null
                        && channelBannerView.mCurrentChannel != null
                        && info.getId().equals(channelBannerView.mCurrentChannel.getInputId())) {
                    channelBannerView.updateTvInputLogo(bitmap);
                }
            }
        };
    }

    private void updateText(TextView view, String text) {
        if (TextUtils.isEmpty(text)) {
            view.setVisibility(View.GONE);
        } else {
            view.setVisibility(View.VISIBLE);
            view.setText(text);
        }
    }

    private void updateTextView(TextView textView, int sizeRes, int marginTopRes) {
        float textSize = mResources.getDimension(sizeRes);
        if (textView.getTextSize() != textSize) {
            textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
        }
        updateTopMargin(textView, marginTopRes);
    }

    private void updateTopMargin(View view, int marginTopRes) {
        RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) view.getLayoutParams();
        int topMargin = (int) mResources.getDimension(marginTopRes);
        if (lp.topMargin != topMargin) {
            lp.topMargin = topMargin;
            view.setLayoutParams(lp);
        }
    }

    private static ImageLoaderCallback<ChannelBannerView> createChannelLogoCallback(
            ChannelBannerView channelBannerView, final Channel channel) {
        return new ImageLoaderCallback<ChannelBannerView>(channelBannerView) {
            @Override
            public void onBitmapLoaded(ChannelBannerView view, @Nullable Bitmap logo) {
                if (channel.equals(view.mCurrentChannel)) {
                    // The logo is obsolete.
                    return;
                }
                view.updateLogo(logo);
            }
        };
    }

    private void updateLogo(@Nullable Bitmap logo) {
        if (logo == null) {
            // Need to update the text size of the program text view depending on the channel logo.
            updateProgramTextView(mLastUpdatedProgram);
            return;
        }

        mChannelLogoImageView.setImageBitmap(logo);
        mChannelLogoImageView.setVisibility(View.VISIBLE);
        updateProgramTextView(mLastUpdatedProgram);

        if (mResizeAnimator == null) {
            String description = mProgramDescriptionTextView.getText().toString();
            boolean programDescriptionNeedFadeAnimation =
                    !description.equals(mProgramDescriptionText) && !mUpdateOnTune;
            updateBannerHeight(programDescriptionNeedFadeAnimation);
        } else {
            mProgramInfoUpdatePendingByResizing = true;
        }
    }

    private void updateProgramInfo(Program program) {
        if (mLockType == LOCK_CHANNEL_INFO) {
            program = mLockedChannelProgram;
        } else if (program == null || !program.isValid() || TextUtils.isEmpty(program.getTitle())) {
            program = mNoProgram;
        }

        if (mLastUpdatedProgram == null
                || !TextUtils.equals(program.getTitle(), mLastUpdatedProgram.getTitle())
                || !TextUtils.equals(
                        program.getEpisodeDisplayTitle(getContext()),
                        mLastUpdatedProgram.getEpisodeDisplayTitle(getContext()))) {
            updateProgramTextView(program);
        }
        updateProgramTimeInfo(program);
        updateRecordingStatus(program);
        updateProgramRatings(program);

        // When the program is changed, but the previous resize animation has not ended yet,
        // cancel the animation.
        boolean isProgramChanged = !program.equals(mLastUpdatedProgram);
        if (mResizeAnimator != null && isProgramChanged) {
            setLastUpdatedProgram(program);
            mProgramInfoUpdatePendingByResizing = true;
            mResizeAnimator.cancel();
        } else if (mResizeAnimator == null) {
            if (mLockType != LOCK_NONE || TextUtils.isEmpty(program.getDescription())) {
                mProgramDescriptionTextView.setVisibility(GONE);
                mProgramDescriptionText = "";
            } else {
                mProgramDescriptionTextView.setVisibility(VISIBLE);
                mProgramDescriptionText = program.getDescription();
            }
            String description = mProgramDescriptionTextView.getText().toString();
            boolean programDescriptionNeedFadeAnimation =
                    (isProgramChanged || !description.equals(mProgramDescriptionText))
                            && !mUpdateOnTune;
            updateBannerHeight(programDescriptionNeedFadeAnimation);
        } else {
            mProgramInfoUpdatePendingByResizing = true;
        }
        setLastUpdatedProgram(program);
    }

    private void updateProgramTextView(Program program) {
        if (program == null) {
            return;
        }
        updateProgramTextView(
                program.equals(mLockedChannelProgram),
                program.getTitle(),
                program.getEpisodeDisplayTitle(getContext()));
    }

    private void updateProgramTextView(boolean dimText, String title, String episodeDisplayTitle) {
        mProgramTextView.setVisibility(View.VISIBLE);
        if (dimText) {
            mProgramTextView.setTextColor(mChannelBannerDimTextColor);
        } else {
            mProgramTextView.setTextColor(mChannelBannerTextColor);
        }
        updateTextView(
                mProgramTextView,
                R.dimen.channel_banner_program_large_text_size,
                R.dimen.channel_banner_program_large_margin_top);
        if (TextUtils.isEmpty(episodeDisplayTitle)) {
            mProgramTextView.setText(title);
        } else {
            String fullTitle = title + "  " + episodeDisplayTitle;

            SpannableString text = new SpannableString(fullTitle);
            text.setSpan(
                    new TextAppearanceSpan(
                            getContext(), R.style.text_appearance_channel_banner_episode_title),
                    fullTitle.length() - episodeDisplayTitle.length(),
                    fullTitle.length(),
                    Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            mProgramTextView.setText(text);
        }
        int width =
                mProgramDescriptionTextViewWidth
                        + (mCurrentChannelLogoExists
                                ? 0
                                : mChannelLogoImageViewWidth + mChannelLogoImageViewMarginStart);
        ViewGroup.LayoutParams lp = mProgramTextView.getLayoutParams();
        lp.width = width;
        mProgramTextView.setLayoutParams(lp);
        mProgramTextView.measure(
                MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));

        boolean oneline = (mProgramTextView.getLineCount() == 1);
        if (!oneline) {
            updateTextView(
                    mProgramTextView,
                    R.dimen.channel_banner_program_medium_text_size,
                    R.dimen.channel_banner_program_medium_margin_top);
            mProgramTextView.measure(
                    MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            oneline = (mProgramTextView.getLineCount() == 1);
        }
        updateTopMargin(
                mAnchorView,
                oneline
                        ? R.dimen.channel_banner_anchor_one_line_y
                        : R.dimen.channel_banner_anchor_two_line_y);
    }

    private void updateProgramRatings(Program program) {
        if (mLockType == LOCK_CHANNEL_INFO) {
            for (int i = 0; i < DISPLAYED_CONTENT_RATINGS_COUNT; i++) {
                mContentRatingsTextViews[i].setVisibility(View.GONE);
            }
        } else if (mBlockingContentRating != null) {
            String displayNameForRating =
                    mContentRatingsManager.getDisplayNameForRating(mBlockingContentRating);
            if (!TextUtils.isEmpty(displayNameForRating)) {
                mContentRatingsTextViews[0].setText(displayNameForRating);
                mContentRatingsTextViews[0].setVisibility(View.VISIBLE);
            } else {
                mContentRatingsTextViews[0].setVisibility(View.GONE);
            }
            for (int i = 1; i < DISPLAYED_CONTENT_RATINGS_COUNT; i++) {
                mContentRatingsTextViews[i].setVisibility(View.GONE);
            }
        } else {
            TvContentRating[] ratings = (program == null) ? null : program.getContentRatings();
            for (int i = 0; i < DISPLAYED_CONTENT_RATINGS_COUNT; i++) {
                if (ratings == null || ratings.length <= i) {
                    mContentRatingsTextViews[i].setVisibility(View.GONE);
                } else {
                    mContentRatingsTextViews[i].setText(
                            mContentRatingsManager.getDisplayNameForRating(ratings[i]));
                    mContentRatingsTextViews[i].setVisibility(View.VISIBLE);
                }
            }
        }
    }

    private void updateProgramTimeInfo(Program program) {
        long durationMs = program.getDurationMillis();
        long startTimeMs = program.getStartTimeUtcMillis();
        long endTimeMs = program.getEndTimeUtcMillis();

        if (mLockType != LOCK_CHANNEL_INFO && durationMs > 0 && startTimeMs > 0) {
            mProgramTimeTextView.setVisibility(View.VISIBLE);
            mRemainingTimeView.setVisibility(View.VISIBLE);
            mProgramTimeTextView.setText(
                    Utils.getDurationString(getContext(), startTimeMs, endTimeMs, true));
        } else {
            mProgramTimeTextView.setVisibility(View.GONE);
            mRemainingTimeView.setVisibility(View.GONE);
        }
    }

    private int getProgressPercent(long currTime, long startTime, long endTime) {
        if (currTime <= startTime) {
            return 0;
        } else if (currTime >= endTime) {
            return 100;
        } else {
            return (int) (100 * (currTime - startTime) / (endTime - startTime));
        }
    }

    private void updateRecordingStatus(Program program) {
        if (mDvrManager == null) {
            updateProgressBarAndRecIcon(program, null);
            return;
        }
        ScheduledRecording currentRecording =
                (mCurrentChannel == null)
                        ? null
                        : mDvrManager.getCurrentRecording(mCurrentChannel.getId());
        if (DEBUG) {
            Log.d(TAG, currentRecording == null ? "No Recording" : "Recording:" + currentRecording);
        }
        if (currentRecording != null && isCurrentProgram(currentRecording, program)) {
            updateProgressBarAndRecIcon(program, currentRecording);
        } else {
            updateProgressBarAndRecIcon(program, null);
        }
    }

    private void updateProgressBarAndRecIcon(
            Program program, @Nullable ScheduledRecording recording) {
        long programStartTime = program.getStartTimeUtcMillis();
        long programEndTime = program.getEndTimeUtcMillis();
        long currentPosition = mMainActivity.getCurrentPlayingPosition();
        updateRecordingIndicator(recording);
        if (recording != null) {
            // Recording now. Use recording-style progress bar.
            mRemainingTimeView.setProgress(
                    getProgressPercent(
                            recording.getStartTimeMs(), programStartTime, programEndTime));
            mRemainingTimeView.setSecondaryProgress(
                    getProgressPercent(currentPosition, programStartTime, programEndTime));
        } else {
            // No recording is going now. Recover progress bar.
            mRemainingTimeView.setProgress(
                    getProgressPercent(currentPosition, programStartTime, programEndTime));
            mRemainingTimeView.setSecondaryProgress(0);
        }
    }

    private void updateRecordingIndicator(@Nullable ScheduledRecording recording) {
        if (recording != null) {
            if (mRemainingTimeView.getVisibility() == View.GONE) {
                mRecordingIndicatorView.setText(
                        mMainActivity
                                .getResources()
                                .getString(
                                        R.string.dvr_recording_till_format,
                                        DateUtils.formatDateTime(
                                                mMainActivity,
                                                recording.getEndTimeMs(),
                                                DateUtils.FORMAT_SHOW_TIME)));
                mRecordingIndicatorView.setCompoundDrawablePadding(mRecordingIconPadding);
            } else {
                mRecordingIndicatorView.setText("");
                mRecordingIndicatorView.setCompoundDrawablePadding(0);
            }
            mRecordingIndicatorView.setVisibility(View.VISIBLE);
        } else {
            mRecordingIndicatorView.setVisibility(View.GONE);
        }
    }

    private boolean isCurrentProgram(ScheduledRecording recording, Program program) {
        long currentPosition = mMainActivity.getCurrentPlayingPosition();
        return (recording.getType() == ScheduledRecording.TYPE_PROGRAM
                        && recording.getProgramId() == program.getId())
                || (recording.getType() == ScheduledRecording.TYPE_TIMED
                        && currentPosition >= recording.getStartTimeMs()
                        && currentPosition <= recording.getEndTimeMs());
    }

    private void setLastUpdatedProgram(Program program) {
        mLastUpdatedProgram = program;
    }

    private void updateBannerHeight(boolean needProgramDescriptionFadeAnimation) {
        SoftPreconditions.checkState(mResizeAnimator == null);
        // Need to measure the layout height with the new description text.
        CharSequence oldDescription = mProgramDescriptionTextView.getText();
        mProgramDescriptionTextView.setText(mProgramDescriptionText);
        measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
        int targetHeight = getMeasuredHeight();

        if (mCurrentHeight == 0 || !isShown()) {
            // Do not add the resize animation when the banner has not been shown before.
            mCurrentHeight = targetHeight;
            LayoutParams layoutParams = (LayoutParams) getLayoutParams();
            if (targetHeight != layoutParams.height) {
                layoutParams.height = targetHeight;
                setLayoutParams(layoutParams);
            }
        } else if (mCurrentHeight != targetHeight || needProgramDescriptionFadeAnimation) {
            // Restore description text for fade in/out animation.
            if (needProgramDescriptionFadeAnimation) {
                mProgramDescriptionTextView.setText(oldDescription);
            }
            mResizeAnimator =
                    createResizeAnimator(targetHeight, needProgramDescriptionFadeAnimation);
            mResizeAnimator.start();
        }
    }

    private Animator createResizeAnimator(int targetHeight, boolean addFadeAnimation) {
        final ValueAnimator heightAnimator = ValueAnimator.ofInt(mCurrentHeight, targetHeight);
        heightAnimator.addUpdateListener(
                new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        int value = (Integer) animation.getAnimatedValue();
                        LayoutParams layoutParams =
                                (LayoutParams) ChannelBannerView.this.getLayoutParams();
                        if (value != layoutParams.height) {
                            layoutParams.height = value;
                            ChannelBannerView.this.setLayoutParams(layoutParams);
                        }
                        mCurrentHeight = value;
                    }
                });

        heightAnimator.setDuration(mResizeAnimDuration);
        heightAnimator.setInterpolator(mResizeInterpolator);

        if (!addFadeAnimation) {
            heightAnimator.addListener(mResizeAnimatorListener);
            return heightAnimator;
        }

        AnimatorSet fadeOutAndHeightAnimator = new AnimatorSet();
        fadeOutAndHeightAnimator.playTogether(mProgramDescriptionFadeOutAnimator, heightAnimator);
        AnimatorSet animator = new AnimatorSet();
        animator.playSequentially(fadeOutAndHeightAnimator, mProgramDescriptionFadeInAnimator);
        animator.addListener(mResizeAnimatorListener);
        return animator;
    }

    @Override
    public void onAccessibilityStateChanged(boolean enabled) {
        mAutoHideScheduler.onAccessibilityStateChanged(enabled);
    }
}
