/*
 * 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.Rect;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

public class MultiPaneChallengeLayout extends ViewGroup implements ChallengeLayout {
    private static final String TAG = "MultiPaneChallengeLayout";

    final int mOrientation;
    private boolean mIsBouncing;

    public static final int HORIZONTAL = LinearLayout.HORIZONTAL;
    public static final int VERTICAL = LinearLayout.VERTICAL;
    public static final int ANIMATE_BOUNCE_DURATION = 350;

    private KeyguardSecurityContainer mChallengeView;
    private View mUserSwitcherView;
    private View mScrimView;
    private OnBouncerStateChangedListener mBouncerListener;

    private final Rect mTempRect = new Rect();
    private final Rect mZeroPadding = new Rect();
    private final Rect mInsets = new Rect();

    private final DisplayMetrics mDisplayMetrics;

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

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

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

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

        final TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.MultiPaneChallengeLayout, defStyleAttr, 0);
        mOrientation = a.getInt(R.styleable.MultiPaneChallengeLayout_android_orientation,
                HORIZONTAL);
        a.recycle();

        final Resources res = getResources();
        mDisplayMetrics = res.getDisplayMetrics();

        setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_STABLE | SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
    }

    public void setInsets(Rect insets) {
        mInsets.set(insets);
    }

    @Override
    public boolean isChallengeShowing() {
        return true;
    }

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

    @Override
    public void showChallenge(boolean b) {
    }

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

    @Override
    public void showBouncer() {
        if (mIsBouncing) return;
        mIsBouncing = true;
        if (mScrimView != null) {
            if (mChallengeView != null) {
                mChallengeView.showBouncer(ANIMATE_BOUNCE_DURATION);
            }

            Animator anim = ObjectAnimator.ofFloat(mScrimView, "alpha", 1f);
            anim.setDuration(ANIMATE_BOUNCE_DURATION);
            anim.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationStart(Animator animation) {
                    mScrimView.setVisibility(VISIBLE);
                }
            });
            anim.start();
        }
        if (mBouncerListener != null) {
            mBouncerListener.onBouncerStateChanged(true);
        }
    }

    @Override
    public void hideBouncer() {
        if (!mIsBouncing) return;
        mIsBouncing = false;
        if (mScrimView != null) {
            if (mChallengeView != null) {
                mChallengeView.hideBouncer(ANIMATE_BOUNCE_DURATION);
            }

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

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

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

    @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);
    }

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

    private int getVirtualHeight(LayoutParams lp, int height, int heightUsed) {
        int virtualHeight = height;
        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.
            virtualHeight = mDisplayMetrics.heightPixels - root.getPaddingTop() - mInsets.top;
        }
        if (lp.childType == LayoutParams.CHILD_TYPE_USER_SWITCHER) {
            // Always measure the user switcher as if there were no IME insets
            // on the window.
            return virtualHeight - heightUsed;
        } else if (lp.childType == LayoutParams.CHILD_TYPE_PAGE_DELETE_DROP_TARGET) {
            return height;
        }
        return Math.min(virtualHeight - heightUsed, height);
    }

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

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

        final int insetHeight = height - mInsets.top - mInsets.bottom;
        final int insetHeightSpec = MeasureSpec.makeMeasureSpec(insetHeight, MeasureSpec.EXACTLY);

        int widthUsed = 0;
        int heightUsed = 0;

        // First pass. Find the challenge view and measure the user switcher,
        // which consumes space in the layout.
        mChallengeView = null;
        mUserSwitcherView = null;
        final int count = getChildCount();
        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 of type challenge");
                }
                if (!(child instanceof KeyguardSecurityContainer)) {
                    throw new IllegalArgumentException(
                            "Challenge must be a KeyguardSecurityContainer");
                }
                mChallengeView = (KeyguardSecurityContainer) child;
            } else if (lp.childType == LayoutParams.CHILD_TYPE_USER_SWITCHER) {
                if (mUserSwitcherView != null) {
                    throw new IllegalStateException(
                            "There may only be one child of type userSwitcher");
                }
                mUserSwitcherView = child;

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

                int adjustedWidthSpec = widthSpec;
                int adjustedHeightSpec = insetHeightSpec;
                if (lp.maxWidth >= 0) {
                    adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
                            Math.min(lp.maxWidth, width), MeasureSpec.EXACTLY);
                }
                if (lp.maxHeight >= 0) {
                    adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
                            Math.min(lp.maxHeight, insetHeight), MeasureSpec.EXACTLY);
                }
                // measureChildWithMargins will resolve layout direction for the LayoutParams
                measureChildWithMargins(child, adjustedWidthSpec, 0, adjustedHeightSpec, 0);

                // Only subtract out space from one dimension. Favor vertical.
                // Offset by 1.5x to add some balance along the other edge.
                if (Gravity.isVertical(lp.gravity)) {
                    heightUsed += child.getMeasuredHeight() * 1.5f;
                } else if (Gravity.isHorizontal(lp.gravity)) {
                    widthUsed += child.getMeasuredWidth() * 1.5f;
                }
            } else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
                setScrimView(child);
                child.measure(widthSpec, heightSpec);
            }
        }

        // Second pass. Measure everything that's left.
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            final LayoutParams lp = (LayoutParams) child.getLayoutParams();

            if (lp.childType == LayoutParams.CHILD_TYPE_USER_SWITCHER ||
                    lp.childType == LayoutParams.CHILD_TYPE_SCRIM ||
                    child.getVisibility() == GONE) {
                // Don't need to measure GONE children, and the user switcher was already measured.
                continue;
            }

            final int virtualHeight = getVirtualHeight(lp, insetHeight, heightUsed);

            int adjustedWidthSpec;
            int adjustedHeightSpec;
            if (lp.centerWithinArea > 0) {
                if (mOrientation == HORIZONTAL) {
                    adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
                            (int) ((width - widthUsed) * lp.centerWithinArea + 0.5f),
                            MeasureSpec.EXACTLY);
                    adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
                            virtualHeight, MeasureSpec.EXACTLY);
                } else {
                    adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
                            width - widthUsed, MeasureSpec.EXACTLY);
                    adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
                            (int) (virtualHeight * lp.centerWithinArea + 0.5f),
                            MeasureSpec.EXACTLY);
                }
            } else {
                adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
                        width - widthUsed, MeasureSpec.EXACTLY);
                adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
                        virtualHeight, MeasureSpec.EXACTLY);
            }
            if (lp.maxWidth >= 0) {
                adjustedWidthSpec = MeasureSpec.makeMeasureSpec(
                        Math.min(lp.maxWidth, MeasureSpec.getSize(adjustedWidthSpec)),
                        MeasureSpec.EXACTLY);
            }
            if (lp.maxHeight >= 0) {
                adjustedHeightSpec = MeasureSpec.makeMeasureSpec(
                        Math.min(lp.maxHeight, MeasureSpec.getSize(adjustedHeightSpec)),
                        MeasureSpec.EXACTLY);
            }

            measureChildWithMargins(child, adjustedWidthSpec, 0, adjustedHeightSpec, 0);
        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final Rect padding = mTempRect;
        padding.left = getPaddingLeft();
        padding.top = getPaddingTop();
        padding.right = getPaddingRight();
        padding.bottom = getPaddingBottom();
        final int width = r - l;
        final int height = b - t;
        final int insetHeight = height - mInsets.top - mInsets.bottom;

        // Reserve extra space in layout for the user switcher by modifying
        // local padding during this layout pass
        if (mUserSwitcherView != null && mUserSwitcherView.getVisibility() != GONE) {
            layoutWithGravity(width, insetHeight, mUserSwitcherView, padding, true);
        }

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

            // We did the user switcher above if we have one.
            if (child == mUserSwitcherView || child.getVisibility() == GONE) continue;

            if (child == mScrimView) {
                child.layout(0, 0, width, height);
                continue;
            } else if (lp.childType == LayoutParams.CHILD_TYPE_PAGE_DELETE_DROP_TARGET) {
                layoutWithGravity(width, insetHeight, child, mZeroPadding, false);
                continue;
            }

            layoutWithGravity(width, insetHeight, child, padding, false);
        }
    }

    private void layoutWithGravity(int width, int height, View child, Rect padding,
            boolean adjustPadding) {
        final LayoutParams lp = (LayoutParams) child.getLayoutParams();

        final int heightUsed = padding.top + padding.bottom - getPaddingTop() - getPaddingBottom();
        height = getVirtualHeight(lp, height, heightUsed);

        final int gravity = Gravity.getAbsoluteGravity(lp.gravity, getLayoutDirection());

        final boolean fixedLayoutSize = lp.centerWithinArea > 0;
        final boolean fixedLayoutHorizontal = fixedLayoutSize && mOrientation == HORIZONTAL;
        final boolean fixedLayoutVertical = fixedLayoutSize && mOrientation == VERTICAL;

        final int adjustedWidth;
        final int adjustedHeight;
        if (fixedLayoutHorizontal) {
            final int paddedWidth = width - padding.left - padding.right;
            adjustedWidth = (int) (paddedWidth * lp.centerWithinArea + 0.5f);
            adjustedHeight = height;
        } else if (fixedLayoutVertical) {
            final int paddedHeight = height - getPaddingTop() - getPaddingBottom();
            adjustedWidth = width;
            adjustedHeight = (int) (paddedHeight * lp.centerWithinArea + 0.5f);
        } else {
            adjustedWidth = width;
            adjustedHeight = height;
        }

        final boolean isVertical = Gravity.isVertical(gravity);
        final boolean isHorizontal = Gravity.isHorizontal(gravity);
        final int childWidth = child.getMeasuredWidth();
        final int childHeight = child.getMeasuredHeight();

        int left = padding.left;
        int top = padding.top;
        int right = left + childWidth;
        int bottom = top + childHeight;
        switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) {
            case Gravity.TOP:
                top = fixedLayoutVertical ?
                        padding.top + (adjustedHeight - childHeight) / 2 : padding.top;
                bottom = top + childHeight;
                if (adjustPadding && isVertical) {
                    padding.top = bottom;
                    padding.bottom += childHeight / 2;
                }
                break;
            case Gravity.BOTTOM:
                bottom = fixedLayoutVertical
                        ? padding.top + height - (adjustedHeight - childHeight) / 2
                        : padding.top + height;
                top = bottom - childHeight;
                if (adjustPadding && isVertical) {
                    padding.bottom = height - top;
                    padding.top += childHeight / 2;
                }
                break;
            case Gravity.CENTER_VERTICAL:
                top = padding.top + (height - childHeight) / 2;
                bottom = top + childHeight;
                break;
        }
        switch (gravity & Gravity.HORIZONTAL_GRAVITY_MASK) {
            case Gravity.LEFT:
                left = fixedLayoutHorizontal ?
                        padding.left + (adjustedWidth - childWidth) / 2 : padding.left;
                right = left + childWidth;
                if (adjustPadding && isHorizontal && !isVertical) {
                    padding.left = right;
                    padding.right += childWidth / 2;
                }
                break;
            case Gravity.RIGHT:
                right = fixedLayoutHorizontal
                        ? width - padding.right - (adjustedWidth - childWidth) / 2
                        : width - padding.right;
                left = right - childWidth;
                if (adjustPadding && isHorizontal && !isVertical) {
                    padding.right = width - left;
                    padding.left += childWidth / 2;
                }
                break;
            case Gravity.CENTER_HORIZONTAL:
                final int paddedWidth = width - padding.left - padding.right;
                left = (paddedWidth - childWidth) / 2;
                right = left + childWidth;
                break;
        }
        top += mInsets.top;
        bottom += mInsets.top;
        child.layout(left, top, right, bottom);
    }

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

    @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 float centerWithinArea = 0;

        public int childType = 0;

        public static final int CHILD_TYPE_NONE = 0;
        public static final int CHILD_TYPE_WIDGET = 1;
        public static final int CHILD_TYPE_CHALLENGE = 2;
        public static final int CHILD_TYPE_USER_SWITCHER = 3;
        public static final int CHILD_TYPE_SCRIM = 4;
        public static final int CHILD_TYPE_PAGE_DELETE_DROP_TARGET = 7;

        public int gravity = Gravity.NO_GRAVITY;

        public int maxWidth = -1;
        public int maxHeight = -1;

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

        LayoutParams(Context c, AttributeSet attrs, MultiPaneChallengeLayout parent) {
            super(c, attrs);

            final TypedArray a = c.obtainStyledAttributes(attrs,
                    R.styleable.MultiPaneChallengeLayout_Layout);

            centerWithinArea = a.getFloat(
                    R.styleable.MultiPaneChallengeLayout_Layout_layout_centerWithinArea, 0);
            childType = a.getInt(R.styleable.MultiPaneChallengeLayout_Layout_layout_childType,
                    CHILD_TYPE_NONE);
            gravity = a.getInt(R.styleable.MultiPaneChallengeLayout_Layout_layout_gravity,
                    Gravity.NO_GRAVITY);
            maxWidth = a.getDimensionPixelSize(
                    R.styleable.MultiPaneChallengeLayout_Layout_layout_maxWidth, -1);
            maxHeight = a.getDimensionPixelSize(
                    R.styleable.MultiPaneChallengeLayout_Layout_layout_maxHeight, -1);

            // Default gravity settings based on type and parent orientation
            if (gravity == Gravity.NO_GRAVITY) {
                if (parent.mOrientation == HORIZONTAL) {
                    switch (childType) {
                        case CHILD_TYPE_WIDGET:
                            gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
                            break;
                        case CHILD_TYPE_CHALLENGE:
                            gravity = Gravity.RIGHT | Gravity.CENTER_VERTICAL;
                            break;
                        case CHILD_TYPE_USER_SWITCHER:
                            gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
                            break;
                    }
                } else {
                    switch (childType) {
                        case CHILD_TYPE_WIDGET:
                            gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
                            break;
                        case CHILD_TYPE_CHALLENGE:
                            gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
                            break;
                        case CHILD_TYPE_USER_SWITCHER:
                            gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
                            break;
                    }
                }
            }

            a.recycle();
        }

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

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

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

        public LayoutParams(LayoutParams source) {
            this((MarginLayoutParams) source);

            centerWithinArea = source.centerWithinArea;
            childType = source.childType;
            gravity = source.gravity;
            maxWidth = source.maxWidth;
            maxHeight = source.maxHeight;
        }
    }
}
