/*
 * Copyright (C) 2014 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 androidx.leanback.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Transformation;
import android.widget.FrameLayout;

import androidx.annotation.VisibleForTesting;
import androidx.leanback.R;

import java.util.ArrayList;

/**
 * A card style layout that responds to certain state changes. It arranges its
 * children in a vertical column, with different regions becoming visible at
 * different times.
 *
 * <p>
 * A BaseCardView will draw its children based on its type, the region
 * visibilities of the child types, and the state of the widget. A child may be
 * marked as belonging to one of three regions: main, info, or extra. The main
 * region is always visible, while the info and extra regions can be set to
 * display based on the activated or selected state of the View. The card states
 * are set by calling {@link #setActivated(boolean) setActivated} and
 * {@link #setSelected(boolean) setSelected}.
 * <p>
 * See {@link BaseCardView.LayoutParams} for layout attributes.
 * </p>
 */
public class BaseCardView extends FrameLayout {
    private static final String TAG = "BaseCardView";
    private static final boolean DEBUG = false;

    /**
     * A simple card type with a single layout area. This card type does not
     * change its layout or size as it transitions between
     * Activated/Not-Activated or Selected/Unselected states.
     *
     * @see #getCardType()
     */
    public static final int CARD_TYPE_MAIN_ONLY = 0;

    /**
     * A Card type with 2 layout areas: A main area which is always visible, and
     * an info area that fades in over the main area when it is visible.
     * The card height will not change.
     *
     * @see #getCardType()
     */
    public static final int CARD_TYPE_INFO_OVER = 1;

    /**
     * A Card type with 2 layout areas: A main area which is always visible, and
     * an info area that appears below the main area. When the info area is visible
     * the total card height will change.
     *
     * @see #getCardType()
     */
    public static final int CARD_TYPE_INFO_UNDER = 2;

    /**
     * A Card type with 3 layout areas: A main area which is always visible; an
     * info area which will appear below the main area, and an extra area that
     * only appears after a short delay. The info area appears below the main
     * area, causing the total card height to change. The extra area animates in
     * at the bottom of the card, shifting up the info view without affecting
     * the card height.
     *
     * @see #getCardType()
     */
    public static final int CARD_TYPE_INFO_UNDER_WITH_EXTRA = 3;

    /**
     * Indicates that a card region is always visible.
     */
    public static final int CARD_REGION_VISIBLE_ALWAYS = 0;

    /**
     * Indicates that a card region is visible when the card is activated.
     */
    public static final int CARD_REGION_VISIBLE_ACTIVATED = 1;

    /**
     * Indicates that a card region is visible when the card is selected.
     */
    public static final int CARD_REGION_VISIBLE_SELECTED = 2;

    private static final int CARD_TYPE_INVALID = 4;

    private int mCardType;
    private int mInfoVisibility;
    private int mExtraVisibility;

    private ArrayList<View> mMainViewList;
    ArrayList<View> mInfoViewList;
    ArrayList<View> mExtraViewList;

    private int mMeasuredWidth;
    private int mMeasuredHeight;
    private boolean mDelaySelectedAnim;
    private int mSelectedAnimationDelay;
    private final int mActivatedAnimDuration;
    private final int mSelectedAnimDuration;

    /**
     * Distance of top of info view to bottom of MainView, it will shift up when extra view appears.
     */
    float mInfoOffset;
    float mInfoVisFraction;
    float mInfoAlpha;
    private Animation mAnim;

    private final static int[] LB_PRESSED_STATE_SET = new int[]{
        android.R.attr.state_pressed};

    private final Runnable mAnimationTrigger = new Runnable() {
        @Override
        public void run() {
            animateInfoOffset(true);
        }
    };

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

    public BaseCardView(Context context, AttributeSet attrs) {
        this(context, attrs, R.attr.baseCardViewStyle);
    }

