/*
 * 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 com.android.systemui.recents.views;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.*;
import android.graphics.Bitmap.Config;
import android.util.AttributeSet;
import android.view.accessibility.AccessibilityManager;
import android.view.View;
import android.view.ViewOutlineProvider;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;

import com.android.internal.logging.MetricsLogger;
import com.android.systemui.R;
import com.android.systemui.recents.Constants;
import com.android.systemui.recents.RecentsConfiguration;
import com.android.systemui.recents.misc.Utilities;
import com.android.systemui.recents.model.Task;
import com.android.systemui.statusbar.phone.PhoneStatusBar;

/* A task view */
public class TaskView extends FrameLayout implements Task.TaskCallbacks,
        View.OnClickListener, View.OnLongClickListener {

    /** The TaskView callbacks */
    interface TaskViewCallbacks {
        public void onTaskViewAppIconClicked(TaskView tv);
        public void onTaskViewAppInfoClicked(TaskView tv);
        public void onTaskViewClicked(TaskView tv, Task task, boolean lockToTask);
        public void onTaskViewDismissed(TaskView tv);
        public void onTaskViewClipStateChanged(TaskView tv);
        public void onTaskViewFocusChanged(TaskView tv, boolean focused);
        public void onTaskResize(TaskView tv);
    }

    RecentsConfiguration mConfig;

    float mTaskProgress;
    ObjectAnimator mTaskProgressAnimator;
    float mMaxDimScale;
    int mDimAlpha;
    AccelerateInterpolator mDimInterpolator = new AccelerateInterpolator(1f);
    PorterDuffColorFilter mDimColorFilter = new PorterDuffColorFilter(0, PorterDuff.Mode.SRC_ATOP);
    Paint mDimLayerPaint = new Paint();
    float mActionButtonTranslationZ;

    Task mTask;
    boolean mTaskDataLoaded;
    boolean mIsFocused;
    boolean mFocusAnimationsEnabled;
    boolean mClipViewInStack;
    AnimateableViewBounds mViewBounds;

    View mContent;
    TaskViewThumbnail mThumbnailView;
    TaskViewHeader mHeaderView;
    View mActionButtonView;
    TaskViewCallbacks mCb;

    // Focus animation
    float mFocusProgress;
    Paint mFocusPaint = new Paint();
    int mFocusColor = 0xff009688;
    int mFocusAlpha = 0x40;
    int mFocusBorderAlpha;
    static Interpolator sFocusInInterpolator = new DecelerateInterpolator(3f);
    static Interpolator sFocusInRadiusInterpolator = new DecelerateInterpolator();
    static Interpolator sFocusOutInterpolator = new DecelerateInterpolator();
    ObjectAnimator mFocusAnimator;
    static long sFocusInDurationMs = 350;
    static long sFocusOutDurationMs = 200;
    float mFocusInCircleRadiusProgress;
    int mFocusInFillAlpha;
    int mFocusInCircleAlpha;
    int mFocusOutFillAlpha;
    boolean mFocusAnimatorWasTriggered;
    int mFocusBorderSize;

    // Optimizations
    ValueAnimator.AnimatorUpdateListener mUpdateDimListener =
            new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    setTaskProgress((Float) animation.getAnimatedValue());
                }
            };

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

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

    public TaskView(Context context, AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

    public TaskView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        mConfig = RecentsConfiguration.getInstance();
        mMaxDimScale = mConfig.taskStackMaxDim / 255f;
        mClipViewInStack = true;
        mViewBounds = new AnimateableViewBounds(this, mConfig.taskViewRoundedCornerRadiusPx);
        setTaskProgress(getTaskProgress());
        setDim(getDim());
        if (mConfig.fakeShadows) {
            setBackground(new FakeShadowDrawable(context.getResources(), mConfig));
        }
        setOutlineProvider(mViewBounds);

        mFocusAnimator = ObjectAnimator.ofFloat(this, "focusProgress", 1f);
        mFocusAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animator) {
                mFocusAnimatorWasTriggered = true;
            }
        });

        mFocusColor =
                context.getResources().getColor(R.color.recents_focus_color);
        mFocusPaint.setColor(mFocusColor);
        mFocusBorderSize =
                context.getResources().getDimensionPixelSize(R.dimen.recents_border_size);
    }

    /** Set callback */
    void setCallbacks(TaskViewCallbacks cb) {
        mCb = cb;
    }

    /** Resets this TaskView for reuse. */
    void reset() {
        resetViewProperties();
        setClipViewInStack(false);
        setCallbacks(null);
        disableFocusAnimations();
    }

    /** Gets the task */
    Task getTask() {
        return mTask;
    }

    /** Returns the view bounds. */
    AnimateableViewBounds getViewBounds() {
        return mViewBounds;
    }

    @Override
    protected void onFinishInflate() {
        // Bind the views
        mContent = findViewById(R.id.task_view_content);
        mHeaderView = (TaskViewHeader) findViewById(R.id.task_view_bar);
        mThumbnailView = (TaskViewThumbnail) findViewById(R.id.task_view_thumbnail);
        mThumbnailView.updateClipToTaskBar(mHeaderView);
        mActionButtonView = findViewById(R.id.lock_to_app_fab);
        mActionButtonView.setOutlineProvider(new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {
                // Set the outline to match the FAB background
                outline.setOval(0, 0, mActionButtonView.getWidth(), mActionButtonView.getHeight());
            }
        });
        mActionButtonTranslationZ = mActionButtonView.getTranslationZ();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);

        int widthWithoutPadding = width - mPaddingLeft - mPaddingRight;
        int heightWithoutPadding = height - mPaddingTop - mPaddingBottom;

        // Measure the content
        mContent.measure(MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY));

        // Measure the bar view, and action button
        mHeaderView.measure(MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(mConfig.taskBarHeight, MeasureSpec.EXACTLY));
        mActionButtonView.measure(
                MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.AT_MOST),
                MeasureSpec.makeMeasureSpec(heightWithoutPadding, MeasureSpec.AT_MOST));
        // Measure the thumbnail to be square
        mThumbnailView.measure(
                MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(widthWithoutPadding, MeasureSpec.EXACTLY));
        setMeasuredDimension(width, height);
        invalidateOutline();
    }

    /** Synchronizes this view's properties with the task's transform */
    void updateViewPropertiesToTaskTransform(TaskViewTransform toTransform, int duration) {
        updateViewPropertiesToTaskTransform(toTransform, duration, null);
    }

    void updateViewPropertiesToTaskTransform(TaskViewTransform toTransform, int duration,
            ValueAnimator.AnimatorUpdateListener updateCallback) {
        // Apply the transform
        toTransform.applyToTaskView(this, duration, mConfig.fastOutSlowInInterpolator, false,
                !mConfig.fakeShadows, updateCallback);

        // Update the task progress
        Utilities.cancelAnimationWithoutCallbacks(mTaskProgressAnimator);
        if (duration <= 0) {
            setTaskProgress(toTransform.p);
        } else {
            mTaskProgressAnimator = ObjectAnimator.ofFloat(this, "taskProgress", toTransform.p);
            mTaskProgressAnimator.setDuration(duration);
            mTaskProgressAnimator.addUpdateListener(mUpdateDimListener);
            mTaskProgressAnimator.start();
        }
    }

    /** Resets this view's properties */
    void resetViewProperties() {
        unsetFocusedTask();
        setDim(0);
        setLayerType(View.LAYER_TYPE_NONE, null);
        TaskViewTransform.reset(this);
        if (mActionButtonView != null) {
            mActionButtonView.setScaleX(1f);
            mActionButtonView.setScaleY(1f);
            mActionButtonView.setAlpha(1f);
            mActionButtonView.setTranslationZ(mActionButtonTranslationZ);
        }
    }

    /**
     * When we are un/filtering, this method will set up the transform that we are animating to,
     * in order to hide the task.
     */
    void prepareTaskTransformForFilterTaskHidden(TaskViewTransform toTransform) {
        // Fade the view out and slide it away
        toTransform.alpha = 0f;
        toTransform.translationY += 200;
        toTransform.translationZ = 0;
    }

    /**
     * When we are un/filtering, this method will setup the transform that we are animating from,
     * in order to show the task.
     */
    void prepareTaskTransformForFilterTaskVisible(TaskViewTransform fromTransform) {
        // Fade the view in
        fromTransform.alpha = 0f;
    }

    /**
     * Prepares this task view for the enter-recents animations. This is called earlier in the
     * first layout because the actual animation into recents may take a long time.
     */
    void prepareEnterRecentsAnimation(boolean isTaskViewLaunchTargetTask,
            boolean occludesLaunchTarget, int offscreenY) {
        int initialDim = getDim();
        if (mConfig.launchedHasConfigurationChanged) {
            // Just load the views as-is
        } else if (mConfig.launchedFromAppWithThumbnail) {
            if (isTaskViewLaunchTargetTask) {
                // Set the dim to 0 so we can animate it in
                initialDim = 0;
                // Hide the action button
                mActionButtonView.setAlpha(0f);
            } else if (occludesLaunchTarget) {
                // Move the task view off screen (below) so we can animate it in
                setTranslationY(offscreenY);
            }

        } else if (mConfig.launchedFromHome) {
            // Move the task view off screen (below) so we can animate it in
            setTranslationY(offscreenY);
            setTranslationZ(0);
            setScaleX(1f);
            setScaleY(1f);
        }
        // Apply the current dim
        setDim(initialDim);
        // Prepare the thumbnail view alpha
        mThumbnailView.prepareEnterRecentsAnimation(isTaskViewLaunchTargetTask);
    }

    /** Animates this task view as it enters recents */
    void startEnterRecentsAnimation(final ViewAnimation.TaskViewEnterContext ctx) {
        final TaskViewTransform transform = ctx.currentTaskTransform;
        int startDelay = 0;

        if (mConfig.launchedFromAppWithThumbnail) {
            if (mTask.isLaunchTarget) {
                // Animate the dim/overlay
                if (Constants.DebugFlags.App.EnableThumbnailAlphaOnFrontmost) {
                    // Animate the thumbnail alpha before the dim animation (to prevent updating the
                    // hardware layer)
                    mThumbnailView.startEnterRecentsAnimation(mConfig.transitionEnterFromAppDelay,
                            new Runnable() {
                                @Override
                                public void run() {
                                    animateDimToProgress(0, mConfig.taskViewEnterFromAppDuration,
                                            ctx.postAnimationTrigger.decrementOnAnimationEnd());
                                }
                            });
                } else {
                    // Immediately start the dim animation
                    animateDimToProgress(mConfig.transitionEnterFromAppDelay,
                            mConfig.taskViewEnterFromAppDuration,
                            ctx.postAnimationTrigger.decrementOnAnimationEnd());
                }
                ctx.postAnimationTrigger.increment();

                // Animate the action button in
                fadeInActionButton(mConfig.transitionEnterFromAppDelay,
                        mConfig.taskViewEnterFromAppDuration);
            } else {
                // Animate the task up if it was occluding the launch target
                if (ctx.currentTaskOccludesLaunchTarget) {
                    setTranslationY(transform.translationY
                            + mConfig.taskViewAffiliateGroupEnterOffsetPx);
                    setAlpha(0f);
                    animate().alpha(1f)
                            .translationY(transform.translationY)
                            .setStartDelay(mConfig.transitionEnterFromAppDelay)
                            .setUpdateListener(null)
                            .setInterpolator(mConfig.fastOutSlowInInterpolator)
                            .setDuration(mConfig.taskViewEnterFromHomeDuration)
                            .withEndAction(new Runnable() {
                                @Override
                                public void run() {
                                    // Decrement the post animation trigger
                                    ctx.postAnimationTrigger.decrement();
                                }
                            })
                            .start();
                    ctx.postAnimationTrigger.increment();
                }
            }
            startDelay = mConfig.transitionEnterFromAppDelay;

        } else if (mConfig.launchedFromHome) {
            // Animate the tasks up
            int frontIndex = (ctx.currentStackViewCount - ctx.currentStackViewIndex - 1);
            int delay = mConfig.transitionEnterFromHomeDelay +
                    frontIndex * mConfig.taskViewEnterFromHomeStaggerDelay;

            setScaleX(transform.scale);
            setScaleY(transform.scale);
            if (!mConfig.fakeShadows) {
                animate().translationZ(transform.translationZ);
            }
            animate()
                    .translationY(transform.translationY)
                    .setStartDelay(delay)
                    .setUpdateListener(ctx.updateListener)
                    .setInterpolator(mConfig.quintOutInterpolator)
                    .setDuration(mConfig.taskViewEnterFromHomeDuration +
                            frontIndex * mConfig.taskViewEnterFromHomeStaggerDelay)
                    .withEndAction(new Runnable() {
                        @Override
                        public void run() {
                            // Decrement the post animation trigger
                            ctx.postAnimationTrigger.decrement();
                        }
                    })
                    .start();
            ctx.postAnimationTrigger.increment();
            startDelay = delay;
        }

        // Enable the focus animations from this point onwards so that they aren't affected by the
        // window transitions
        postDelayed(new Runnable() {
            @Override
            public void run() {
                enableFocusAnimations();
            }
        }, startDelay);
    }

    public void fadeInActionButton(int delay, int duration) {
        // Hide the action button
        mActionButtonView.setAlpha(0f);

        // Animate the action button in
        mActionButtonView.animate().alpha(1f)
                .setStartDelay(delay)
                .setDuration(duration)
                .setInterpolator(PhoneStatusBar.ALPHA_IN)
                .start();
    }

    /** Animates this task view as it leaves recents by pressing home. */
    void startExitToHomeAnimation(ViewAnimation.TaskViewExitContext ctx) {
        animate()
                .translationY(ctx.offscreenTranslationY)
                .setStartDelay(0)
                .setUpdateListener(null)
                .setInterpolator(mConfig.fastOutLinearInInterpolator)
                .setDuration(mConfig.taskViewExitToHomeDuration)
                .withEndAction(ctx.postAnimationTrigger.decrementAsRunnable())
                .start();
        ctx.postAnimationTrigger.increment();
    }

    /** Animates this task view away when dismissing all tasks. */
    void startDismissAllAnimation() {
        dismissTask();
    }

    /** Animates this task view as it exits recents */
    void startLaunchTaskAnimation(final Runnable postAnimRunnable, boolean isLaunchingTask,
            boolean occludesLaunchTarget, boolean lockToTask) {
        if (isLaunchingTask) {
            // Animate the thumbnail alpha back into full opacity for the window animation out
            mThumbnailView.startLaunchTaskAnimation(postAnimRunnable);

            // Animate the dim
            if (mDimAlpha > 0) {
                ObjectAnimator anim = ObjectAnimator.ofInt(this, "dim", 0);
                anim.setDuration(mConfig.taskViewExitToAppDuration);
                anim.setInterpolator(mConfig.fastOutLinearInInterpolator);
                anim.start();
            }

            // Animate the action button away
            if (!lockToTask) {
                float toScale = 0.9f;
                mActionButtonView.animate()
                        .scaleX(toScale)
                        .scaleY(toScale);
            }
            mActionButtonView.animate()
                    .alpha(0f)
                    .setStartDelay(0)
                    .setDuration(mConfig.taskViewExitToAppDuration)
                    .setInterpolator(mConfig.fastOutLinearInInterpolator)
                    .start();
        } else {
            // If this is another view in the task grouping and is in front of the launch task,
            // animate it away first
            if (occludesLaunchTarget) {
                animate()
                        .alpha(0f)
                        .translationY(
                                getTranslationY() + mConfig.taskViewAffiliateGroupEnterOffsetPx)
                        .setStartDelay(0)
                        .setUpdateListener(null)
                        .setInterpolator(mConfig.fastOutLinearInInterpolator)
                        .setDuration(mConfig.taskViewExitToAppDuration)
                        .start();
            }
        }
    }

    /** Animates the deletion of this task view */
    void startDeleteTaskAnimation(final Runnable r, int delay) {
        // Disabling clipping with the stack while the view is animating away
        setClipViewInStack(false);

        animate().translationX(mConfig.taskViewRemoveAnimTranslationXPx)
                .alpha(0f)
                .setStartDelay(delay)
                .setUpdateListener(null)
                .setInterpolator(mConfig.fastOutSlowInInterpolator)
                .setDuration(mConfig.taskViewRemoveAnimDuration)
                .withEndAction(new Runnable() {
                    @Override
                    public void run() {
                        if (r != null) {
                            r.run();
                        }

                        // Re-enable clipping with the stack (we will reuse this view)
                        setClipViewInStack(true);
                    }
                })
                .start();
    }

    /** Enables/disables handling touch on this task view. */
    void setTouchEnabled(boolean enabled) {
        setOnClickListener(enabled ? this : null);
    }

    /** Dismisses this task. */
    void dismissTask() {
        // Animate out the view and call the callback
        final TaskView tv = this;
        startDeleteTaskAnimation(new Runnable() {
            @Override
            public void run() {
                if (mCb != null) {
                    mCb.onTaskViewDismissed(tv);
                }
            }
        }, 0);
    }

    /**
     * Returns whether this view should be clipped, or any views below should clip against this
     * view.
     */
    boolean shouldClipViewInStack() {
        return mClipViewInStack && (getVisibility() == View.VISIBLE);
    }

    /** Sets whether this view should be clipped, or clipped against. */
    void setClipViewInStack(boolean clip) {
        if (clip != mClipViewInStack) {
            mClipViewInStack = clip;
            if (mCb != null) {
                mCb.onTaskViewClipStateChanged(this);
            }
        }
    }

    @Override
    public void dispatchDraw(Canvas canvas) {
        if (mFocusAnimatorWasTriggered) {
            canvas.save(Canvas.CLIP_SAVE_FLAG);
            mFocusPaint.setAlpha(mFocusBorderAlpha);
            canvas.clipRect(-mFocusBorderSize, -mFocusBorderSize,
                    getWidth() + mFocusBorderSize, getHeight() + mFocusBorderSize,
                    Region.Op.REPLACE);
            canvas.drawRoundRect(-mFocusBorderSize, -mFocusBorderSize,
                    getWidth() + mFocusBorderSize, getHeight() + mFocusBorderSize,
                    mConfig.taskViewRoundedCornerRadiusPx,
                    mConfig.taskViewRoundedCornerRadiusPx, mFocusPaint);
            canvas.restore();
        }

        super.dispatchDraw(canvas);

        if (mFocusAnimatorWasTriggered) {
            if (mIsFocused) {
                final int x = getWidth() / 2;
                final int y = getHeight() / 2;
                final float hypot = (float) Math.hypot(x, y);
                final float radius = hypot * mFocusInCircleRadiusProgress;

                mFocusPaint.setAlpha(mFocusInFillAlpha);
                canvas.drawRect(0, 0, getWidth(), getHeight(), mFocusPaint);

                mFocusPaint.setAlpha(mFocusInCircleAlpha);
                canvas.drawCircle(x, y, radius, mFocusPaint);
            } else {
                mFocusPaint.setAlpha(mFocusOutFillAlpha);
                canvas.drawRect(0, 0, getWidth(), getHeight(), mFocusPaint);
            }
        }
    }

    /** Sets the current focus animation progress. Used by the property animator. */
    public void setFocusProgress(float progress) {
        mFocusProgress = progress;

        if (mIsFocused) {
            final float interpolatedProgress = sFocusInInterpolator.getInterpolation(progress);

            mFocusInCircleRadiusProgress =
                    0.5f + sFocusInRadiusInterpolator.getInterpolation(progress);
            mFocusInCircleAlpha =
                    (int) (mFocusAlpha * interpolatedProgress);
            mFocusInFillAlpha =
                    Math.min((mFocusAlpha / 4) +
                            (int) ((mFocusAlpha / 2) * interpolatedProgress), 255);
            mFocusBorderAlpha =
                    Math.min(mFocusAlpha + (int) (mFocusAlpha * 3f * interpolatedProgress), 255);
        } else {
            final float interpolatedProgress = sFocusOutInterpolator.getInterpolation(progress);

            mFocusOutFillAlpha =
                    (int) (mFocusAlpha * (1 - interpolatedProgress));
            mFocusBorderAlpha =
                    Math.min((int) (mFocusAlpha * 4f * (1 - interpolatedProgress)), 255);
        }

        invalidate();
    }

    /** Returns the current focus animation progress. */
    public float getFocusProgress() {
        return mFocusProgress;
    }

    /** Sets the current task progress. */
    public void setTaskProgress(float p) {
        mTaskProgress = p;
        mViewBounds.setAlpha(p);
        updateDimFromTaskProgress();
    }

    /** Returns the current task progress. */
    public float getTaskProgress() {
        return mTaskProgress;
    }

    /** Returns the current dim. */
    public void setDim(int dim) {
        mDimAlpha = dim;
        if (mConfig.useHardwareLayers) {
            // Defer setting hardware layers if we have not yet measured, or there is no dim to draw
            if (getMeasuredWidth() > 0 && getMeasuredHeight() > 0) {
                mDimColorFilter.setColor(Color.argb(mDimAlpha, 0, 0, 0));
                mDimLayerPaint.setColorFilter(mDimColorFilter);
                mContent.setLayerType(LAYER_TYPE_HARDWARE, mDimLayerPaint);
            }
        } else {
            float dimAlpha = mDimAlpha / 255.0f;
            if (mThumbnailView != null) {
                mThumbnailView.setDimAlpha(dimAlpha);
            }
            if (mHeaderView != null) {
                mHeaderView.setDimAlpha(dim);
            }
        }
    }

    /** Returns the current dim. */
    public int getDim() {
        return mDimAlpha;
    }

    /** Animates the dim to the task progress. */
    void animateDimToProgress(int delay, int duration, Animator.AnimatorListener postAnimRunnable) {
        // Animate the dim into view as well
        int toDim = getDimFromTaskProgress();
        if (toDim != getDim()) {
            ObjectAnimator anim = ObjectAnimator.ofInt(TaskView.this, "dim", toDim);
            anim.setStartDelay(delay);
            anim.setDuration(duration);
            if (postAnimRunnable != null) {
                anim.addListener(postAnimRunnable);
            }
            anim.start();
        }
    }

    /** Compute the dim as a function of the scale of this view. */
    int getDimFromTaskProgress() {
        float dim = mMaxDimScale * mDimInterpolator.getInterpolation(1f - mTaskProgress);
        return (int) (dim * 255);
    }

    /** Update the dim as a function of the scale of this view. */
    void updateDimFromTaskProgress() {
        setDim(getDimFromTaskProgress());
    }

    /**** View focus state ****/

    /**
     * Sets the focused task explicitly. We need a separate flag because requestFocus() won't happen
     * if the view is not currently visible, or we are in touch state (where we still want to keep
     * track of focus).
     */
    public void setFocusedTask() {
        if (mIsFocused) {
            return;
        }
        mIsFocused = true;

        performFocusAnimation();
        // Update the thumbnail alpha with the focus
        mThumbnailView.onFocusChanged(true);
        // Call the callback
        if (mCb != null) {
            mCb.onTaskViewFocusChanged(this, true);
        }
        // Workaround, we don't always want it focusable in touch mode, but we want the first task
        // to be focused after the enter-recents animation, which can be triggered from either touch
        // or keyboard
        setFocusableInTouchMode(true);
        requestFocus();
        setFocusableInTouchMode(false);
        invalidate();
    }

    /** Performs the focus animation for alt-tab traversal. */
    private void performFocusAnimation() {
        if (mFocusAnimationsEnabled) {
            // Focus the header bar
            mHeaderView.onTaskViewFocusChanged(true);

            mFocusAnimator.setDuration(sFocusInDurationMs);
            mFocusAnimator.start();
        }
    }

    /**
     * Unsets the focused task explicitly.
     */
    void unsetFocusedTask() {
        if (!mIsFocused) {
            return;
        }

        mIsFocused = false;
        if (mFocusAnimationsEnabled) {
            // Un-focus the header bar
            mHeaderView.onTaskViewFocusChanged(false);

            mFocusAnimator.setDuration(sFocusOutDurationMs);
            mFocusAnimator.start();
        }

        // Update the thumbnail alpha with the focus
        mThumbnailView.onFocusChanged(false);
        // Call the callback
        if (mCb != null) {
            mCb.onTaskViewFocusChanged(this, false);
        }
        invalidate();
    }

    /**
     * Updates the explicitly focused state when the view focus changes.
     */
    @Override
    protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) {
        super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
        if (!gainFocus) {
            unsetFocusedTask();
        }
    }

    /**
     * Returns whether we have explicitly been focused.
     */
    public boolean isFocusedTask() {
        return mIsFocused;
    }

    /** Enables all focus animations. */
    void enableFocusAnimations() {
        boolean wasFocusAnimationsEnabled = mFocusAnimationsEnabled;
        mFocusAnimationsEnabled = true;
        if (mIsFocused && !wasFocusAnimationsEnabled) {
            // Re-notify the header if we were focused and animations were not previously enabled
            performFocusAnimation();
        }
    }

    /** Disables focus animations and resets focus state. */
    void disableFocusAnimations() {
        mFocusAnimationsEnabled = false;
        mIsFocused = false;
        mFocusAnimatorWasTriggered = false;
    }

    public void disableLayersForOneFrame() {
        mHeaderView.disableLayersForOneFrame();
    }

    /**** TaskCallbacks Implementation ****/

    /** Binds this task view to the task */
    public void onTaskBound(Task t) {
        mTask = t;
        mTask.setCallbacks(this);

        // Hide the action button if lock to app is disabled for this view
        int lockButtonVisibility = (!t.lockToTaskEnabled || !t.lockToThisTask) ? GONE : VISIBLE;
        if (mActionButtonView.getVisibility() != lockButtonVisibility) {
            mActionButtonView.setVisibility(lockButtonVisibility);
            requestLayout();
        }
    }

    @Override
    public void onTaskDataLoaded() {
        if (mThumbnailView != null && mHeaderView != null) {
            // Bind each of the views to the new task data
            mThumbnailView.rebindToTask(mTask);
            mHeaderView.rebindToTask(mTask);
            // Rebind any listeners
            AccessibilityManager am = (AccessibilityManager) getContext().
                    getSystemService(Context.ACCESSIBILITY_SERVICE);
            if (Constants.DebugFlags.App.EnableTaskFiltering || (am != null && am.isEnabled())) {
                mHeaderView.mApplicationIcon.setOnClickListener(this);
            }
            mHeaderView.mDismissButton.setOnClickListener(this);
            if (mConfig.multiStackEnabled) {
                mHeaderView.mMoveTaskButton.setOnClickListener(this);
            }
            mActionButtonView.setOnClickListener(this);
            mHeaderView.mApplicationIcon.setOnLongClickListener(this);
        }
        mTaskDataLoaded = true;
    }

    @Override
    public void onTaskDataUnloaded() {
        if (mThumbnailView != null && mHeaderView != null) {
            // Unbind each of the views from the task data and remove the task callback
            mTask.setCallbacks(null);
            mThumbnailView.unbindFromTask();
            mHeaderView.unbindFromTask();
            // Unbind any listeners
            mHeaderView.mApplicationIcon.setOnClickListener(null);
            mHeaderView.mDismissButton.setOnClickListener(null);
            if (mConfig.multiStackEnabled) {
                mHeaderView.mMoveTaskButton.setOnClickListener(null);
            }
            mActionButtonView.setOnClickListener(null);
            mHeaderView.mApplicationIcon.setOnLongClickListener(null);
        }
        mTaskDataLoaded = false;
    }

    @Override
    public void onMultiStackDebugTaskStackIdChanged() {
        mHeaderView.rebindToTask(mTask);
    }

    /**** View.OnClickListener Implementation ****/

    @Override
    public void onClick(final View v) {
        final TaskView tv = this;
        final boolean delayViewClick = (v != this) && (v != mActionButtonView);
        if (delayViewClick) {
            // We purposely post the handler delayed to allow for the touch feedback to draw
            postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (v == mHeaderView.mApplicationIcon) {
                        if (Constants.DebugFlags.App.EnableTaskFiltering) {
                            if (mCb != null) {
                                mCb.onTaskViewAppIconClicked(tv);
                            }
                        } else {
                            AccessibilityManager am = (AccessibilityManager) getContext().
                                    getSystemService(Context.ACCESSIBILITY_SERVICE);
                            if (am != null && am.isEnabled()) {
                                if (mCb != null) {
                                    mCb.onTaskViewAppInfoClicked(tv);
                                }
                            }
                        }
                    } else if (v == mHeaderView.mDismissButton) {
                        dismissTask();
                        // Keep track of deletions by the dismiss button
                        MetricsLogger.histogram(getContext(), "overview_task_dismissed_source",
                                Constants.Metrics.DismissSourceHeaderButton);
                    } else if (v == mHeaderView.mMoveTaskButton) {
                        if (mCb != null) {
                            mCb.onTaskResize(tv);
                        }
                    }
                }
            }, 125);
        } else {
            if (v == mActionButtonView) {
                // Reset the translation of the action button before we animate it out
                mActionButtonView.setTranslationZ(0f);
            }
            if (mCb != null) {
                mCb.onTaskViewClicked(tv, tv.getTask(), (v == mActionButtonView));
            }
        }
    }

    /**** View.OnLongClickListener Implementation ****/

    @Override
    public boolean onLongClick(View v) {
        if (v == mHeaderView.mApplicationIcon) {
            if (mCb != null) {
                mCb.onTaskViewAppInfoClicked(this);
                return true;
            }
        }
        return false;
    }
}
