/*
 * Copyright (C) 2012 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.keyguard;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.FloatProperty;
import android.util.Log;
import android.util.Property;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.Interpolator;
import android.widget.Scroller;

/**
 * This layout handles interaction with the sliding security challenge views
 * that overlay/resize other keyguard contents.
 */
public class SlidingChallengeLayout extends ViewGroup implements ChallengeLayout {
    private static final String TAG = "SlidingChallengeLayout";
    private static final boolean DEBUG = false;

    // The drag handle is measured in dp above & below the top edge of the
    // challenge view; these parameters change based on whether the challenge 
    // is open or closed.
    private static final int DRAG_HANDLE_CLOSED_ABOVE = 8; // dp
    private static final int DRAG_HANDLE_CLOSED_BELOW = 0; // dp
    private static final int DRAG_HANDLE_OPEN_ABOVE = 8; // dp
    private static final int DRAG_HANDLE_OPEN_BELOW = 0; // dp

    private static final int HANDLE_ANIMATE_DURATION = 250; // ms

    // Drawn to show the drag handle in closed state; crossfades to the challenge view
    // when challenge is fully visible
    private boolean mEdgeCaptured;

    private DisplayMetrics mDisplayMetrics;

    // Initialized during measurement from child layoutparams
    private View mExpandChallengeView;
    private KeyguardSecurityContainer mChallengeView;
    private View mScrimView;
    private View mWidgetsView;

    // Range: 0 (fully hidden) to 1 (fully visible)
    private float mChallengeOffset = 1.f;
    private boolean mChallengeShowing = true;
    private boolean mChallengeShowingTargetState = true;
    private boolean mWasChallengeShowing = true;
    private boolean mIsBouncing = false;

    private final Scroller mScroller;
    private ObjectAnimator mFader;
    private int mScrollState;
    private OnChallengeScrolledListener mScrollListener;
    private OnBouncerStateChangedListener mBouncerListener;

    public static final int SCROLL_STATE_IDLE = 0;
    public static final int SCROLL_STATE_DRAGGING = 1;
    public static final int SCROLL_STATE_SETTLING = 2;
    public static final int SCROLL_STATE_FADING = 3;

    private static final int CHALLENGE_FADE_OUT_DURATION = 100;
    private static final int CHALLENGE_FADE_IN_DURATION = 160;

    private static final int MAX_SETTLE_DURATION = 600; // ms

    // ID of the pointer in charge of a current drag
    private int mActivePointerId = INVALID_POINTER;
    private static final int INVALID_POINTER = -1;

    // True if the user is currently dragging the slider
    private boolean mDragging;
    // True if the user may not drag until a new gesture begins
    private boolean mBlockDrag;

    private VelocityTracker mVelocityTracker;
    private int mMinVelocity;
    private int mMaxVelocity;
    private float mGestureStartX, mGestureStartY; // where did you first touch the screen?
    private int mGestureStartChallengeBottom; // where was the challenge at that time?

    private int mDragHandleClosedBelow; // handle hitrect extension into the challenge view
    private int mDragHandleClosedAbove; // extend the handle's hitrect this far above the line
    private int mDragHandleOpenBelow; // handle hitrect extension into the challenge view
    private int mDragHandleOpenAbove; // extend the handle's hitrect this far above the line

    private int mDragHandleEdgeSlop;
    private int mChallengeBottomBound; // Number of pixels from the top of the challenge view
                                       // that should remain on-screen

    private int mTouchSlop;
    private int mTouchSlopSquare;

    float mHandleAlpha;
    float mFrameAlpha;
    float mFrameAnimationTarget = Float.MIN_VALUE;
    private ObjectAnimator mHandleAnimation;
    private ObjectAnimator mFrameAnimation;

    private boolean mHasGlowpad;

    // We have an internal and external version, and we and them together.
    private boolean mChallengeInteractiveExternal = true;
    private boolean mChallengeInteractiveInternal = true;

    static final Property<SlidingChallengeLayout, Float> HANDLE_ALPHA =
            new FloatProperty<SlidingChallengeLayout>("handleAlpha") {
        @Override
        public void setValue(SlidingChallengeLayout view, float value) {
            view.mHandleAlpha = value;
            view.invalidate();
        }

        @Override
        public Float get(SlidingChallengeLayout view) {
            return view.mHandleAlpha;
        }
    };

    // True if at least one layout pass has happened since the view was attached.
    private boolean mHasLayout;

    private static final Interpolator sMotionInterpolator = new Interpolator() {
        public float getInterpolation(float t) {
            t -= 1.0f;
            return t * t * t * t * t + 1.0f;
        }
    };

    private static final Interpolator sHandleFadeInterpolator = new Interpolator() {
        public float getInterpolation(float t) {
            return t * t;
        }
    };

    private final Runnable mEndScrollRunnable = new Runnable () {
        public void run() {
            completeChallengeScroll();
        }
    };

