/*
 * 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.internal.policy.impl.keyguard;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.TimeInterpolator;
import android.appwidget.AppWidgetHostView;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
import android.os.Handler;
import android.os.HandlerThread;
import android.text.format.DateFormat;
import android.util.AttributeSet;
import android.util.Slog;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.TextClock;

import com.android.internal.widget.LockPatternUtils;

import java.util.ArrayList;
import java.util.TimeZone;

public class KeyguardWidgetPager extends PagedView implements PagedView.PageSwitchListener,
        OnLongClickListener, ChallengeLayout.OnBouncerStateChangedListener {

    ZInterpolator mZInterpolator = new ZInterpolator(0.5f);
    private static float CAMERA_DISTANCE = 10000;
    protected static float OVERSCROLL_MAX_ROTATION = 30;
    private static final boolean PERFORM_OVERSCROLL_ROTATION = true;

    private static final int FLAG_HAS_LOCAL_HOUR = 0x1;
    private static final int FLAG_HAS_LOCAL_MINUTE = 0x2;

    protected KeyguardViewStateManager mViewStateManager;
    private LockPatternUtils mLockPatternUtils;

    // Related to the fading in / out background outlines
    public static final int CHILDREN_OUTLINE_FADE_OUT_DURATION = 375;
    public static final int CHILDREN_OUTLINE_FADE_IN_DURATION = 100;
    protected AnimatorSet mChildrenOutlineFadeAnimation;
    protected int mScreenCenter;
    private boolean mHasMeasure = false;
    boolean showHintsAfterLayout = false;

    private static final long CUSTOM_WIDGET_USER_ACTIVITY_TIMEOUT = 30000;
    private static final String TAG = "KeyguardWidgetPager";
    private boolean mCenterSmallWidgetsVertically;

    private int mPage = 0;
    private Callbacks mCallbacks;

    private int mWidgetToResetAfterFadeOut;
    protected boolean mShowingInitialHints = false;

    // A temporary handle to the Add-Widget view
    private View mAddWidgetView;
    private int mLastWidthMeasureSpec;
    private int mLastHeightMeasureSpec;

    // Bouncer
    private int mBouncerZoomInOutDuration = 250;
    private float BOUNCER_SCALE_FACTOR = 0.67f;

    // Background worker thread: used here for persistence, also made available to widget frames
    private final HandlerThread mBackgroundWorkerThread;
    private final Handler mBackgroundWorkerHandler;

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

    public KeyguardWidgetPager(Context context) {
        this(null, null, 0);
    }

    public KeyguardWidgetPager(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        if (getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
            setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
        }

        setPageSwitchListener(this);

        mBackgroundWorkerThread = new HandlerThread("KeyguardWidgetPager Worker");
        mBackgroundWorkerThread.start();
        mBackgroundWorkerHandler = new Handler(mBackgroundWorkerThread.getLooper());
    }

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

        // Clean up the worker thread
        mBackgroundWorkerThread.quit();
    }

    public void setViewStateManager(KeyguardViewStateManager viewStateManager) {
        mViewStateManager = viewStateManager;
    }

    public void setLockPatternUtils(LockPatternUtils l) {
        mLockPatternUtils = l;
    }

    @Override
    public void onPageSwitching(View newPage, int newPageIndex) {
        if (mViewStateManager != null) {
            mViewStateManager.onPageSwitching(newPage, newPageIndex);
        }
    }

    @Override
    public void onPageSwitched(View newPage, int newPageIndex) {
        boolean showingClock = false;
        if (newPage instanceof ViewGroup) {
            ViewGroup vg = (ViewGroup) newPage;
            if (vg.getChildAt(0) instanceof KeyguardStatusView) {
                showingClock = true;
            }
        }

        if (newPage != null &&
                findClockInHierarchy(newPage) == (FLAG_HAS_LOCAL_HOUR | FLAG_HAS_LOCAL_MINUTE)) {
            showingClock = true;
        }

        // Disable the status bar clock if we're showing the default status widget
        if (showingClock) {
            setSystemUiVisibility(getSystemUiVisibility() | View.STATUS_BAR_DISABLE_CLOCK);
        } else {
            setSystemUiVisibility(getSystemUiVisibility() & ~View.STATUS_BAR_DISABLE_CLOCK);
        }

        // Extend the display timeout if the user switches pages
        if (mPage != newPageIndex) {
            int oldPageIndex = mPage;
            mPage = newPageIndex;
            userActivity();
            KeyguardWidgetFrame oldWidgetPage = getWidgetPageAt(oldPageIndex);
            if (oldWidgetPage != null) {
                oldWidgetPage.onActive(false);
            }
            KeyguardWidgetFrame newWidgetPage = getWidgetPageAt(newPageIndex);
            if (newWidgetPage != null) {
                newWidgetPage.onActive(true);
                newWidgetPage.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
                newWidgetPage.requestAccessibilityFocus();
            }
            if (mParent != null && AccessibilityManager.getInstance(mContext).isEnabled()) {
                AccessibilityEvent event = AccessibilityEvent.obtain(
                        AccessibilityEvent.TYPE_VIEW_SCROLLED);
                onInitializeAccessibilityEvent(event);
                onPopulateAccessibilityEvent(event);
                mParent.requestSendAccessibilityEvent(this, event);
            }
        }
        if (mViewStateManager != null) {
            mViewStateManager.onPageSwitched(newPage, newPageIndex);
        }
    }

    @Override
    public void sendAccessibilityEvent(int eventType) {
        if (eventType != AccessibilityEvent.TYPE_VIEW_SCROLLED || isPageMoving()) {
            super.sendAccessibilityEvent(eventType);
        }
    }

    private void updateWidgetFramesImportantForAccessibility() {
        final int pageCount = getPageCount();
        for (int i = 0; i < pageCount; i++) {
            KeyguardWidgetFrame frame = getWidgetPageAt(i);
            updateWidgetFrameImportantForAccessibility(frame);
        }
    }

    private void updateWidgetFrameImportantForAccessibility(KeyguardWidgetFrame frame) {
        if (frame.getContentAlpha() <= 0) {
            frame.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
        } else {
            frame.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
        }
    }

    private void userActivity() {
        if (mCallbacks != null) {
            mCallbacks.onUserActivityTimeoutChanged();
            mCallbacks.userActivity();
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        return captureUserInteraction(ev) || super.onTouchEvent(ev);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return captureUserInteraction(ev) || super.onInterceptTouchEvent(ev);
    }

    private boolean captureUserInteraction(MotionEvent ev) {
        KeyguardWidgetFrame currentWidgetPage = getWidgetPageAt(getCurrentPage());
        return currentWidgetPage != null && currentWidgetPage.onUserInteraction(ev);
    }

    public void showPagingFeedback() {
        // Nothing yet.
    }

    public long getUserActivityTimeout() {
        View page = getPageAt(mPage);
        if (page instanceof ViewGroup) {
            ViewGroup vg = (ViewGroup) page;
            View view = vg.getChildAt(0);
            if (!(view instanceof KeyguardStatusView)
                    && !(view instanceof KeyguardMultiUserSelectorView)) {
                return CUSTOM_WIDGET_USER_ACTIVITY_TIMEOUT;
            }
        }
        return -1;
    }

    public void setCallbacks(Callbacks callbacks) {
        mCallbacks = callbacks;
    }

    public interface Callbacks {
        public void userActivity();
        public void onUserActivityTimeoutChanged();
        public void onAddView(View v);
        public void onRemoveView(View v, boolean deletePermanently);
        public void onRemoveViewAnimationCompleted();
    }

    public void addWidget(View widget) {
        addWidget(widget, -1);
    }

    public void onRemoveView(View v, final boolean deletePermanently) {
        final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId();
        if (mCallbacks != null) {
            mCallbacks.onRemoveView(v, deletePermanently);
        }
        mBackgroundWorkerHandler.post(new Runnable() {
            @Override
            public void run() {
                mLockPatternUtils.removeAppWidget(appWidgetId);
            }
        });
    }

    @Override
    public void onRemoveViewAnimationCompleted() {
        if (mCallbacks != null) {
            mCallbacks.onRemoveViewAnimationCompleted();
        }
    }

    public void onAddView(View v, final int index) {
        final int appWidgetId = ((KeyguardWidgetFrame) v).getContentAppWidgetId();
        final int[] pagesRange = new int[mTempVisiblePagesRange.length];
        getVisiblePages(pagesRange);
        boundByReorderablePages(true, pagesRange);
        if (mCallbacks != null) {
            mCallbacks.onAddView(v);
        }
        // Subtract from the index to take into account pages before the reorderable
        // pages (e.g. the "add widget" page)
        mBackgroundWorkerHandler.post(new Runnable() {
            @Override
            public void run() {
                mLockPatternUtils.addAppWidget(appWidgetId, index - pagesRange[0]);
            }
        });
    }

    /*
     * We wrap widgets in a special frame which handles drawing the over scroll foreground.
     */
    public void addWidget(View widget, int pageIndex) {
        KeyguardWidgetFrame frame;
        // All views contained herein should be wrapped in a KeyguardWidgetFrame
        if (!(widget instanceof KeyguardWidgetFrame)) {
            frame = new KeyguardWidgetFrame(getContext());
            FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
                    LayoutParams.MATCH_PARENT);
            lp.gravity = Gravity.TOP;

            // The framework adds a default padding to AppWidgetHostView. We don't need this padding
            // for the Keyguard, so we override it to be 0.
            widget.setPadding(0,  0, 0, 0);
            frame.addView(widget, lp);

            // We set whether or not this widget supports vertical resizing.
            if (widget instanceof AppWidgetHostView) {
                AppWidgetHostView awhv = (AppWidgetHostView) widget;
                AppWidgetProviderInfo info = awhv.getAppWidgetInfo();
                if ((info.resizeMode & AppWidgetProviderInfo.RESIZE_VERTICAL) != 0) {
                    frame.setWidgetLockedSmall(false);
                } else {
                    // Lock the widget to be small.
                    frame.setWidgetLockedSmall(true);
                    if (mCenterSmallWidgetsVertically) {
                        lp.gravity = Gravity.CENTER;
                    }
                }
            }
        } else {
            frame = (KeyguardWidgetFrame) widget;
        }

        ViewGroup.LayoutParams pageLp = new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        frame.setOnLongClickListener(this);
        frame.setWorkerHandler(mBackgroundWorkerHandler);

        if (pageIndex == -1) {
            addView(frame, pageLp);
        } else {
            addView(frame, pageIndex, pageLp);
        }

        // Update the frame content description.
        View content = (widget == frame) ?  frame.getContent() : widget;
        if (content != null) {
            String contentDescription = mContext.getString(
                com.android.internal.R.string.keyguard_accessibility_widget,
                content.getContentDescription());
            frame.setContentDescription(contentDescription);
        }
        updateWidgetFrameImportantForAccessibility(frame);
    }

    /**
     * Use addWidget() instead.
     * @deprecated
     */
    @Override
    public void addView(View child, int index) {
        enforceKeyguardWidgetFrame(child);
        super.addView(child, index);
    }

    /**
     * Use addWidget() instead.
     * @deprecated
     */
    @Override
    public void addView(View child, int width, int height) {
        enforceKeyguardWidgetFrame(child);
        super.addView(child, width, height);
    }

    /**
     * Use addWidget() instead.
     * @deprecated
     */
    @Override
    public void addView(View child, LayoutParams params) {
        enforceKeyguardWidgetFrame(child);
        super.addView(child, params);
    }

    /**
     * Use addWidget() instead.
     * @deprecated
     */
    @Override
    public void addView(View child, int index, LayoutParams params) {
        enforceKeyguardWidgetFrame(child);
        super.addView(child, index, params);
    }

    private void enforceKeyguardWidgetFrame(View child) {
        if (!(child instanceof KeyguardWidgetFrame)) {
            throw new IllegalArgumentException(
                    "KeyguardWidgetPager children must be KeyguardWidgetFrames");
        }
    }

    public KeyguardWidgetFrame getWidgetPageAt(int index) {
        // This is always a valid cast as we've guarded the ability to
        return (KeyguardWidgetFrame) getChildAt(index);
    }

    protected void onUnhandledTap(MotionEvent ev) {
        showPagingFeedback();
    }

    @Override
    protected void onPageBeginMoving() {
        if (mViewStateManager != null) {
            mViewStateManager.onPageBeginMoving();
        }
        if (!isReordering(false)) {
            showOutlinesAndSidePages();
        }
        userActivity();
    }

    @Override
    protected void onPageEndMoving() {
        if (mViewStateManager != null) {
            mViewStateManager.onPageEndMoving();
        }

        // In the reordering case, the pages will be faded appropriately on completion
        // of the zoom in animation.
        if (!isReordering(false)) {
            hideOutlinesAndSidePages();
        }
    }

    protected void enablePageContentLayers() {
        int children = getChildCount();
        for (int i = 0; i < children; i++) {
            getWidgetPageAt(i).enableHardwareLayersForContent();
        }
    }

    protected void disablePageContentLayers() {
        int children = getChildCount();
        for (int i = 0; i < children; i++) {
            getWidgetPageAt(i).disableHardwareLayersForContent();
        }
    }

    /*
     * This interpolator emulates the rate at which the perceived scale of an object changes
     * as its distance from a camera increases. When this interpolator is applied to a scale
     * animation on a view, it evokes the sense that the object is shrinking due to moving away
     * from the camera.
     */
    static class ZInterpolator implements TimeInterpolator {
        private float focalLength;

        public ZInterpolator(float foc) {
            focalLength = foc;
        }

        public float getInterpolation(float input) {
            return (1.0f - focalLength / (focalLength + input)) /
                (1.0f - focalLength / (focalLength + 1.0f));
        }
    }

    @Override
    protected void overScroll(float amount) {
        acceleratedOverScroll(amount);
    }

    float backgroundAlphaInterpolator(float r) {
        return Math.min(1f, r);
    }

    private void updatePageAlphaValues(int screenCenter) {
    }

    public float getAlphaForPage(int screenCenter, int index, boolean showSidePages) {
        if (showSidePages) {
            return 1f;
        } else {
            return index == mCurrentPage ? 1.0f : 0f;
        }
    }

    public float getOutlineAlphaForPage(int screenCenter, int index, boolean showSidePages) {
        if (showSidePages) {
            return getAlphaForPage(screenCenter, index, showSidePages)
                    * KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER;
        } else {
            return 0f;
        }
    }

    protected boolean isOverScrollChild(int index, float scrollProgress) {
        boolean isInOverscroll = mOverScrollX < 0 || mOverScrollX > mMaxScrollX;
        return (isInOverscroll && (index == 0 && scrollProgress < 0 ||
                index == getChildCount() - 1 && scrollProgress > 0));
    }

    @Override
    protected void screenScrolled(int screenCenter) {
        mScreenCenter = screenCenter;
        updatePageAlphaValues(screenCenter);
        for (int i = 0; i < getChildCount(); i++) {
            KeyguardWidgetFrame v = getWidgetPageAt(i);
            if (v == mDragView) continue;
            if (v != null) {
                float scrollProgress = getScrollProgress(screenCenter, v, i);

                v.setCameraDistance(mDensity * CAMERA_DISTANCE);

                if (isOverScrollChild(i, scrollProgress) && PERFORM_OVERSCROLL_ROTATION) {
                    float pivotX = v.getMeasuredWidth() / 2;
                    float pivotY = v.getMeasuredHeight() / 2;
                    v.setPivotX(pivotX);
                    v.setPivotY(pivotY);
                    v.setRotationY(- OVERSCROLL_MAX_ROTATION * scrollProgress);
                    v.setOverScrollAmount(Math.abs(scrollProgress), scrollProgress < 0);
                } else {
                    v.setRotationY(0f);
                    v.setOverScrollAmount(0, false);
                }

                float alpha = v.getAlpha();
                // If the view has 0 alpha, we set it to be invisible so as to prevent
                // it from accepting touches
                if (alpha == 0) {
                    v.setVisibility(INVISIBLE);
                } else if (v.getVisibility() != VISIBLE) {
                    v.setVisibility(VISIBLE);
                }
            }
        }
    }

    public boolean isWidgetPage(int pageIndex) {
        if (pageIndex < 0 || pageIndex >= getChildCount()) {
            return false;
        }
        View v = getChildAt(pageIndex);
        if (v != null && v instanceof KeyguardWidgetFrame) {
            KeyguardWidgetFrame kwf = (KeyguardWidgetFrame) v;
            return kwf.getContentAppWidgetId() != AppWidgetManager.INVALID_APPWIDGET_ID;
        }
        return false;
    }

    /**
     * Returns the bounded set of pages that are re-orderable.  The range is fully inclusive.
     */
    @Override
    void boundByReorderablePages(boolean isReordering, int[] range) {
        if (isReordering) {
            // Remove non-widget pages from the range
            while (range[1] >= range[0] && !isWidgetPage(range[1])) {
                range[1]--;
            }
            while (range[0] <= range[1] && !isWidgetPage(range[0])) {
                range[0]++;
            }
        }
    }

    protected void reorderStarting() {
        showOutlinesAndSidePages();
    }

    @Override
    protected void onStartReordering() {
        super.onStartReordering();
        enablePageContentLayers();
        reorderStarting();
    }

    @Override
    protected void onEndReordering() {
        super.onEndReordering();
        hideOutlinesAndSidePages();
    }

    void showOutlinesAndSidePages() {
        animateOutlinesAndSidePages(true);
    }

    void hideOutlinesAndSidePages() {
        animateOutlinesAndSidePages(false);
    }

    void updateChildrenContentAlpha(float sidePageAlpha) {
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            KeyguardWidgetFrame child = getWidgetPageAt(i);
            if (i != mCurrentPage) {
                child.setBackgroundAlpha(sidePageAlpha);
                child.setContentAlpha(0f);
            } else {
                child.setBackgroundAlpha(0f);
                child.setContentAlpha(1f);
            }
        }
    }

    public void showInitialPageHints() {
        mShowingInitialHints = true;
        updateChildrenContentAlpha(KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER);
    }

    @Override
    void setCurrentPage(int currentPage) {
        super.setCurrentPage(currentPage);
        updateChildrenContentAlpha(0.0f);
        updateWidgetFramesImportantForAccessibility();
    }

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
        mHasMeasure = false;
    }

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        mLastWidthMeasureSpec = widthMeasureSpec;
        mLastHeightMeasureSpec = heightMeasureSpec;

        int maxChallengeTop = -1;
        View parent = (View) getParent();
        boolean challengeShowing = false;
        // Widget pages need to know where the top of the sliding challenge is so that they
        // now how big the widget should be when the challenge is up. We compute it here and
        // then propagate it to each of our children.
        if (parent.getParent() instanceof SlidingChallengeLayout) {
            SlidingChallengeLayout scl = (SlidingChallengeLayout) parent.getParent();
            int top = scl.getMaxChallengeTop();

            // This is a bit evil, but we need to map a coordinate relative to the SCL into a
            // coordinate relative to our children, hence we subtract the top padding.s
            maxChallengeTop = top - getPaddingTop();
            challengeShowing = scl.isChallengeShowing();

            int count = getChildCount();
            for (int i = 0; i < count; i++) {
                KeyguardWidgetFrame frame = getWidgetPageAt(i);
                frame.setMaxChallengeTop(maxChallengeTop);
                // On the very first measure pass, if the challenge is showing, we need to make sure
                // that the widget on the current page is small.
                if (challengeShowing && i == mCurrentPage && !mHasMeasure) {
                    frame.shrinkWidget();
                }
            }
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mHasMeasure = true;
    }

    void animateOutlinesAndSidePages(final boolean show) {
        animateOutlinesAndSidePages(show, -1);
    }

    public void setWidgetToResetOnPageFadeOut(int widget) {
        mWidgetToResetAfterFadeOut = widget;
    }

    public int getWidgetToResetOnPageFadeOut() {
        return mWidgetToResetAfterFadeOut;
    }

    void animateOutlinesAndSidePages(final boolean show, int duration) {
        if (mChildrenOutlineFadeAnimation != null) {
            mChildrenOutlineFadeAnimation.cancel();
            mChildrenOutlineFadeAnimation = null;
        }
        int count = getChildCount();
        PropertyValuesHolder alpha;
        ArrayList<Animator> anims = new ArrayList<Animator>();

        if (duration == -1) {
            duration = show ? CHILDREN_OUTLINE_FADE_IN_DURATION :
                CHILDREN_OUTLINE_FADE_OUT_DURATION;
        }

        int curPage = getNextPage();
        for (int i = 0; i < count; i++) {
            float finalContentAlpha;
            if (show) {
                finalContentAlpha = getAlphaForPage(mScreenCenter, i, true);
            } else if (!show && i == curPage) {
                finalContentAlpha = 1f;
            } else {
                finalContentAlpha = 0f;
            }
            KeyguardWidgetFrame child = getWidgetPageAt(i);

            alpha = PropertyValuesHolder.ofFloat("contentAlpha", finalContentAlpha);
            ObjectAnimator a = ObjectAnimator.ofPropertyValuesHolder(child, alpha);
            anims.add(a);

            float finalOutlineAlpha = show ? getOutlineAlphaForPage(mScreenCenter, i, true) : 0f;
            child.fadeFrame(this, show, finalOutlineAlpha, duration);
        }

        mChildrenOutlineFadeAnimation = new AnimatorSet();
        mChildrenOutlineFadeAnimation.playTogether(anims);

        mChildrenOutlineFadeAnimation.setDuration(duration);
        mChildrenOutlineFadeAnimation.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(Animator animation) {
                if (show) {
                    enablePageContentLayers();
                }
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                if (!show) {
                    disablePageContentLayers();
                    KeyguardWidgetFrame frame = getWidgetPageAt(mWidgetToResetAfterFadeOut);
                    if (frame != null && !(frame == getWidgetPageAt(mCurrentPage) &&
                            mViewStateManager.isChallengeOverlapping())) {
                        frame.resetSize();
                    }
                    mWidgetToResetAfterFadeOut = -1;
                    mShowingInitialHints = false;
                }
                updateWidgetFramesImportantForAccessibility();
            }
        });
        mChildrenOutlineFadeAnimation.start();
    }

    @Override
    public boolean onLongClick(View v) {
        // Disallow long pressing to reorder if the challenge is showing
        boolean isChallengeOverlapping = mViewStateManager.isChallengeShowing() &&
                mViewStateManager.isChallengeOverlapping();
        if (!isChallengeOverlapping && startReordering()) {
            return true;
        }
        return false;
    }

    public void removeWidget(View view) {
        if (view instanceof KeyguardWidgetFrame) {
            removeView(view);
        } else {
            // Assume view was wrapped by a KeyguardWidgetFrame in KeyguardWidgetPager#addWidget().
            // This supports legacy hard-coded "widgets" like KeyguardTransportControlView.
            int pos = getWidgetPageIndex(view);
            if (pos != -1) {
                KeyguardWidgetFrame frame = (KeyguardWidgetFrame) getChildAt(pos);
                frame.removeView(view);
                removeView(frame);
            } else {
                Slog.w(TAG, "removeWidget() can't find:" + view);
            }
        }
    }

    public int getWidgetPageIndex(View view) {
        if (view instanceof KeyguardWidgetFrame) {
            return indexOfChild(view);
        } else {
            // View was wrapped by a KeyguardWidgetFrame by KeyguardWidgetPager#addWidget()
            return indexOfChild((KeyguardWidgetFrame)view.getParent());
        }
    }

    @Override
    protected void setPageHoveringOverDeleteDropTarget(int viewIndex, boolean isHovering) {
        KeyguardWidgetFrame child = getWidgetPageAt(viewIndex);
        child.setIsHoveringOverDeleteDropTarget(isHovering);
    }

    // ChallengeLayout.OnBouncerStateChangedListener
    @Override
    public void onBouncerStateChanged(boolean bouncerActive) {
        if (bouncerActive) {
            zoomOutToBouncer();
        } else {
            zoomInFromBouncer();
        }
    }

    void setBouncerAnimationDuration(int duration) {
        mBouncerZoomInOutDuration = duration;
    }

    // Zoom in after the bouncer is dismissed
    void zoomInFromBouncer() {
        if (mZoomInOutAnim != null && mZoomInOutAnim.isRunning()) {
            mZoomInOutAnim.cancel();
        }
        final View currentPage = getPageAt(getCurrentPage());
        if (currentPage.getScaleX() < 1f || currentPage.getScaleY() < 1f) {
            mZoomInOutAnim = new AnimatorSet();
            mZoomInOutAnim.playTogether(
                    ObjectAnimator.ofFloat(currentPage, "scaleX", 1f),
                    ObjectAnimator.ofFloat(currentPage , "scaleY", 1f));
            mZoomInOutAnim.setDuration(mBouncerZoomInOutDuration);
            mZoomInOutAnim.setInterpolator(new DecelerateInterpolator(1.5f));
            mZoomInOutAnim.start();
        }
        if (currentPage instanceof KeyguardWidgetFrame) {
            ((KeyguardWidgetFrame)currentPage).onBouncerShowing(false);
        }
    }

    // Zoom out after the bouncer is initiated
    void zoomOutToBouncer() {
        if (mZoomInOutAnim != null && mZoomInOutAnim.isRunning()) {
            mZoomInOutAnim.cancel();
        }
        int curPage = getCurrentPage();
        View currentPage = getPageAt(curPage);
        if (shouldSetTopAlignedPivotForWidget(curPage)) {
            currentPage.setPivotY(0);
            // Note: we are working around the issue that setting the x-pivot to the same value as it
            //       was does not actually work.
            currentPage.setPivotX(0);
            currentPage.setPivotX(currentPage.getMeasuredWidth() / 2);
        }
        if (!(currentPage.getScaleX() < 1f || currentPage.getScaleY() < 1f)) {
            mZoomInOutAnim = new AnimatorSet();
            mZoomInOutAnim.playTogether(
                    ObjectAnimator.ofFloat(currentPage, "scaleX", BOUNCER_SCALE_FACTOR),
                    ObjectAnimator.ofFloat(currentPage, "scaleY", BOUNCER_SCALE_FACTOR));
            mZoomInOutAnim.setDuration(mBouncerZoomInOutDuration);
            mZoomInOutAnim.setInterpolator(new DecelerateInterpolator(1.5f));
            mZoomInOutAnim.start();
        }
        if (currentPage instanceof KeyguardWidgetFrame) {
            ((KeyguardWidgetFrame)currentPage).onBouncerShowing(true);
        }
    }

    void setAddWidgetEnabled(boolean enabled) {
        if (mAddWidgetView != null && enabled) {
            addView(mAddWidgetView, 0);
            // We need to force measure the PagedView so that the calls to update the scroll
            // position below work
            measure(mLastWidthMeasureSpec, mLastHeightMeasureSpec);
            // Bump up the current page to account for the addition of the new page
            setCurrentPage(mCurrentPage + 1);
            mAddWidgetView = null;
        } else if (mAddWidgetView == null && !enabled) {
            View addWidget = findViewById(com.android.internal.R.id.keyguard_add_widget);
            if (addWidget != null) {
                mAddWidgetView = addWidget;
                removeView(addWidget);
            }
        }
    }

    boolean isAddPage(int pageIndex) {
        View v = getChildAt(pageIndex);
        return v != null && v.getId() == com.android.internal.R.id.keyguard_add_widget;
    }

    boolean isCameraPage(int pageIndex) {
        View v = getChildAt(pageIndex);
        return v != null && v instanceof CameraWidgetFrame;
    }

    @Override
    protected boolean shouldSetTopAlignedPivotForWidget(int childIndex) {
        return !isCameraPage(childIndex) && super.shouldSetTopAlignedPivotForWidget(childIndex);
    }

    /**
     * Search given {@link View} hierarchy for {@link TextClock} instances that
     * show various time components. Returns combination of
     * {@link #FLAG_HAS_LOCAL_HOUR} and {@link #FLAG_HAS_LOCAL_MINUTE}.
     */
    private static int findClockInHierarchy(View view) {
        if (view instanceof TextClock) {
            return getClockFlags((TextClock) view);
        } else if (view instanceof ViewGroup) {
            int flags = 0;
            final ViewGroup group = (ViewGroup) view;
            final int size = group.getChildCount();
            for (int i = 0; i < size; i++) {
                flags |= findClockInHierarchy(group.getChildAt(i));
            }
            return flags;
        } else {
            return 0;
        }
    }

    /**
     * Return combination of {@link #FLAG_HAS_LOCAL_HOUR} and
     * {@link #FLAG_HAS_LOCAL_MINUTE} describing the time represented described
     * by the given {@link TextClock}.
     */
    private static int getClockFlags(TextClock clock) {
        int flags = 0;

        final String timeZone = clock.getTimeZone();
        if (timeZone != null && !TimeZone.getDefault().equals(TimeZone.getTimeZone(timeZone))) {
            // Ignore clocks showing another timezone
            return 0;
        }

        final CharSequence format = clock.getFormat();
        final char hour = clock.is24HourModeEnabled() ? DateFormat.HOUR_OF_DAY
                : DateFormat.HOUR;

        if (DateFormat.hasDesignator(format, hour)) {
            flags |= FLAG_HAS_LOCAL_HOUR;
        }
        if (DateFormat.hasDesignator(format, DateFormat.MINUTE)) {
            flags |= FLAG_HAS_LOCAL_MINUTE;
        }

        return flags;
    }
}
