/*
 * 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.widget;

import java.lang.Math;

import com.android.internal.R;

import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.util.AttributeSet;
import android.util.Log;
import android.util.StateSet;
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewGroup;
import android.widget.RemoteViews.RemoteView;

/**
 * A layout that switches between its children based on the requested layout height.
 * Each child specifies its minimum and maximum valid height.  Results are undefined
 * if children specify overlapping ranges.  A child may specify the maximum height
 * as 'unbounded' to indicate that it is willing to be displayed arbitrarily tall.
 *
 * <p>
 * See {@link SizeAdaptiveLayout.LayoutParams} for a full description of the
 * layout parameters used by SizeAdaptiveLayout.
 */
@RemoteView
public class SizeAdaptiveLayout extends ViewGroup {

    private static final String TAG = "SizeAdaptiveLayout";
    private static final boolean DEBUG = false;
    private static final boolean REPORT_BAD_BOUNDS = true;
    private static final long CROSSFADE_TIME = 250;

    // TypedArray indices
    private static final int MIN_VALID_HEIGHT =
            R.styleable.SizeAdaptiveLayout_Layout_layout_minHeight;
    private static final int MAX_VALID_HEIGHT =
            R.styleable.SizeAdaptiveLayout_Layout_layout_maxHeight;

    // view state
    private View mActiveChild;
    private View mLastActive;

    // animation state
    private AnimatorSet mTransitionAnimation;
    private AnimatorListener mAnimatorListener;
    private ObjectAnimator mFadePanel;
    private ObjectAnimator mFadeView;
    private int mCanceledAnimationCount;
    private View mEnteringView;
    private View mLeavingView;
    // View used to hide larger views under smaller ones to create a uniform crossfade
    private View mModestyPanel;
    private int mModestyPanelTop;

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

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

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

    public SizeAdaptiveLayout(
            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initialize();
    }