    public BaseCardView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.lbBaseCardView,
                defStyleAttr, 0);

        try {
            mCardType = a.getInteger(R.styleable.lbBaseCardView_cardType, CARD_TYPE_MAIN_ONLY);
            Drawable cardForeground = a.getDrawable(R.styleable.lbBaseCardView_cardForeground);
            if (cardForeground != null) {
                setForeground(cardForeground);
            }
            Drawable cardBackground = a.getDrawable(R.styleable.lbBaseCardView_cardBackground);
            if (cardBackground != null) {
                setBackground(cardBackground);
            }
            mInfoVisibility = a.getInteger(R.styleable.lbBaseCardView_infoVisibility,
                    CARD_REGION_VISIBLE_ACTIVATED);
            mExtraVisibility = a.getInteger(R.styleable.lbBaseCardView_extraVisibility,
                    CARD_REGION_VISIBLE_SELECTED);
            // Extra region should never show before info region.
            if (mExtraVisibility < mInfoVisibility) {
                mExtraVisibility = mInfoVisibility;
            }

            mSelectedAnimationDelay = a.getInteger(
                    R.styleable.lbBaseCardView_selectedAnimationDelay,
                    getResources().getInteger(R.integer.lb_card_selected_animation_delay));

            mSelectedAnimDuration = a.getInteger(
                    R.styleable.lbBaseCardView_selectedAnimationDuration,
                    getResources().getInteger(R.integer.lb_card_selected_animation_duration));

            mActivatedAnimDuration =
                    a.getInteger(R.styleable.lbBaseCardView_activatedAnimationDuration,
                    getResources().getInteger(R.integer.lb_card_activated_animation_duration));
        } finally {
            a.recycle();
        }

        mDelaySelectedAnim = true;

        mMainViewList = new ArrayList<View>();
        mInfoViewList = new ArrayList<View>();
        mExtraViewList = new ArrayList<View>();

        mInfoOffset = 0.0f;
        mInfoVisFraction = getFinalInfoVisFraction();
        mInfoAlpha = getFinalInfoAlpha();
    }

    /**
     * Sets a flag indicating if the Selected animation (if the selected card
     * type implements one) should run immediately after the card is selected,
     * or if it should be delayed. The default behavior is to delay this
     * animation. This is a one-shot override. If set to false, after the card
     * is selected and the selected animation is triggered, this flag is
     * automatically reset to true. This is useful when you want to change the
     * default behavior, and have the selected animation run immediately. One
     * such case could be when focus moves from one row to the other, when
     * instead of delaying the selected animation until the user pauses on a
     * card, it may be desirable to trigger the animation for that card
     * immediately.
     *
     * @param delay True (default) if the selected animation should be delayed
     *            after the card is selected, or false if the animation should
     *            run immediately the next time the card is Selected.
     */
    public void setSelectedAnimationDelayed(boolean delay) {
        mDelaySelectedAnim = delay;
    }

    /**
     * Returns a boolean indicating if the selected animation will run
     * immediately or be delayed the next time the card is Selected.
     *
     * @return true if this card is set to delay the selected animation the next
     *         time it is selected, or false if the selected animation will run
     *         immediately the next time the card is selected.
     */
    public boolean isSelectedAnimationDelayed() {
        return mDelaySelectedAnim;
    }

    /**
     * Sets the type of this Card.
     *
     * @param type The desired card type.
     */
    public void setCardType(int type) {
        if (mCardType != type) {
            if (type >= CARD_TYPE_MAIN_ONLY && type < CARD_TYPE_INVALID) {
                // Valid card type
                mCardType = type;
            } else {
                Log.e(TAG, "Invalid card type specified: " + type
                        + ". Defaulting to type CARD_TYPE_MAIN_ONLY.");
                mCardType = CARD_TYPE_MAIN_ONLY;
            }
            requestLayout();
        }
    }

    /**
     * Returns the type of this Card.
     *
     * @return The type of this card.
     */
    public int getCardType() {
        return mCardType;
    }

    /**
     * Sets the visibility of the info region of the card.
     *
     * @param visibility The region visibility to use for the info region. Must
     *     be one of {@link #CARD_REGION_VISIBLE_ALWAYS},
     *     {@link #CARD_REGION_VISIBLE_SELECTED}, or
     *     {@link #CARD_REGION_VISIBLE_ACTIVATED}.
     */
    public void setInfoVisibility(int visibility) {
        if (mInfoVisibility != visibility) {
            cancelAnimations();
            mInfoVisibility = visibility;
            mInfoVisFraction = getFinalInfoVisFraction();
            requestLayout();
            float newInfoAlpha = getFinalInfoAlpha();
            if (newInfoAlpha != mInfoAlpha) {
                mInfoAlpha = newInfoAlpha;
                for (int i = 0; i < mInfoViewList.size(); i++) {
                    mInfoViewList.get(i).setAlpha(mInfoAlpha);
                }
            }
        }
    }

    final float getFinalInfoVisFraction() {
        return mCardType == CARD_TYPE_INFO_UNDER && mInfoVisibility == CARD_REGION_VISIBLE_SELECTED
                && !isSelected() ? 0.0f : 1.0f;
    }

    final float getFinalInfoAlpha() {
        return mCardType == CARD_TYPE_INFO_OVER && mInfoVisibility == CARD_REGION_VISIBLE_SELECTED
                && !isSelected() ? 0.0f : 1.0f;
    }

    /**
     * Returns the visibility of the info region of the card.
     */
    public int getInfoVisibility() {
        return mInfoVisibility;
    }

    /**
     * Sets the visibility of the extra region of the card.
     *
     * @param visibility The region visibility to use for the extra region. Must
     *     be one of {@link #CARD_REGION_VISIBLE_ALWAYS},
     *     {@link #CARD_REGION_VISIBLE_SELECTED}, or
     *     {@link #CARD_REGION_VISIBLE_ACTIVATED}.
     * @deprecated Extra view's visibility is controlled by {@link #setInfoVisibility(int)}
     */
    @Deprecated
    public void setExtraVisibility(int visibility) {
        if (mExtraVisibility != visibility) {
            mExtraVisibility = visibility;
        }
    }

    /**
     * Returns the visibility of the extra region of the card.
     * @deprecated Extra view's visibility is controlled by {@link #getInfoVisibility()}
     */
    @Deprecated
    public int getExtraVisibility() {
        return mExtraVisibility;
    }

    /**
     * Sets the Activated state of this Card. This can trigger changes in the
     * card layout, resulting in views to become visible or hidden. A card is
     * normally set to Activated state when its parent container (like a Row)
     * receives focus, and then activates all of its children.
     *
     * @param activated True if the card is ACTIVE, or false if INACTIVE.
     * @see #isActivated()
     */
    @Override
    public void setActivated(boolean activated) {
        if (activated != isActivated()) {
            super.setActivated(activated);
            applyActiveState(isActivated());
        }
    }

    /**
     * Sets the Selected state of this Card. This can trigger changes in the
     * card layout, resulting in views to become visible or hidden. A card is
     * normally set to Selected state when it receives input focus.
     *
     * @param selected True if the card is Selected, or false otherwise.
     * @see #isSelected()
     */
    @Override
    public void setSelected(boolean selected) {
        if (selected != isSelected()) {
            super.setSelected(selected);
            applySelectedState(isSelected());
        }
    }

    @Override
    public boolean shouldDelayChildPressedState() {
        return false;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        mMeasuredWidth = 0;
        mMeasuredHeight = 0;
        int state = 0;
        int mainHeight = 0;
        int infoHeight = 0;
        int extraHeight = 0;

        findChildrenViews();

        final int unspecifiedSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        // MAIN is always present
        for (int i = 0; i < mMainViewList.size(); i++) {
            View mainView = mMainViewList.get(i);
            if (mainView.getVisibility() != View.GONE) {
                measureChild(mainView, unspecifiedSpec, unspecifiedSpec);
                mMeasuredWidth = Math.max(mMeasuredWidth, mainView.getMeasuredWidth());
                mainHeight += mainView.getMeasuredHeight();
                state = View.combineMeasuredStates(state, mainView.getMeasuredState());
            }
        }
        setPivotX(mMeasuredWidth / 2);
        setPivotY(mainHeight / 2);


        // The MAIN area determines the card width
        int cardWidthMeasureSpec = MeasureSpec.makeMeasureSpec(mMeasuredWidth, MeasureSpec.EXACTLY);

        if (hasInfoRegion()) {
            for (int i = 0; i < mInfoViewList.size(); i++) {
                View infoView = mInfoViewList.get(i);
                if (infoView.getVisibility() != View.GONE) {
                    measureChild(infoView, cardWidthMeasureSpec, unspecifiedSpec);
                    if (mCardType != CARD_TYPE_INFO_OVER) {
                        infoHeight += infoView.getMeasuredHeight();
                    }
                    state = View.combineMeasuredStates(state, infoView.getMeasuredState());
                }
            }

            if (hasExtraRegion()) {
                for (int i = 0; i < mExtraViewList.size(); i++) {
                    View extraView = mExtraViewList.get(i);
                    if (extraView.getVisibility() != View.GONE) {
                        measureChild(extraView, cardWidthMeasureSpec, unspecifiedSpec);
                        extraHeight += extraView.getMeasuredHeight();
                        state = View.combineMeasuredStates(state, extraView.getMeasuredState());
                    }
                }
            }
        }

        boolean infoAnimating = hasInfoRegion() && mInfoVisibility == CARD_REGION_VISIBLE_SELECTED;
        mMeasuredHeight = (int) (mainHeight
                + (infoAnimating ? (infoHeight * mInfoVisFraction) : infoHeight)
                + extraHeight - (infoAnimating ? 0 : mInfoOffset));

        // Report our final dimensions.
        setMeasuredDimension(View.resolveSizeAndState(mMeasuredWidth + getPaddingLeft()
                + getPaddingRight(), widthMeasureSpec, state),
                View.resolveSizeAndState(mMeasuredHeight + getPaddingTop() + getPaddingBottom(),
                        heightMeasureSpec, state << View.MEASURED_HEIGHT_STATE_SHIFT));
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        float currBottom = getPaddingTop();

        // MAIN is always present
        for (int i = 0; i < mMainViewList.size(); i++) {
            View mainView = mMainViewList.get(i);
            if (mainView.getVisibility() != View.GONE) {
                mainView.layout(getPaddingLeft(),
                        (int) currBottom,
                                mMeasuredWidth + getPaddingLeft(),
                        (int) (currBottom + mainView.getMeasuredHeight()));
                currBottom += mainView.getMeasuredHeight();
            }
        }

        if (hasInfoRegion()) {
            float infoHeight = 0f;
            for (int i = 0; i < mInfoViewList.size(); i++) {
                infoHeight += mInfoViewList.get(i).getMeasuredHeight();
            }

            if (mCardType == CARD_TYPE_INFO_OVER) {
                // retract currBottom to overlap the info views on top of main
                currBottom -= infoHeight;
                if (currBottom < 0) {
                    currBottom = 0;
                }
            } else if (mCardType == CARD_TYPE_INFO_UNDER) {
                if (mInfoVisibility == CARD_REGION_VISIBLE_SELECTED) {
                    infoHeight = infoHeight * mInfoVisFraction;
                }
            } else {
                currBottom -= mInfoOffset;
            }

            for (int i = 0; i < mInfoViewList.size(); i++) {
                View infoView = mInfoViewList.get(i);
                if (infoView.getVisibility() != View.GONE) {
                    int viewHeight = infoView.getMeasuredHeight();
                    if (viewHeight > infoHeight) {
                        viewHeight = (int) infoHeight;
                    }
                    infoView.layout(getPaddingLeft(),
                            (int) currBottom,
                                    mMeasuredWidth + getPaddingLeft(),
                            (int) (currBottom + viewHeight));
                    currBottom += viewHeight;
                    infoHeight -= viewHeight;
                    if (infoHeight <= 0) {
                        break;
                    }
                }
            }

            if (hasExtraRegion()) {
                for (int i = 0; i < mExtraViewList.size(); i++) {
                    View extraView = mExtraViewList.get(i);
                    if (extraView.getVisibility() != View.GONE) {
                        extraView.layout(getPaddingLeft(),
                                (int) currBottom,
                                        mMeasuredWidth + getPaddingLeft(),
                                (int) (currBottom + extraView.getMeasuredHeight()));
                        currBottom += extraView.getMeasuredHeight();
                    }
                }
            }
        }
        // Force update drawable bounds.
        onSizeChanged(0, 0, right - left, bottom - top);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        removeCallbacks(mAnimationTrigger);
        cancelAnimations();
    }

    private boolean hasInfoRegion() {
        return mCardType != CARD_TYPE_MAIN_ONLY;
    }

    private boolean hasExtraRegion() {
        return mCardType == CARD_TYPE_INFO_UNDER_WITH_EXTRA;
    }

    /**
     * Returns target visibility of info region.
     */
    private boolean isRegionVisible(int regionVisibility) {
        switch (regionVisibility) {
            case CARD_REGION_VISIBLE_ALWAYS:
                return true;
            case CARD_REGION_VISIBLE_ACTIVATED:
                return isActivated();
            case CARD_REGION_VISIBLE_SELECTED:
                return isSelected();
            default:
                if (DEBUG) Log.e(TAG, "invalid region visibility state: " + regionVisibility);
                return false;
        }
    }

    /**
     * Unlike isRegionVisible(), this method returns true when it is fading out when unselected.
     */
    private boolean isCurrentRegionVisible(int regionVisibility) {
        switch (regionVisibility) {
            case CARD_REGION_VISIBLE_ALWAYS:
                return true;
            case CARD_REGION_VISIBLE_ACTIVATED:
                return isActivated();
            case CARD_REGION_VISIBLE_SELECTED:
                if (mCardType == CARD_TYPE_INFO_UNDER) {
                    return mInfoVisFraction > 0f;
                } else {
                    return isSelected();
                }
            default:
                if (DEBUG) Log.e(TAG, "invalid region visibility state: " + regionVisibility);
                return false;
        }
    }

    private void findChildrenViews() {
        mMainViewList.clear();
        mInfoViewList.clear();
        mExtraViewList.clear();

        final int count = getChildCount();

        boolean infoVisible = hasInfoRegion() && isCurrentRegionVisible(mInfoVisibility);
        boolean extraVisible = hasExtraRegion() && mInfoOffset > 0f;

        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);

            if (child == null) {
                continue;
            }

            BaseCardView.LayoutParams lp = (BaseCardView.LayoutParams) child
                    .getLayoutParams();
            if (lp.viewType == LayoutParams.VIEW_TYPE_INFO) {
                child.setAlpha(mInfoAlpha);
                mInfoViewList.add(child);
                child.setVisibility(infoVisible ? View.VISIBLE : View.GONE);
            } else if (lp.viewType == LayoutParams.VIEW_TYPE_EXTRA) {
                mExtraViewList.add(child);
                child.setVisibility(extraVisible ? View.VISIBLE : View.GONE);
            } else {
                // Default to MAIN
                mMainViewList.add(child);
                child.setVisibility(View.VISIBLE);
            }
        }

    }

    @Override
    protected int[] onCreateDrawableState(int extraSpace) {
        // filter out focus states,  since leanback does not fade foreground on focus.
        final int[] s = super.onCreateDrawableState(extraSpace);
        final int N = s.length;
        boolean pressed = false;
        boolean enabled = false;
        for (int i = 0; i < N; i++) {
            if (s[i] == android.R.attr.state_pressed) {
                pressed = true;
            }
            if (s[i] == android.R.attr.state_enabled) {
                enabled = true;
            }
        }
        if (pressed && enabled) {
            return View.PRESSED_ENABLED_STATE_SET;
        } else if (pressed) {
            return LB_PRESSED_STATE_SET;
        } else if (enabled) {
            return View.ENABLED_STATE_SET;
        } else {
            return View.EMPTY_STATE_SET;
        }
    }

    private void applyActiveState(boolean active) {
        if (hasInfoRegion() && mInfoVisibility == CARD_REGION_VISIBLE_ACTIVATED) {
            setInfoViewVisibility(isRegionVisible(mInfoVisibility));
        }
    }

    private void setInfoViewVisibility(boolean visible) {
        if (mCardType == CARD_TYPE_INFO_UNDER_WITH_EXTRA) {
            // Active state changes for card type
            // CARD_TYPE_INFO_UNDER_WITH_EXTRA
            if (visible) {
                for (int i = 0; i < mInfoViewList.size(); i++) {
                    mInfoViewList.get(i).setVisibility(View.VISIBLE);
                }
            } else {
                for (int i = 0; i < mInfoViewList.size(); i++) {
                    mInfoViewList.get(i).setVisibility(View.GONE);
                }
                for (int i = 0; i < mExtraViewList.size(); i++) {
                    mExtraViewList.get(i).setVisibility(View.GONE);
                }
                mInfoOffset = 0.0f;
            }
        } else if (mCardType == CARD_TYPE_INFO_UNDER) {
            // Active state changes for card type CARD_TYPE_INFO_UNDER
            if (mInfoVisibility == CARD_REGION_VISIBLE_SELECTED) {
                animateInfoHeight(visible);
            } else {
                for (int i = 0; i < mInfoViewList.size(); i++) {
                    mInfoViewList.get(i).setVisibility(visible ? View.VISIBLE : View.GONE);
                }
            }
        } else if (mCardType == CARD_TYPE_INFO_OVER) {
            // Active state changes for card type CARD_TYPE_INFO_OVER
            animateInfoAlpha(visible);
        }
    }

    private void applySelectedState(boolean focused) {
        removeCallbacks(mAnimationTrigger);

        if (mCardType == CARD_TYPE_INFO_UNDER_WITH_EXTRA) {
            // Focus changes for card type CARD_TYPE_INFO_UNDER_WITH_EXTRA
            if (focused) {
                if (!mDelaySelectedAnim) {
                    post(mAnimationTrigger);
                    mDelaySelectedAnim = true;
                } else {
                    postDelayed(mAnimationTrigger, mSelectedAnimationDelay);
                }
            } else {
                animateInfoOffset(false);
            }
        } else if (mInfoVisibility == CARD_REGION_VISIBLE_SELECTED) {
            setInfoViewVisibility(focused);
        }
    }

    private void cancelAnimations() {
        if (mAnim != null) {
            mAnim.cancel();
            mAnim = null;
            // force-clear the animation, as Animation#cancel() doesn't work prior to N,
            // and will instead cause the animation to infinitely loop
            clearAnimation();
        }
    }

    // This animation changes the Y offset of the info and extra views,
    // so that they animate UP to make the extra info area visible when a
    // card is selected.
    void animateInfoOffset(boolean shown) {
        cancelAnimations();

        int extraHeight = 0;
        if (shown) {
            int widthSpec = MeasureSpec.makeMeasureSpec(mMeasuredWidth, MeasureSpec.EXACTLY);
            int heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);

            for (int i = 0; i < mExtraViewList.size(); i++) {
                View extraView = mExtraViewList.get(i);
                extraView.setVisibility(View.VISIBLE);
                extraView.measure(widthSpec, heightSpec);
                extraHeight = Math.max(extraHeight, extraView.getMeasuredHeight());
            }
        }

        mAnim = new InfoOffsetAnimation(mInfoOffset, shown ? extraHeight : 0);
        mAnim.setDuration(mSelectedAnimDuration);
        mAnim.setInterpolator(new AccelerateDecelerateInterpolator());
        mAnim.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                if (mInfoOffset == 0f) {
                    for (int i = 0; i < mExtraViewList.size(); i++) {
                        mExtraViewList.get(i).setVisibility(View.GONE);
                    }
                }
            }

                @Override
            public void onAnimationRepeat(Animation animation) {
            }

        });
        startAnimation(mAnim);
    }

    // This animation changes the visible height of the info views,
    // so that they animate in and out of view.
    private void animateInfoHeight(boolean shown) {
        cancelAnimations();

        if (shown) {
            for (int i = 0; i < mInfoViewList.size(); i++) {
                View extraView = mInfoViewList.get(i);
                extraView.setVisibility(View.VISIBLE);
            }
        }

        float targetFraction = shown ? 1.0f : 0f;
        if (mInfoVisFraction == targetFraction) {
            return;
        }
        mAnim = new InfoHeightAnimation(mInfoVisFraction, targetFraction);
        mAnim.setDuration(mSelectedAnimDuration);
        mAnim.setInterpolator(new AccelerateDecelerateInterpolator());
        mAnim.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                if (mInfoVisFraction == 0f) {
                    for (int i = 0; i < mInfoViewList.size(); i++) {
                        mInfoViewList.get(i).setVisibility(View.GONE);
                    }
                }
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
            }

        });
        startAnimation(mAnim);
    }

    // This animation changes the alpha of the info views, so they animate in
    // and out. It's meant to be used when the info views are overlaid on top of
    // the main view area. It gets triggered by a change in the Active state of
    // the card.
    private void animateInfoAlpha(boolean shown) {
        cancelAnimations();

        if (shown) {
            for (int i = 0; i < mInfoViewList.size(); i++) {
                mInfoViewList.get(i).setVisibility(View.VISIBLE);
            }
        }
        float targetAlpha = shown ? 1.0f : 0.0f;
        if (targetAlpha == mInfoAlpha) {
            return;
        }

        mAnim = new InfoAlphaAnimation(mInfoAlpha, shown ? 1.0f : 0.0f);
        mAnim.setDuration(mActivatedAnimDuration);
        mAnim.setInterpolator(new DecelerateInterpolator());
        mAnim.setAnimationListener(new Animation.AnimationListener() {
            @Override
            public void onAnimationStart(Animation animation) {
            }

            @Override
            public void onAnimationEnd(Animation animation) {
                if (mInfoAlpha == 0.0) {
                    for (int i = 0; i < mInfoViewList.size(); i++) {
                        mInfoViewList.get(i).setVisibility(View.GONE);
                    }
                }
            }

            @Override
            public void onAnimationRepeat(Animation animation) {
            }

        });
        startAnimation(mAnim);
    }

    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        return new BaseCardView.LayoutParams(getContext(), attrs);
    }

    @Override
    protected LayoutParams generateDefaultLayoutParams() {
        return new BaseCardView.LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    }

    @Override
    protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
        if (lp instanceof LayoutParams) {
            return new LayoutParams((LayoutParams) lp);
        } else {
            return new LayoutParams(lp);
        }
    }

    @Override
    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
        return p instanceof BaseCardView.LayoutParams;
    }

    /**
     * Per-child layout information associated with BaseCardView.
     */
    public static class LayoutParams extends FrameLayout.LayoutParams {
        public static final int VIEW_TYPE_MAIN = 0;
        public static final int VIEW_TYPE_INFO = 1;
        public static final int VIEW_TYPE_EXTRA = 2;

        /**
         * Card component type for the view associated with these LayoutParams.
         */
        @ViewDebug.ExportedProperty(category = "layout", mapping = {
                @ViewDebug.IntToString(from = VIEW_TYPE_MAIN, to = "MAIN"),
                @ViewDebug.IntToString(from = VIEW_TYPE_INFO, to = "INFO"),
                @ViewDebug.IntToString(from = VIEW_TYPE_EXTRA, to = "EXTRA")
        })
        public int viewType = VIEW_TYPE_MAIN;

        /**
         * {@inheritDoc}
         */
        public LayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);
            TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.lbBaseCardView_Layout);

            viewType = a.getInt(
                    R.styleable.lbBaseCardView_Layout_layout_viewType, VIEW_TYPE_MAIN);

            a.recycle();
        }

        /**
         * {@inheritDoc}
         */
        public LayoutParams(int width, int height) {
            super(width, height);
        }

        /**
         * {@inheritDoc}
         */
        public LayoutParams(ViewGroup.LayoutParams p) {
            super(p);
        }

        /**
         * Copy constructor. Clones the width, height, and View Type of the
         * source.
         *
         * @param source The layout params to copy from.
         */
        public LayoutParams(LayoutParams source) {
            super((ViewGroup.MarginLayoutParams) source);

            this.viewType = source.viewType;
        }
    }

    class AnimationBase extends Animation {

        @VisibleForTesting
        final void mockStart() {
            getTransformation(0, null);
        }

        @VisibleForTesting
        final void mockEnd() {
            applyTransformation(1f, null);
            cancelAnimations();
        }
    }

    // Helper animation class used in the animation of the info and extra
    // fields vertically within the card
    final class InfoOffsetAnimation extends AnimationBase {
        private float mStartValue;
        private float mDelta;

        public InfoOffsetAnimation(float start, float end) {
            mStartValue = start;
            mDelta = end - start;
        }

        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            mInfoOffset = mStartValue + (interpolatedTime * mDelta);
            requestLayout();
        }
    }

    // Helper animation class used in the animation of the visible height
    // for the info fields.
    final class InfoHeightAnimation extends AnimationBase {
        private float mStartValue;
        private float mDelta;

        public InfoHeightAnimation(float start, float end) {
            mStartValue = start;
            mDelta = end - start;
        }

        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            mInfoVisFraction = mStartValue + (interpolatedTime * mDelta);
            requestLayout();
        }
    }

    // Helper animation class used to animate the alpha for the info views
    // when they are fading in or out of view.
    final class InfoAlphaAnimation extends AnimationBase {
        private float mStartValue;
        private float mDelta;

        public InfoAlphaAnimation(float start, float end) {
            mStartValue = start;
            mDelta = end - start;
        }

        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            mInfoAlpha = mStartValue + (interpolatedTime * mDelta);
            for (int i = 0; i < mInfoViewList.size(); i++) {
                mInfoViewList.get(i).setAlpha(mInfoAlpha);
            }
        }
    }

    @Override
    public String toString() {
        if (DEBUG) {
            StringBuilder sb = new StringBuilder();
            sb.append(this.getClass().getSimpleName()).append(" : ");
            sb.append("cardType=");
            switch(mCardType) {
                case CARD_TYPE_MAIN_ONLY:
                    sb.append("MAIN_ONLY");
                    break;
                case CARD_TYPE_INFO_OVER:
                    sb.append("INFO_OVER");
                    break;
                case CARD_TYPE_INFO_UNDER:
                    sb.append("INFO_UNDER");
                    break;
                case CARD_TYPE_INFO_UNDER_WITH_EXTRA:
                    sb.append("INFO_UNDER_WITH_EXTRA");
                    break;
                default:
                    sb.append("INVALID");
                    break;
            }
            sb.append(" : ");
            sb.append(mMainViewList.size()).append(" main views, ");
            sb.append(mInfoViewList.size()).append(" info views, ");
            sb.append(mExtraViewList.size()).append(" extra views : ");
            sb.append("infoVisibility=").append(mInfoVisibility).append(" ");
            sb.append("extraVisibility=").append(mExtraVisibility).append(" ");
            sb.append("isActivated=").append(isActivated());
            sb.append(" : ");
            sb.append("isSelected=").append(isSelected());
            return sb.toString();
        } else {
            return super.toString();
        }
    }
}