    private final OnClickListener mScrimClickListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            hideBouncer();
        }
    };

    private final OnClickListener mExpandChallengeClickListener = new OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!isChallengeShowing()) {
                showChallenge(true);
            }
        }
    };

    /**
     * Listener interface that reports changes in scroll state of the challenge area.
     */
    public interface OnChallengeScrolledListener {
        /**
         * The scroll state itself changed.
         *
         * <p>scrollState will be one of the following:</p>
         *
         * <ul>
         * <li><code>SCROLL_STATE_IDLE</code> - The challenge area is stationary.</li>
         * <li><code>SCROLL_STATE_DRAGGING</code> - The user is actively dragging
         * the challenge area.</li>
         * <li><code>SCROLL_STATE_SETTLING</code> - The challenge area is animating
         * into place.</li>
         * </ul>
         *
         * <p>Do not perform expensive operations (e.g. layout)
         * while the scroll state is not <code>SCROLL_STATE_IDLE</code>.</p>
         *
         * @param scrollState The new scroll state of the challenge area.
         */
        public void onScrollStateChanged(int scrollState);

        /**
         * The precise position of the challenge area has changed.
         *
         * <p>NOTE: It is NOT safe to modify layout or call any View methods that may
         * result in a requestLayout anywhere in your view hierarchy as a result of this call.
         * It may be called during drawing.</p>
         *
         * @param scrollPosition New relative position of the challenge area.
         *                       1.f = fully visible/ready to be interacted with.
         *                       0.f = fully invisible/inaccessible to the user.
         * @param challengeTop Position of the top edge of the challenge view in px in the
         *                     SlidingChallengeLayout's coordinate system.
         */
        public void onScrollPositionChanged(float scrollPosition, int challengeTop);
    }

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

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

    public SlidingChallengeLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        mScroller = new Scroller(context, sMotionInterpolator);

        final ViewConfiguration vc = ViewConfiguration.get(context);
        mMinVelocity = vc.getScaledMinimumFlingVelocity();
        mMaxVelocity = vc.getScaledMaximumFlingVelocity();

        final Resources res = getResources();
        mDragHandleEdgeSlop = res.getDimensionPixelSize(R.dimen.kg_edge_swipe_region_size);

        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        mTouchSlopSquare = mTouchSlop * mTouchSlop;

        mDisplayMetrics = res.getDisplayMetrics();
        final float density = mDisplayMetrics.density;

        // top half of the lock icon, plus another 25% to be sure
        mDragHandleClosedAbove = (int) (DRAG_HANDLE_CLOSED_ABOVE * density + 0.5f);
        mDragHandleClosedBelow = (int) (DRAG_HANDLE_CLOSED_BELOW * density + 0.5f);
        mDragHandleOpenAbove = (int) (DRAG_HANDLE_OPEN_ABOVE * density + 0.5f);
        mDragHandleOpenBelow = (int) (DRAG_HANDLE_OPEN_BELOW * density + 0.5f);

        // how much space to account for in the handle when closed
        mChallengeBottomBound = res.getDimensionPixelSize(R.dimen.kg_widget_pager_bottom_padding);

        setWillNotDraw(false);
        setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_STABLE);
    }

    public void setHandleAlpha(float alpha) {
        if (mExpandChallengeView != null) {
            mExpandChallengeView.setAlpha(alpha);
        }
    }

    public void setChallengeInteractive(boolean interactive) {
        mChallengeInteractiveExternal = interactive;
        if (mExpandChallengeView != null) {
            mExpandChallengeView.setEnabled(interactive);
        }
    }

    void animateHandle(boolean visible) {
        if (mHandleAnimation != null) {
            mHandleAnimation.cancel();
            mHandleAnimation = null;
        }
        final float targetAlpha = visible ? 1.f : 0.f;
        if (targetAlpha == mHandleAlpha) {
            return;
        }
        mHandleAnimation = ObjectAnimator.ofFloat(this, HANDLE_ALPHA, targetAlpha);
        mHandleAnimation.setInterpolator(sHandleFadeInterpolator);
        mHandleAnimation.setDuration(HANDLE_ANIMATE_DURATION);
        mHandleAnimation.start();
    }

    private void sendInitialListenerUpdates() {
        if (mScrollListener != null) {
            int challengeTop = mChallengeView != null ? mChallengeView.getTop() : 0;
            mScrollListener.onScrollPositionChanged(mChallengeOffset, challengeTop);
            mScrollListener.onScrollStateChanged(mScrollState);
        }
    }

    public void setOnChallengeScrolledListener(OnChallengeScrolledListener listener) {
        mScrollListener = listener;
        if (mHasLayout) {
            sendInitialListenerUpdates();
        }
    }

    public void setOnBouncerStateChangedListener(OnBouncerStateChangedListener listener) {
        mBouncerListener = listener;
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();

        mHasLayout = false;
    }

    @Override
    public void onDetachedFromWindow() {
        super.onDetachedFromWindow();

        removeCallbacks(mEndScrollRunnable);
        mHasLayout = false;
    }

    @Override
    public void requestChildFocus(View child, View focused) {
        if (mIsBouncing && child != mChallengeView) {
            // Clear out of the bouncer if the user tries to move focus outside of
            // the security challenge view.
            hideBouncer();
        }
        super.requestChildFocus(child, focused);
    }

    // We want the duration of the page snap animation to be influenced by the distance that
    // the screen has to travel, however, we don't want this duration to be effected in a
    // purely linear fashion. Instead, we use this method to moderate the effect that the distance
    // of travel has on the overall snap duration.
    float distanceInfluenceForSnapDuration(float f) {
        f -= 0.5f; // center the values about 0.
        f *= 0.3f * Math.PI / 2.0f;
        return (float) Math.sin(f);
    }

    void setScrollState(int state) {
        if (mScrollState != state) {
            mScrollState = state;

            animateHandle(state == SCROLL_STATE_IDLE && !mChallengeShowing);
            if (mScrollListener != null) {
                mScrollListener.onScrollStateChanged(state);
            }
        }
    }

    void completeChallengeScroll() {
        setChallengeShowing(mChallengeShowingTargetState);
        mChallengeOffset = mChallengeShowing ? 1.f : 0.f;
        setScrollState(SCROLL_STATE_IDLE);
        mChallengeInteractiveInternal = true;
        mChallengeView.setLayerType(LAYER_TYPE_NONE, null);
    }

    void setScrimView(View scrim) {
        if (mScrimView != null) {
            mScrimView.setOnClickListener(null);
        }
        mScrimView = scrim;
        mScrimView.setVisibility(mIsBouncing ? VISIBLE : GONE);
        mScrimView.setFocusable(true);
        mScrimView.setOnClickListener(mScrimClickListener);
    }

    /**
     * Animate the bottom edge of the challenge view to the given position.
     *
     * @param y desired final position for the bottom edge of the challenge view in px
     * @param velocity velocity in
     */
    void animateChallengeTo(int y, int velocity) {
        if (mChallengeView == null) {
            // Nothing to do.
            return;
        }

        cancelTransitionsInProgress();

        mChallengeInteractiveInternal = false;
        mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
        final int sy = mChallengeView.getBottom();
        final int dy = y - sy;
        if (dy == 0) {
            completeChallengeScroll();
            return;
        }

        setScrollState(SCROLL_STATE_SETTLING);

        final int childHeight = mChallengeView.getHeight();
        final int halfHeight = childHeight / 2;
        final float distanceRatio = Math.min(1f, 1.0f * Math.abs(dy) / childHeight);
        final float distance = halfHeight + halfHeight *
                distanceInfluenceForSnapDuration(distanceRatio);

        int duration = 0;
        velocity = Math.abs(velocity);
        if (velocity > 0) {
            duration = 4 * Math.round(1000 * Math.abs(distance / velocity));
        } else {
            final float childDelta = (float) Math.abs(dy) / childHeight;
            duration = (int) ((childDelta + 1) * 100);
        }
        duration = Math.min(duration, MAX_SETTLE_DURATION);

        mScroller.startScroll(0, sy, 0, dy, duration);
        postInvalidateOnAnimation();
    }

    private void setChallengeShowing(boolean showChallenge) {
        if (mChallengeShowing == showChallenge) {
            return;
        }
        mChallengeShowing = showChallenge;

        if (mExpandChallengeView == null || mChallengeView == null) {
            // These might not be here yet if we haven't been through layout.
            // If we haven't, the first layout pass will set everything up correctly
            // based on mChallengeShowing as set above.
            return;
        }

        if (mChallengeShowing) {
            mExpandChallengeView.setVisibility(View.INVISIBLE);
            mChallengeView.setVisibility(View.VISIBLE);
            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
                mChallengeView.requestAccessibilityFocus();
                mChallengeView.announceForAccessibility(mContext.getString(
                        R.string.keyguard_accessibility_unlock_area_expanded));
            }
        } else {
            mExpandChallengeView.setVisibility(View.VISIBLE);
            mChallengeView.setVisibility(View.INVISIBLE);
            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
                mExpandChallengeView.requestAccessibilityFocus();
                mChallengeView.announceForAccessibility(mContext.getString(
                        R.string.keyguard_accessibility_unlock_area_collapsed));
            }
        }
    }

    /**
     * @return true if the challenge is at all visible.
     */
    public boolean isChallengeShowing() {
        return mChallengeShowing;
    }

    @Override
    public boolean isChallengeOverlapping() {
        return mChallengeShowing;
    }

    @Override
    public boolean isBouncing() {
        return mIsBouncing;
    }

    @Override
    public int getBouncerAnimationDuration() {
        return HANDLE_ANIMATE_DURATION;
    }

    @Override
    public void showBouncer() {
        if (mIsBouncing) return;
        mWasChallengeShowing = mChallengeShowing;
        mIsBouncing = true;
        showChallenge(true);
        if (mScrimView != null) {
            Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 1f);
            anim.setDuration(HANDLE_ANIMATE_DURATION);
            anim.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animation) {
                    mScrimView.setVisibility(VISIBLE);
                }
            });
            anim.start();
        }
        if (mChallengeView != null) {
            mChallengeView.showBouncer(HANDLE_ANIMATE_DURATION);
        }

        if (mBouncerListener != null) {
            mBouncerListener.onBouncerStateChanged(true);
        }
    }

    @Override
    public void hideBouncer() {
        if (!mIsBouncing) return;
        if (!mWasChallengeShowing) showChallenge(false);
        mIsBouncing = false;

        if (mScrimView != null) {
            Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 0f);
            anim.setDuration(HANDLE_ANIMATE_DURATION);
            anim.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    mScrimView.setVisibility(GONE);
                }
            });
            anim.start();
        }
        if (mChallengeView != null) {
            mChallengeView.hideBouncer(HANDLE_ANIMATE_DURATION);
        }
        if (mBouncerListener != null) {
            mBouncerListener.onBouncerStateChanged(false);
        }
    }

    private int getChallengeMargin(boolean expanded) {
        return expanded && mHasGlowpad ? 0 : mDragHandleEdgeSlop;
    }

    private float getChallengeAlpha() {
        float x = mChallengeOffset - 1;
        return x * x * x + 1.f;
    }

    @Override
    public void requestDisallowInterceptTouchEvent(boolean allowIntercept) {
        // We'll intercept whoever we feel like! ...as long as it isn't a challenge view.
        // If there are one or more pointers in the challenge view before we take over
        // touch events, onInterceptTouchEvent will set mBlockDrag.
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(ev);

        final int action = ev.getActionMasked();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                mGestureStartX = ev.getX();
                mGestureStartY = ev.getY();
                mBlockDrag = false;
                break;

            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                resetTouch();
                break;

            case MotionEvent.ACTION_MOVE:
                final int count = ev.getPointerCount();
                for (int i = 0; i < count; i++) {
                    final float x = ev.getX(i);
                    final float y = ev.getY(i);
                    if (!mIsBouncing && mActivePointerId == INVALID_POINTER
                                && (crossedDragHandle(x, y, mGestureStartY)
                                || (isInChallengeView(x, y) &&
                                        mScrollState == SCROLL_STATE_SETTLING))) {
                        mActivePointerId = ev.getPointerId(i);
                        mGestureStartX = x;
                        mGestureStartY = y;
                        mGestureStartChallengeBottom = getChallengeBottom();
                        mDragging = true;
                        mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
                    } else if (mChallengeShowing && isInChallengeView(x, y)) {
                        mBlockDrag = true;
                    }
                }
                break;
        }

        if (mBlockDrag || isChallengeInteractionBlocked()) {
            mActivePointerId = INVALID_POINTER;
            mDragging = false;
        }

        return mDragging;
    }

    private boolean isChallengeInteractionBlocked() {
        return !mChallengeInteractiveExternal || !mChallengeInteractiveInternal;
    }

    private void resetTouch() {
        mVelocityTracker.recycle();
        mVelocityTracker = null;
        mActivePointerId = INVALID_POINTER;
        mDragging = mBlockDrag = false;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (mVelocityTracker == null) {
            mVelocityTracker = VelocityTracker.obtain();
        }
        mVelocityTracker.addMovement(ev);

        final int action = ev.getActionMasked();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                mBlockDrag = false;
                mGestureStartX = ev.getX();
                mGestureStartY = ev.getY();
                break;

            case MotionEvent.ACTION_CANCEL:
                if (mDragging && !isChallengeInteractionBlocked()) {
                    showChallenge(0);
                }
                resetTouch();
                break;

            case MotionEvent.ACTION_POINTER_UP:
                if (mActivePointerId != ev.getPointerId(ev.getActionIndex())) {
                    break;
                }
            case MotionEvent.ACTION_UP:
                if (mDragging && !isChallengeInteractionBlocked()) {
                    mVelocityTracker.computeCurrentVelocity(1000, mMaxVelocity);
                    showChallenge((int) mVelocityTracker.getYVelocity(mActivePointerId));
                }
                resetTouch();
                break;

            case MotionEvent.ACTION_MOVE:
                if (!mDragging && !mBlockDrag && !mIsBouncing) {
                    final int count = ev.getPointerCount();
                    for (int i = 0; i < count; i++) {
                        final float x = ev.getX(i);
                        final float y = ev.getY(i);

                        if ((isInDragHandle(x, y) || crossedDragHandle(x, y, mGestureStartY) ||
                                (isInChallengeView(x, y) && mScrollState == SCROLL_STATE_SETTLING))
                                && mActivePointerId == INVALID_POINTER
                                && !isChallengeInteractionBlocked()) {
                            mGestureStartX = x;
                            mGestureStartY = y;
                            mActivePointerId = ev.getPointerId(i);
                            mGestureStartChallengeBottom = getChallengeBottom();
                            mDragging = true;
                            mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);
                            break;
                        }
                    }
                }
                // Not an else; this can be set above.
                if (mDragging) {
                    // No-op if already in this state, but set it here in case we arrived
                    // at this point from either intercept or the above.
                    setScrollState(SCROLL_STATE_DRAGGING);

                    final int index = ev.findPointerIndex(mActivePointerId);
                    if (index < 0) {
                        // Oops, bogus state. We lost some touch events somewhere.
                        // Just drop it with no velocity and let things settle.
                        resetTouch();
                        showChallenge(0);
                        return true;
                    }
                    final float y = ev.getY(index);
                    final float pos = Math.min(y - mGestureStartY,
                            getLayoutBottom() - mChallengeBottomBound);

                    moveChallengeTo(mGestureStartChallengeBottom + (int) pos);
                }
                break;
        }
        return true;
    }

    /**
     * The lifecycle of touch events is subtle and it's very easy to do something
     * that will cause bugs that will be nasty to track when overriding this method.
     * Normally one should always override onInterceptTouchEvent instead.
     *
     * To put it another way, don't try this at home.
     */
    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        final int action = ev.getActionMasked();
        boolean handled = false;
        if (action == MotionEvent.ACTION_DOWN) {
            // Defensive programming: if we didn't get the UP or CANCEL, reset anyway.
            mEdgeCaptured = false;
        }
        if (mWidgetsView != null && !mIsBouncing && (mEdgeCaptured || isEdgeSwipeBeginEvent(ev))) {
            // Normally we would need to do a lot of extra stuff here.
            // We can only get away with this because we haven't padded in
            // the widget pager or otherwise transformed it during layout.
            // We also don't support things like splitting MotionEvents.

            // We set handled to captured even if dispatch is returning false here so that
            // we don't send a different view a busted or incomplete event stream.
            handled = mEdgeCaptured |= mWidgetsView.dispatchTouchEvent(ev);
        }

        if (!handled && !mEdgeCaptured) {
            handled = super.dispatchTouchEvent(ev);
        }

        if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
            mEdgeCaptured = false;
        }

        return handled;
    }

    private boolean isEdgeSwipeBeginEvent(MotionEvent ev) {
        if (ev.getActionMasked() != MotionEvent.ACTION_DOWN) {
            return false;
        }

        final float x = ev.getX();
        return x < mDragHandleEdgeSlop || x >= getWidth() - mDragHandleEdgeSlop;
    }

    /**
     * We only want to add additional vertical space to the drag handle when the panel is fully
     * closed.
     */
    private int getDragHandleSizeAbove() {
        return isChallengeShowing() ? mDragHandleOpenAbove : mDragHandleClosedAbove;
    }
    private int getDragHandleSizeBelow() {
        return isChallengeShowing() ? mDragHandleOpenBelow : mDragHandleClosedBelow;
    }

    private boolean isInChallengeView(float x, float y) {
        return isPointInView(x, y, mChallengeView);
    }

    private boolean isInDragHandle(float x, float y) {
        return isPointInView(x, y, mExpandChallengeView);
    }

    private boolean isPointInView(float x, float y, View view) {
        if (view == null) {
            return false;
        }
        return x >= view.getLeft() && y >= view.getTop()
                && x < view.getRight() && y < view.getBottom();
    }

    private boolean crossedDragHandle(float x, float y, float initialY) {

        final int challengeTop = mChallengeView.getTop();
        final boolean horizOk = x >= 0 && x < getWidth();

        final boolean vertOk;
        if (mChallengeShowing) {
            vertOk = initialY < (challengeTop - getDragHandleSizeAbove()) &&
                    y > challengeTop + getDragHandleSizeBelow();
        } else {
            vertOk = initialY > challengeTop + getDragHandleSizeBelow() &&
                    y < challengeTop - getDragHandleSizeAbove();
        }
        return horizOk && vertOk;
    }

    private int makeChildMeasureSpec(int maxSize, int childDimen) {
        final int mode;
        final int size;
        switch (childDimen) {
            case LayoutParams.WRAP_CONTENT:
                mode = MeasureSpec.AT_MOST;
                size = maxSize;
                break;
            case LayoutParams.MATCH_PARENT:
                mode = MeasureSpec.EXACTLY;
                size = maxSize;
                break;
            default:
                mode = MeasureSpec.EXACTLY;
                size = Math.min(maxSize, childDimen);
                break;
        }
        return MeasureSpec.makeMeasureSpec(size, mode);
    }

    @Override
    protected void onMeasure(int widthSpec, int heightSpec) {
        if (MeasureSpec.getMode(widthSpec) != MeasureSpec.EXACTLY ||
                MeasureSpec.getMode(heightSpec) != MeasureSpec.EXACTLY) {
            throw new IllegalArgumentException(
                    "SlidingChallengeLayout must be measured with an exact size");
        }

        final int width = MeasureSpec.getSize(widthSpec);
        final int height = MeasureSpec.getSize(heightSpec);
        setMeasuredDimension(width, height);

        // Find one and only one challenge view.
        final View oldChallengeView = mChallengeView;
        final View oldExpandChallengeView = mChallengeView;
        mChallengeView = null;
        mExpandChallengeView = null;
        final int count = getChildCount();

        // First iteration through the children finds special children and sets any associated
        // state.
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            if (lp.childType == LayoutParams.CHILD_TYPE_CHALLENGE) {
                if (mChallengeView != null) {
                    throw new IllegalStateException(
                            "There may only be one child with layout_isChallenge=\"true\"");
                }
                if (!(child instanceof KeyguardSecurityContainer)) {
                            throw new IllegalArgumentException(
                                    "Challenge must be a KeyguardSecurityContainer");
                }
                mChallengeView = (KeyguardSecurityContainer) child;
                if (mChallengeView != oldChallengeView) {
                    mChallengeView.setVisibility(mChallengeShowing ? VISIBLE : INVISIBLE);
                }
                // We're going to play silly games with the frame's background drawable later.
                if (!mHasLayout) {
                    // Set up the margin correctly based on our content for the first run.
                    mHasGlowpad = child.findViewById(R.id.keyguard_selector_view) != null;
                    lp.leftMargin = lp.rightMargin = getChallengeMargin(true);
                }
            } else if (lp.childType == LayoutParams.CHILD_TYPE_EXPAND_CHALLENGE_HANDLE) {
                if (mExpandChallengeView != null) {
                    throw new IllegalStateException(
                            "There may only be one child with layout_childType"
                            + "=\"expandChallengeHandle\"");
                }
                mExpandChallengeView = child;
                if (mExpandChallengeView != oldExpandChallengeView) {
                    mExpandChallengeView.setVisibility(mChallengeShowing ? INVISIBLE : VISIBLE);
                    mExpandChallengeView.setOnClickListener(mExpandChallengeClickListener);
                }
            } else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
                setScrimView(child);
            } else if (lp.childType == LayoutParams.CHILD_TYPE_WIDGETS) {
                mWidgetsView = child;
            }
        }

        // We want to measure the challenge view first, since the KeyguardWidgetPager
        // needs to do things its measure pass that are dependent on the challenge view
        // having been measured.
        if (mChallengeView != null && mChallengeView.getVisibility() != View.GONE) {
            // This one's a little funny. If the IME is present - reported in the form
            // of insets on the root view - we only give the challenge the space it would
            // have had if the IME wasn't there in order to keep the rest of the layout stable.
            // We base this on the layout_maxHeight on the challenge view. If it comes out
            // negative or zero, either we didn't have a maxHeight or we're totally out of space,
            // so give up and measure as if this rule weren't there.
            int challengeHeightSpec = heightSpec;
            final View root = getRootView();
            if (root != null) {
                final LayoutParams lp = (LayoutParams) mChallengeView.getLayoutParams();
                final int specSize = MeasureSpec.getSize(heightSpec);
                final int windowHeight = mDisplayMetrics.heightPixels - root.getPaddingTop();
                final int diff = windowHeight - specSize;
                final int maxChallengeHeight = lp.maxHeight - diff;
                if (maxChallengeHeight > 0) {
                    challengeHeightSpec = makeChildMeasureSpec(maxChallengeHeight, lp.height);
                }
            }
            measureChildWithMargins(mChallengeView, widthSpec, 0, challengeHeightSpec, 0);
        }

        // Measure the rest of the children
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() == GONE) {
                continue;
            }
            // Don't measure the challenge view twice!
            if (child == mChallengeView) continue;

            // Measure children. Widget frame measures special, so that we can ignore
            // insets for the IME.
            int parentWidthSpec = widthSpec, parentHeightSpec = heightSpec;
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            if (lp.childType == LayoutParams.CHILD_TYPE_WIDGETS) {
                final View root = getRootView();
                if (root != null) {
                    // This calculation is super dodgy and relies on several assumptions.
                    // Specifically that the root of the window will be padded in for insets
                    // and that the window is LAYOUT_IN_SCREEN.
                    final int windowWidth = mDisplayMetrics.widthPixels;
                    final int windowHeight = mDisplayMetrics.heightPixels - root.getPaddingTop();
                    parentWidthSpec = MeasureSpec.makeMeasureSpec(
                            windowWidth, MeasureSpec.EXACTLY);
                    parentHeightSpec = MeasureSpec.makeMeasureSpec(
                            windowHeight, MeasureSpec.EXACTLY);
                }
            }
            measureChildWithMargins(child, parentWidthSpec, 0, parentHeightSpec, 0);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int paddingLeft = getPaddingLeft();
        final int paddingTop = getPaddingTop();
        final int paddingRight = getPaddingRight();
        final int paddingBottom = getPaddingBottom();
        final int width = r - l;
        final int height = b - t;

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

            if (child.getVisibility() == GONE) continue;

            final LayoutParams lp = (LayoutParams) child.getLayoutParams();

            if (lp.childType == LayoutParams.CHILD_TYPE_CHALLENGE) {
                // Challenge views pin to the bottom, offset by a portion of their height,
                // and center horizontally.
                final int center = (paddingLeft + width - paddingRight) / 2;
                final int childWidth = child.getMeasuredWidth();
                final int childHeight = child.getMeasuredHeight();
                final int left = center - childWidth / 2;
                final int layoutBottom = height - paddingBottom - lp.bottomMargin;
                // We use the top of the challenge view to position the handle, so
                // we never want less than the handle size showing at the bottom.
                final int bottom = layoutBottom + (int) ((childHeight - mChallengeBottomBound)
                        * (1 - mChallengeOffset));
                child.setAlpha(getChallengeAlpha());
                child.layout(left, bottom - childHeight, left + childWidth, bottom);
            } else if (lp.childType == LayoutParams.CHILD_TYPE_EXPAND_CHALLENGE_HANDLE) {
                final int center = (paddingLeft + width - paddingRight) / 2;
                final int left = center - child.getMeasuredWidth() / 2;
                final int right = left + child.getMeasuredWidth();
                final int bottom = height - paddingBottom - lp.bottomMargin;
                final int top = bottom - child.getMeasuredHeight();
                child.layout(left, top, right, bottom);
            } else {
                // Non-challenge views lay out from the upper left, layered.
                child.layout(paddingLeft + lp.leftMargin,
                        paddingTop + lp.topMargin,
                        paddingLeft + child.getMeasuredWidth(),
                        paddingTop + child.getMeasuredHeight());
            }
        }

        if (!mHasLayout) {
            mHasLayout = true;
        }
    }

    @Override
    public void draw(Canvas c) {
        super.draw(c);
        if (DEBUG) {
            final Paint debugPaint = new Paint();
            debugPaint.setColor(0x40FF00CC);
            // show the isInDragHandle() rect
            c.drawRect(mDragHandleEdgeSlop,
                    mChallengeView.getTop() - getDragHandleSizeAbove(),
                    getWidth() - mDragHandleEdgeSlop,
                    mChallengeView.getTop() + getDragHandleSizeBelow(),
                    debugPaint);
        }
    }

    public void computeScroll() {
        super.computeScroll();

        if (!mScroller.isFinished()) {
            if (mChallengeView == null) {
                // Can't scroll if the view is missing.
                Log.e(TAG, "Challenge view missing in computeScroll");
                mScroller.abortAnimation();
                return;
            }

            mScroller.computeScrollOffset();
            moveChallengeTo(mScroller.getCurrY());

            if (mScroller.isFinished()) {
                post(mEndScrollRunnable);
            }
        }
    }

    private void cancelTransitionsInProgress() {
        if (!mScroller.isFinished()) {
            mScroller.abortAnimation();
            completeChallengeScroll();
        }
        if (mFader != null) {
            mFader.cancel();
        }
    }

    public void fadeInChallenge() {
        fadeChallenge(true);
    }

    public void fadeOutChallenge() {
        fadeChallenge(false);
    }

    public void fadeChallenge(final boolean show) {
        if (mChallengeView != null) {

            cancelTransitionsInProgress();
            float alpha = show ? 1f : 0f;
            int duration = show ? CHALLENGE_FADE_IN_DURATION : CHALLENGE_FADE_OUT_DURATION;
            mFader = ObjectAnimator.ofFloat(mChallengeView, "alpha", alpha);
            mFader.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animation) {
                    onFadeStart(show);
                }
                @Override
                public void onAnimationEnd(Animator animation) {
                    onFadeEnd(show);
                }
            });
            mFader.setDuration(duration);
            mFader.start();
        }
    }

    private int getMaxChallengeBottom() {
        if (mChallengeView == null) return 0;
        final int layoutBottom = getLayoutBottom();
        final int challengeHeight = mChallengeView.getMeasuredHeight();

        return (layoutBottom + challengeHeight - mChallengeBottomBound);
    }

    private int getMinChallengeBottom() {
        return getLayoutBottom();
    }


    private void onFadeStart(boolean show) {
        mChallengeInteractiveInternal = false;
        mChallengeView.setLayerType(LAYER_TYPE_HARDWARE, null);

        if (show) {
            moveChallengeTo(getMinChallengeBottom());
        }

        setScrollState(SCROLL_STATE_FADING);
    }

    private void onFadeEnd(boolean show) {
        mChallengeInteractiveInternal = true;
        setChallengeShowing(show);

        if (!show) {
            moveChallengeTo(getMaxChallengeBottom());
        }

        mChallengeView.setLayerType(LAYER_TYPE_NONE, null);
        mFader = null;
        setScrollState(SCROLL_STATE_IDLE);
    }

    public int getMaxChallengeTop() {
        if (mChallengeView == null) return 0;

        final int layoutBottom = getLayoutBottom();
        final int challengeHeight = mChallengeView.getMeasuredHeight();
        return layoutBottom - challengeHeight;
    }

    /**
     * Move the bottom edge of mChallengeView to a new position and notify the listener
     * if it represents a change in position. Changes made through this method will
     * be stable across layout passes. If this method is called before first layout of
     * this SlidingChallengeLayout it will have no effect.
     *
     * @param bottom New bottom edge in px in this SlidingChallengeLayout's coordinate system.
     * @return true if the challenge view was moved
     */
    private boolean moveChallengeTo(int bottom) {
        if (mChallengeView == null || !mHasLayout) {
            return false;
        }

        final int layoutBottom = getLayoutBottom();
        final int challengeHeight = mChallengeView.getHeight();

        bottom = Math.max(getMinChallengeBottom(),
                Math.min(bottom, getMaxChallengeBottom()));

        float offset = 1.f - (float) (bottom - layoutBottom) /
                (challengeHeight - mChallengeBottomBound);
        mChallengeOffset = offset;
        if (offset > 0 && !mChallengeShowing) {
            setChallengeShowing(true);
        }

        mChallengeView.layout(mChallengeView.getLeft(),
                bottom - mChallengeView.getHeight(), mChallengeView.getRight(), bottom);

        mChallengeView.setAlpha(getChallengeAlpha());
        if (mScrollListener != null) {
            mScrollListener.onScrollPositionChanged(offset, mChallengeView.getTop());
        }
        postInvalidateOnAnimation();
        return true;
    }

    /**
     * The bottom edge of this SlidingChallengeLayout's coordinate system; will coincide with
     * the bottom edge of mChallengeView when the challenge is fully opened.
     */
    private int getLayoutBottom() {
        final int bottomMargin = (mChallengeView == null)
                ? 0
                : ((LayoutParams) mChallengeView.getLayoutParams()).bottomMargin;
        final int layoutBottom = getMeasuredHeight() - getPaddingBottom() - bottomMargin;
        return layoutBottom;
    }

    /**
     * The bottom edge of mChallengeView; essentially, where the sliding challenge 'is'.
     */
    private int getChallengeBottom() {
        if (mChallengeView == null) return 0;

        return mChallengeView.getBottom();
    }

    /**
     * Show or hide the challenge view, animating it if necessary.
     * @param show true to show, false to hide
     */
    public void showChallenge(boolean show) {
        showChallenge(show, 0);
        if (!show) {
            // Block any drags in progress so that callers can use this to disable dragging
            // for other touch interactions.
            mBlockDrag = true;
        }
    }

    private void showChallenge(int velocity) {
        boolean show = false;
        if (Math.abs(velocity) > mMinVelocity) {
            show = velocity < 0;
        } else {
            show = mChallengeOffset >= 0.5f;
        }
        showChallenge(show, velocity);
    }

    private void showChallenge(boolean show, int velocity) {
        if (mChallengeView == null) {
            setChallengeShowing(false);
            return;
        }

        if (mHasLayout) {
            mChallengeShowingTargetState = show;
            final int layoutBottom = getLayoutBottom();
            animateChallengeTo(show ? layoutBottom :
                    layoutBottom + mChallengeView.getHeight() - mChallengeBottomBound, velocity);
        }
    }

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

    @Override
    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
        return p instanceof LayoutParams ? new LayoutParams((LayoutParams) p) :
                p instanceof MarginLayoutParams ? new LayoutParams((MarginLayoutParams) p) :
                new LayoutParams(p);
    }

    @Override
    protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
        return new LayoutParams();
    }

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

    public static class LayoutParams extends MarginLayoutParams {
        public int childType = CHILD_TYPE_NONE;
        public static final int CHILD_TYPE_NONE = 0;
        public static final int CHILD_TYPE_CHALLENGE = 2;
        public static final int CHILD_TYPE_SCRIM = 4;
        public static final int CHILD_TYPE_WIDGETS = 5;
        public static final int CHILD_TYPE_EXPAND_CHALLENGE_HANDLE = 6;

        public int maxHeight;

        public LayoutParams() {
            this(MATCH_PARENT, WRAP_CONTENT);
        }

        public LayoutParams(int width, int height) {
            super(width, height);
        }

        public LayoutParams(android.view.ViewGroup.LayoutParams source) {
            super(source);
        }

        public LayoutParams(MarginLayoutParams source) {
            super(source);
        }

        public LayoutParams(LayoutParams source) {
            super(source);

            childType = source.childType;
        }

        public LayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);

            final TypedArray a = c.obtainStyledAttributes(attrs,
                    R.styleable.SlidingChallengeLayout_Layout);
            childType = a.getInt(R.styleable.SlidingChallengeLayout_Layout_layout_childType,
                    CHILD_TYPE_NONE);
            maxHeight = a.getDimensionPixelSize(
                    R.styleable.SlidingChallengeLayout_Layout_layout_maxHeight, 0);
            a.recycle();
        }
    }
}