    private void initialize() {
        mModestyPanel = new View(getContext());
        // If the SizeAdaptiveLayout has a solid background, use it as a transition hint.
        Drawable background = getBackground();
        if (background instanceof StateListDrawable) {
            StateListDrawable sld = (StateListDrawable) background;
            sld.setState(StateSet.WILD_CARD);
            background = sld.getCurrent();
        }
        if (background instanceof ColorDrawable) {
            mModestyPanel.setBackgroundDrawable(background);
        } else {
            mModestyPanel.setBackgroundColor(Color.BLACK);
        }
        SizeAdaptiveLayout.LayoutParams layout =
                new SizeAdaptiveLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                                                    ViewGroup.LayoutParams.MATCH_PARENT);
        mModestyPanel.setLayoutParams(layout);
        addView(mModestyPanel);
        mFadePanel = ObjectAnimator.ofFloat(mModestyPanel, "alpha", 0f);
        mFadeView = ObjectAnimator.ofFloat(null, "alpha", 0f);
        mAnimatorListener = new BringToFrontOnEnd();
        mTransitionAnimation = new AnimatorSet();
        mTransitionAnimation.play(mFadeView).with(mFadePanel);
        mTransitionAnimation.setDuration(CROSSFADE_TIME);
        mTransitionAnimation.addListener(mAnimatorListener);
    }

    /**
     * Visible for testing
     * @hide
     */
    public Animator getTransitionAnimation() {
        return mTransitionAnimation;
    }

    /**
     * Visible for testing
     * @hide
     */
    public View getModestyPanel() {
        return mModestyPanel;
    }

    @Override
    public void onAttachedToWindow() {
        mLastActive = null;
        // make sure all views start off invisible.
        for (int i = 0; i < getChildCount(); i++) {
            getChildAt(i).setVisibility(View.GONE);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (DEBUG) Log.d(TAG, this + " measure spec: " +
                         MeasureSpec.toString(heightMeasureSpec));
        View model = selectActiveChild(heightMeasureSpec);
        if (model == null) {
            setMeasuredDimension(0, 0);
            return;
        }
        SizeAdaptiveLayout.LayoutParams lp =
          (SizeAdaptiveLayout.LayoutParams) model.getLayoutParams();
        if (DEBUG) Log.d(TAG, "active min: " + lp.minHeight + " max: " + lp.maxHeight);
        measureChild(model, widthMeasureSpec, heightMeasureSpec);
        int childHeight = model.getMeasuredHeight();
        int childWidth = model.getMeasuredHeight();
        int childState = combineMeasuredStates(0, model.getMeasuredState());
        if (DEBUG) Log.d(TAG, "measured child at: " + childHeight);
        int resolvedWidth = resolveSizeAndState(childWidth, widthMeasureSpec, childState);
        int resolvedHeight = resolveSizeAndState(childHeight, heightMeasureSpec, childState);
        if (DEBUG) Log.d(TAG, "resolved to: " + resolvedHeight);
        int boundedHeight = clampSizeToBounds(resolvedHeight, model);
        if (DEBUG) Log.d(TAG, "bounded to: " + boundedHeight);
        setMeasuredDimension(resolvedWidth, boundedHeight);
    }

    private int clampSizeToBounds(int measuredHeight, View child) {
        SizeAdaptiveLayout.LayoutParams lp =
                (SizeAdaptiveLayout.LayoutParams) child.getLayoutParams();
        int heightIn = View.MEASURED_SIZE_MASK & measuredHeight;
        int height = Math.max(heightIn, lp.minHeight);
        if (lp.maxHeight != SizeAdaptiveLayout.LayoutParams.UNBOUNDED) {
            height = Math.min(height, lp.maxHeight);
        }

        if (REPORT_BAD_BOUNDS && heightIn != height) {
            Log.d(TAG, this + "child view " + child + " " +
                  "measured out of bounds at " + heightIn +"px " +
                  "clamped to " + height + "px");
        }

        return height;
    }

    //TODO extend to width and height
    private View selectActiveChild(int heightMeasureSpec) {
        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        final int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        View unboundedView = null;
        View tallestView = null;
        int tallestViewSize = 0;
        View smallestView = null;
        int smallestViewSize = Integer.MAX_VALUE;
        for (int i = 0; i < getChildCount(); i++) {
            View child = getChildAt(i);
            if (child != mModestyPanel) {
                SizeAdaptiveLayout.LayoutParams lp =
                    (SizeAdaptiveLayout.LayoutParams) child.getLayoutParams();
                if (DEBUG) Log.d(TAG, "looking at " + i +
                                 " with min: " + lp.minHeight +
                                 " max: " +  lp.maxHeight);
                if (lp.maxHeight == SizeAdaptiveLayout.LayoutParams.UNBOUNDED &&
                    unboundedView == null) {
                    unboundedView = child;
                }
                if (lp.maxHeight > tallestViewSize) {
                    tallestViewSize = lp.maxHeight;
                    tallestView = child;
                }
                if (lp.minHeight < smallestViewSize) {
                    smallestViewSize = lp.minHeight;
                    smallestView = child;
                }
                if (heightMode != MeasureSpec.UNSPECIFIED &&
                    heightSize >= lp.minHeight && heightSize <= lp.maxHeight) {
                    if (DEBUG) Log.d(TAG, "  found exact match, finishing early");
                    return child;
                }
            }
        }
        if (unboundedView != null) {
            tallestView = unboundedView;
        }
        if (heightMode == MeasureSpec.UNSPECIFIED || heightSize > tallestViewSize) {
            return tallestView;
        } else {
            return smallestView;
        }
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        if (DEBUG) Log.d(TAG, this + " onlayout height: " + (bottom - top));
        mLastActive = mActiveChild;
        int measureSpec = View.MeasureSpec.makeMeasureSpec(bottom - top,
                                                           View.MeasureSpec.EXACTLY);
        mActiveChild = selectActiveChild(measureSpec);
        if (mActiveChild == null) return;

        mActiveChild.setVisibility(View.VISIBLE);

        if (mLastActive != mActiveChild && mLastActive != null) {
            if (DEBUG) Log.d(TAG, this + " changed children from: " + mLastActive +
                    " to: " + mActiveChild);

            mEnteringView = mActiveChild;
            mLeavingView = mLastActive;

            mEnteringView.setAlpha(1f);

            mModestyPanel.setAlpha(1f);
            mModestyPanel.bringToFront();
            mModestyPanelTop = mLeavingView.getHeight();
            mModestyPanel.setVisibility(View.VISIBLE);
            // TODO: mModestyPanel background should be compatible with mLeavingView

            mLeavingView.bringToFront();

            if (mTransitionAnimation.isRunning()) {
                mTransitionAnimation.cancel();
            }
            mFadeView.setTarget(mLeavingView);
            mFadeView.setFloatValues(0f);
            mFadePanel.setFloatValues(0f);
            mTransitionAnimation.setupStartValues();
            mTransitionAnimation.start();
        }
        final int childWidth = mActiveChild.getMeasuredWidth();
        final int childHeight = mActiveChild.getMeasuredHeight();
        // TODO investigate setting LAYER_TYPE_HARDWARE on mLastActive
        mActiveChild.layout(0, 0, childWidth, childHeight);

        if (DEBUG) Log.d(TAG, "got modesty offset of " + mModestyPanelTop);
        mModestyPanel.layout(0, mModestyPanelTop, childWidth, mModestyPanelTop + childHeight);
    }

    @Override
    public LayoutParams generateLayoutParams(AttributeSet attrs) {
        if (DEBUG) Log.d(TAG, "generate layout from attrs");
        return new SizeAdaptiveLayout.LayoutParams(getContext(), attrs);
    }

    @Override
    protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
        if (DEBUG) Log.d(TAG, "generate default layout from viewgroup");
        return new SizeAdaptiveLayout.LayoutParams(p);
    }

    @Override
    protected LayoutParams generateDefaultLayoutParams() {
        if (DEBUG) Log.d(TAG, "generate default layout from null");
        return new SizeAdaptiveLayout.LayoutParams();
    }

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

    /**
     * Per-child layout information associated with ViewSizeAdaptiveLayout.
     *
     * TODO extend to width and height
     *
     * @attr ref android.R.styleable#SizeAdaptiveLayout_Layout_layout_minHeight
     * @attr ref android.R.styleable#SizeAdaptiveLayout_Layout_layout_maxHeight
     */
    public static class LayoutParams extends ViewGroup.LayoutParams {

        /**
         * Indicates the minimum valid height for the child.
         */
        @ViewDebug.ExportedProperty(category = "layout")
        public int minHeight;

        /**
         * Indicates the maximum valid height for the child.
         */
        @ViewDebug.ExportedProperty(category = "layout")
        public int maxHeight;

        /**
         * Constant value for maxHeight that indicates there is not maximum height.
         */
        public static final int UNBOUNDED = -1;

        /**
         * {@inheritDoc}
         */
        public LayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);
            if (DEBUG) {
                Log.d(TAG, "construct layout from attrs");
                for (int i = 0; i < attrs.getAttributeCount(); i++) {
                    Log.d(TAG, " " + attrs.getAttributeName(i) + " = " +
                          attrs.getAttributeValue(i));
                }
            }
            TypedArray a =
                    c.obtainStyledAttributes(attrs,
                            R.styleable.SizeAdaptiveLayout_Layout);

            minHeight = a.getDimensionPixelSize(MIN_VALID_HEIGHT, 0);
            if (DEBUG) Log.d(TAG, "got minHeight of: " + minHeight);

            try {
                maxHeight = a.getLayoutDimension(MAX_VALID_HEIGHT, UNBOUNDED);
                if (DEBUG) Log.d(TAG, "got maxHeight of: " + maxHeight);
            } catch (Exception e) {
                if (DEBUG) Log.d(TAG, "caught exception looking for maxValidHeight " + e);
            }

            a.recycle();
        }

        /**
         * Creates a new set of layout parameters with the specified width, height
         * and valid height bounds.
         *
         * @param width the width, either {@link #MATCH_PARENT},
         *        {@link #WRAP_CONTENT} or a fixed size in pixels
         * @param height the height, either {@link #MATCH_PARENT},
         *        {@link #WRAP_CONTENT} or a fixed size in pixels
         * @param minHeight the minimum height of this child
         * @param maxHeight the maximum height of this child
         *        or {@link #UNBOUNDED} if the child can grow forever
         */
        public LayoutParams(int width, int height, int minHeight, int maxHeight) {
            super(width, height);
            this.minHeight = minHeight;
            this.maxHeight = maxHeight;
        }

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

        /**
         * Constructs a new LayoutParams with default values as defined in {@link LayoutParams}.
         */
        public LayoutParams() {
            this(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
        }

        /**
         * {@inheritDoc}
         */
        public LayoutParams(ViewGroup.LayoutParams p) {
            super(p);
            minHeight = UNBOUNDED;
            maxHeight = UNBOUNDED;
        }

        public String debug(String output) {
            return output + "SizeAdaptiveLayout.LayoutParams={" +
                    ", max=" + maxHeight +
                    ", max=" + minHeight + "}";
        }
    }

    class BringToFrontOnEnd implements AnimatorListener {
        @Override
            public void onAnimationEnd(Animator animation) {
            if (mCanceledAnimationCount == 0) {
                mLeavingView.setVisibility(View.GONE);
                mModestyPanel.setVisibility(View.GONE);
                mEnteringView.bringToFront();
                mEnteringView = null;
                mLeavingView = null;
            } else {
                mCanceledAnimationCount--;
            }
        }

        @Override
            public void onAnimationCancel(Animator animation) {
            mCanceledAnimationCount++;
        }

        @Override
            public void onAnimationRepeat(Animator animation) {
            if (DEBUG) Log.d(TAG, "fade animation repeated: should never happen.");
            assert(false);
        }

        @Override
            public void onAnimationStart(Animator animation) {
        }
    }
}
