/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.systemui.statusbar.stack;

import android.content.Context;
import android.content.res.Configuration;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.android.systemui.R;
import com.android.systemui.ViewInvertHelper;
import com.android.systemui.statusbar.CrossFadeHelper;
import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.HybridNotificationView;
import com.android.systemui.statusbar.notification.HybridNotificationViewManager;
import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.phone.NotificationPanelView;

import java.util.ArrayList;
import java.util.List;

/**
 * A container containing child notifications
 */
public class NotificationChildrenContainer extends ViewGroup {

    private static final int NUMBER_OF_CHILDREN_WHEN_COLLAPSED = 2;
    private static final int NUMBER_OF_CHILDREN_WHEN_SYSTEM_EXPANDED = 5;
    private static final int NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED = 8;

    private final List<View> mDividers = new ArrayList<>();
    private final List<ExpandableNotificationRow> mChildren = new ArrayList<>();
    private final HybridNotificationViewManager mHybridViewManager;
    private int mChildPadding;
    private int mDividerHeight;
    private int mMaxNotificationHeight;
    private int mNotificationHeaderHeight;
    private int mNotificationAppearDistance;
    private int mNotificatonTopPadding;
    private float mCollapsedBottompadding;
    private ViewInvertHelper mOverflowInvertHelper;
    private boolean mChildrenExpanded;
    private ExpandableNotificationRow mNotificationParent;
    private HybridNotificationView mGroupOverflowContainer;
    private ViewState mGroupOverFlowState;
    private int mRealHeight;
    private int mLayoutDirection = LAYOUT_DIRECTION_UNDEFINED;
    private boolean mUserLocked;
    private int mActualHeight;

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

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

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

    public NotificationChildrenContainer(Context context, AttributeSet attrs, int defStyleAttr,
            int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initDimens();
        mHybridViewManager = new HybridNotificationViewManager(getContext(), this);
    }

    private void initDimens() {
        mChildPadding = getResources().getDimensionPixelSize(
                R.dimen.notification_children_padding);
        mDividerHeight = Math.max(1, getResources().getDimensionPixelSize(
                R.dimen.notification_divider_height));
        mMaxNotificationHeight = getResources().getDimensionPixelSize(
                R.dimen.notification_max_height);
        mNotificationAppearDistance = getResources().getDimensionPixelSize(
                R.dimen.notification_appear_distance);
        mNotificationHeaderHeight = getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.notification_content_margin_top);
        mNotificatonTopPadding = getResources().getDimensionPixelSize(
                R.dimen.notification_children_container_top_padding);
        mCollapsedBottompadding = 11.5f * getResources().getDisplayMetrics().density;
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int childCount = Math.min(mChildren.size(), NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED);
        for (int i = 0; i < childCount; i++) {
            View child = mChildren.get(i);
            if (child.getVisibility() == View.GONE) {
                continue;
            }
            child.layout(0, 0, getWidth(), child.getMeasuredHeight());
            mDividers.get(i).layout(0, 0, getWidth(), mDividerHeight);
        }
        if (mGroupOverflowContainer != null) {
            mGroupOverflowContainer.layout(0, 0, getWidth(),
                    mGroupOverflowContainer.getMeasuredHeight());
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int ownMaxHeight = mMaxNotificationHeight;
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        boolean hasFixedHeight = heightMode == MeasureSpec.EXACTLY;
        boolean isHeightLimited = heightMode == MeasureSpec.AT_MOST;
        int size = MeasureSpec.getSize(heightMeasureSpec);
        if (hasFixedHeight || isHeightLimited) {
            ownMaxHeight = Math.min(ownMaxHeight, size);
        }
        int newHeightSpec = MeasureSpec.makeMeasureSpec(ownMaxHeight, MeasureSpec.AT_MOST);
        int dividerHeightSpec = MeasureSpec.makeMeasureSpec(mDividerHeight, MeasureSpec.EXACTLY);
        int height = mNotificationHeaderHeight + mNotificatonTopPadding;
        int childCount = Math.min(mChildren.size(), NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED);
        for (int i = 0; i < childCount; i++) {
            View child = mChildren.get(i);
            child.measure(widthMeasureSpec, newHeightSpec);
            height += child.getMeasuredHeight();

            // layout the divider
            View divider = mDividers.get(i);
            divider.measure(widthMeasureSpec, dividerHeightSpec);
            height += mDividerHeight;
        }
        int width = MeasureSpec.getSize(widthMeasureSpec);
        if (mGroupOverflowContainer != null) {
            mGroupOverflowContainer.measure(widthMeasureSpec, newHeightSpec);
        }
        mRealHeight = height;
        if (heightMode != MeasureSpec.UNSPECIFIED) {
            height = Math.min(height, size);
        }
        setMeasuredDimension(width, height);
    }

    @Override
    public boolean pointInView(float localX, float localY, float slop) {
        return localX >= -slop && localY >= -slop && localX < ((mRight - mLeft) + slop) &&
                localY < (mRealHeight + slop);
    }

    /**
     * Add a child notification to this view.
     *
     * @param row the row to add
     * @param childIndex the index to add it at, if -1 it will be added at the end
     */
    public void addNotification(ExpandableNotificationRow row, int childIndex) {
        int newIndex = childIndex < 0 ? mChildren.size() : childIndex;
        mChildren.add(newIndex, row);
        addView(row);

        View divider = inflateDivider();
        addView(divider);
        mDividers.add(newIndex, divider);

        updateGroupOverflow();
    }

    public void removeNotification(ExpandableNotificationRow row) {
        int childIndex = mChildren.indexOf(row);
        mChildren.remove(row);
        removeView(row);

        final View divider = mDividers.remove(childIndex);
        removeView(divider);
        getOverlay().add(divider);
        CrossFadeHelper.fadeOut(divider, new Runnable() {
            @Override
            public void run() {
                getOverlay().remove(divider);
            }
        });

        row.setSystemChildExpanded(false);
        updateGroupOverflow();
    }

    public void updateGroupOverflow() {
        int childCount = mChildren.size();
        int maxAllowedVisibleChildren = getMaxAllowedVisibleChildren(true /* likeCollapsed */);
        boolean hasOverflow = childCount > maxAllowedVisibleChildren;
        int lastVisibleIndex = hasOverflow ? maxAllowedVisibleChildren - 2
                : maxAllowedVisibleChildren - 1;
        if (hasOverflow) {
            mGroupOverflowContainer = mHybridViewManager.bindFromNotificationGroup(
                    mGroupOverflowContainer, mChildren, lastVisibleIndex + 1);
            if (mOverflowInvertHelper == null) {
                mOverflowInvertHelper= new ViewInvertHelper(mGroupOverflowContainer,
                        NotificationPanelView.DOZE_ANIMATION_DURATION);
            }
            if (mGroupOverFlowState == null) {
                mGroupOverFlowState = new ViewState();
            }
        } else if (mGroupOverflowContainer != null) {
            removeView(mGroupOverflowContainer);
            mGroupOverflowContainer = null;
            mOverflowInvertHelper = null;
            mGroupOverFlowState = null;
        }
    }

    @Override
    protected void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        int layoutDirection = getLayoutDirection();
        if (layoutDirection != mLayoutDirection) {
            updateGroupOverflow();
            mLayoutDirection = layoutDirection;
        }
    }

    private View inflateDivider() {
        return LayoutInflater.from(mContext).inflate(
                R.layout.notification_children_divider, this, false);
    }

    public List<ExpandableNotificationRow> getNotificationChildren() {
        return mChildren;
    }

    /**
     * Apply the order given in the list to the children.
     *
     * @param childOrder the new list order
     * @return whether the list order has changed
     */
    public boolean applyChildOrder(List<ExpandableNotificationRow> childOrder) {
        if (childOrder == null) {
            return false;
        }
        boolean result = false;
        for (int i = 0; i < mChildren.size() && i < childOrder.size(); i++) {
            ExpandableNotificationRow child = mChildren.get(i);
            ExpandableNotificationRow desiredChild = childOrder.get(i);
            if (child != desiredChild) {
                mChildren.remove(desiredChild);
                mChildren.add(i, desiredChild);
                result = true;
            }
        }
        updateExpansionStates();
        return result;
    }

    private void updateExpansionStates() {
        // Let's make the first child expanded if the parent is
        for (int i = 0; i < mChildren.size(); i++) {
            ExpandableNotificationRow child = mChildren.get(i);
            child.setSystemChildExpanded(false);
        }
    }

    /**
     *
     * @return the intrinsic size of this children container, i.e the natural fully expanded state
     */
    public int getIntrinsicHeight() {
        int maxAllowedVisibleChildren = getMaxAllowedVisibleChildren();
        return getIntrinsicHeight(maxAllowedVisibleChildren);
    }

    /**
     * @return the intrinsic height with a number of children given
     *         in @param maxAllowedVisibleChildren
     */
    private int getIntrinsicHeight(float maxAllowedVisibleChildren) {
        int intrinsicHeight = mNotificationHeaderHeight;
        int visibleChildren = 0;
        int childCount = mChildren.size();
        boolean firstChild = true;
        float expandFactor = 0;
        if (mUserLocked) {
            expandFactor = getChildExpandFraction();
        }
        for (int i = 0; i < childCount; i++) {
            if (visibleChildren >= maxAllowedVisibleChildren) {
                break;
            }
            if (!firstChild) {
                if (mUserLocked) {
                    intrinsicHeight += NotificationUtils.interpolate(mChildPadding, mDividerHeight,
                            expandFactor);
                } else {
                    intrinsicHeight += mChildrenExpanded ? mDividerHeight : mChildPadding;
                }
            } else {
                if (mUserLocked) {
                    intrinsicHeight += NotificationUtils.interpolate(
                            0,
                            mNotificatonTopPadding + mDividerHeight,
                            expandFactor);
                } else {
                    intrinsicHeight += mChildrenExpanded
                            ? mNotificatonTopPadding + mDividerHeight
                            : 0;
                }
                firstChild = false;
            }
            ExpandableNotificationRow child = mChildren.get(i);
            intrinsicHeight += child.getIntrinsicHeight();
            visibleChildren++;
        }
        if (mUserLocked) {
            intrinsicHeight += NotificationUtils.interpolate(mCollapsedBottompadding, 0.0f,
                    expandFactor);
        } else if (!mChildrenExpanded) {
            intrinsicHeight += mCollapsedBottompadding;
        }
        return intrinsicHeight;
    }

    /**
     * Update the state of all its children based on a linear layout algorithm.
     *
     * @param resultState the state to update
     * @param parentState the state of the parent
     */
    public void getState(StackScrollState resultState, StackViewState parentState) {
        int childCount = mChildren.size();
        int yPosition = mNotificationHeaderHeight;
        boolean firstChild = true;
        int maxAllowedVisibleChildren = getMaxAllowedVisibleChildren();
        boolean hasOverflow = !mChildrenExpanded && childCount > maxAllowedVisibleChildren
                && maxAllowedVisibleChildren != NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED;
        int lastVisibleIndex = hasOverflow
                ? maxAllowedVisibleChildren - 2
                : maxAllowedVisibleChildren - 1;
        float expandFactor = 0;
        if (mUserLocked) {
            expandFactor = getChildExpandFraction();
        }
        for (int i = 0; i < childCount; i++) {
            ExpandableNotificationRow child = mChildren.get(i);
            if (!firstChild) {
                if (mUserLocked) {
                     yPosition += NotificationUtils.interpolate(mChildPadding, mDividerHeight,
                             expandFactor);
                } else {
                    yPosition += mChildrenExpanded ? mDividerHeight : mChildPadding;
                }
            } else {
                if (mUserLocked) {
                    yPosition += NotificationUtils.interpolate(
                            0,
                            mNotificatonTopPadding + mDividerHeight,
                            expandFactor);
                } else {
                    yPosition += mChildrenExpanded ? mNotificatonTopPadding + mDividerHeight : 0;
                }
                firstChild = false;
            }
            StackViewState childState = resultState.getViewStateForView(child);
            int intrinsicHeight = child.getIntrinsicHeight();
            childState.yTranslation = yPosition;
            childState.zTranslation = 0;
            childState.height = intrinsicHeight;
            childState.dimmed = parentState.dimmed;
            childState.dark = parentState.dark;
            childState.hideSensitive = parentState.hideSensitive;
            childState.belowSpeedBump = parentState.belowSpeedBump;
            childState.clipTopAmount = 0;
            childState.topOverLap = 0;
            boolean visible = i <= lastVisibleIndex;
            childState.alpha = visible ? 1 : 0;
            childState.location = parentState.location;
            yPosition += intrinsicHeight;
        }
        if (mGroupOverflowContainer != null) {
            mGroupOverFlowState.initFrom(mGroupOverflowContainer);
            if (hasOverflow) {
                StackViewState firstOverflowState =
                        resultState.getViewStateForView(mChildren.get(lastVisibleIndex + 1));
                mGroupOverFlowState.yTranslation = firstOverflowState.yTranslation;
            }
            mGroupOverFlowState.alpha = mChildrenExpanded || !hasOverflow ? 0.0f : 1.0f;
        }
    }

    private int getMaxAllowedVisibleChildren() {
        return getMaxAllowedVisibleChildren(false /* likeCollapsed */);
    }

    private int getMaxAllowedVisibleChildren(boolean likeCollapsed) {
        if (!likeCollapsed && (mChildrenExpanded || mNotificationParent.isUserLocked())) {
            return NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED;
        }
        if (mNotificationParent.isExpanded() || mNotificationParent.isHeadsUp()) {
            return NUMBER_OF_CHILDREN_WHEN_SYSTEM_EXPANDED;
        }
        return NUMBER_OF_CHILDREN_WHEN_COLLAPSED;
    }

    public void applyState(StackScrollState state) {
        int childCount = mChildren.size();
        ViewState tmpState = new ViewState();
        float expandFraction = getChildExpandFraction();
        for (int i = 0; i < childCount; i++) {
            ExpandableNotificationRow child = mChildren.get(i);
            StackViewState viewState = state.getViewStateForView(child);
            state.applyState(child, viewState);

            // layout the divider
            View divider = mDividers.get(i);
            tmpState.initFrom(divider);
            tmpState.yTranslation = viewState.yTranslation - mDividerHeight;
            float alpha = mChildrenExpanded && viewState.alpha != 0 ? 0.5f : 0;
            if (mUserLocked && viewState.alpha != 0) {
                alpha = NotificationUtils.interpolate(0, 0.5f, expandFraction);
            }
            tmpState.alpha = alpha;
            state.applyViewState(divider, tmpState);
        }
        if (mGroupOverflowContainer != null) {
            state.applyViewState(mGroupOverflowContainer, mGroupOverFlowState);
        }
    }

    /**
     * This is called when the children expansion has changed and positions the children properly
     * for an appear animation.
     *
     * @param state the new state we animate to
     */
    public void prepareExpansionChanged(StackScrollState state) {
        // TODO: do something that makes sense, like placing the invisible views correctly
        return;
    }

    public void startAnimationToState(StackScrollState state, StackStateAnimator stateAnimator,
            long baseDelay, long duration) {
        int childCount = mChildren.size();
        ViewState tmpState = new ViewState();
        float expandFraction = getChildExpandFraction();
        for (int i = childCount - 1; i >= 0; i--) {
            ExpandableNotificationRow child = mChildren.get(i);
            StackViewState viewState = state.getViewStateForView(child);
            stateAnimator.startStackAnimations(child, viewState, state, -1, baseDelay);

            // layout the divider
            View divider = mDividers.get(i);
            tmpState.initFrom(divider);
            tmpState.yTranslation = viewState.yTranslation - mDividerHeight;
            float alpha = mChildrenExpanded && viewState.alpha != 0 ? 0.5f : 0;
            if (mUserLocked && viewState.alpha != 0) {
                alpha = NotificationUtils.interpolate(0, 0.5f, expandFraction);
            }
            tmpState.alpha = alpha;
            stateAnimator.startViewAnimations(divider, tmpState, baseDelay, duration);
        }
        if (mGroupOverflowContainer != null) {
            stateAnimator.startViewAnimations(mGroupOverflowContainer, mGroupOverFlowState,
                    baseDelay, duration);
        }
    }

    public ExpandableNotificationRow getViewAtPosition(float y) {
        // find the view under the pointer, accounting for GONE views
        final int count = mChildren.size();
        for (int childIdx = 0; childIdx < count; childIdx++) {
            ExpandableNotificationRow slidingChild = mChildren.get(childIdx);
            float childTop = slidingChild.getTranslationY();
            float top = childTop + slidingChild.getClipTopAmount();
            float bottom = childTop + slidingChild.getActualHeight();
            if (y >= top && y <= bottom) {
                return slidingChild;
            }
        }
        return null;
    }

    public void setChildrenExpanded(boolean childrenExpanded) {
        mChildrenExpanded = childrenExpanded;
    }

    public void setNotificationParent(ExpandableNotificationRow parent) {
        mNotificationParent = parent;
    }

    public int getMaxContentHeight() {
        int maxContentHeight = mNotificationHeaderHeight + mNotificatonTopPadding;
        int visibleChildren = 0;
        int childCount = mChildren.size();
        for (int i = 0; i < childCount; i++) {
            if (visibleChildren >= NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED) {
                break;
            }
            ExpandableNotificationRow child = mChildren.get(i);
            float childHeight = child.isExpanded()
                    ? child.getMaxExpandHeight()
                    : child.getShowingLayout().getMinHeight(true /* likeGroupExpanded */);
            maxContentHeight += childHeight;
            visibleChildren++;
        }
        if (visibleChildren > 0) {
            maxContentHeight += visibleChildren * mDividerHeight;
        }
        return maxContentHeight;
    }

    public void setActualHeight(int actualHeight) {
        if (!mUserLocked) {
            return;
        }
        mActualHeight = actualHeight;
        float fraction = getChildExpandFraction();
        int childCount = mChildren.size();
        for (int i = 0; i < childCount; i++) {
            ExpandableNotificationRow child = mChildren.get(i);
            float childHeight = child.isExpanded()
                    ? child.getMaxExpandHeight()
                    : child.getShowingLayout().getMinHeight(true /* likeGroupExpanded */);
            float singleLineHeight = child.getShowingLayout().getMinHeight(
                    false /* likeGroupExpanded */);
            child.setActualHeight((int) NotificationUtils.interpolate(singleLineHeight, childHeight,
                    fraction), false);
        }
    }

    public float getChildExpandFraction() {
        int allChildrenVisibleHeight = getChildrenExpandStartHeight();
        int maxContentHeight = getMaxContentHeight();
        float factor = (mActualHeight - allChildrenVisibleHeight)
                / (float) (maxContentHeight - allChildrenVisibleHeight);
        return Math.max(0.0f, Math.min(1.0f, factor));
    }

    private int getChildrenExpandStartHeight() {
        int intrinsicHeight = mNotificationHeaderHeight;
        int visibleChildren = 0;
        int childCount = mChildren.size();
        for (int i = 0; i < childCount; i++) {
            if (visibleChildren >= NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED) {
                break;
            }
            ExpandableNotificationRow child = mChildren.get(i);
            intrinsicHeight += child.getMinHeight();
            visibleChildren++;
        }
        if (visibleChildren > 0) {
            intrinsicHeight += (visibleChildren - 1) * mChildPadding;
        }
        intrinsicHeight += mCollapsedBottompadding;
        return intrinsicHeight;
    }

    public int getMinHeight() {
        return getIntrinsicHeight(NUMBER_OF_CHILDREN_WHEN_COLLAPSED);
    }

    public int getMinExpandHeight() {
        return getIntrinsicHeight(getMaxAllowedVisibleChildren(true /* forceCollapsed */));
    }

    public void setDark(boolean dark, boolean fade, long delay) {
        if (mGroupOverflowContainer != null) {
            mOverflowInvertHelper.setInverted(dark, fade, delay);
        }
    }

    public void reInflateViews() {
        initDimens();
        for (int i = 0; i < mDividers.size(); i++) {
            View prevDivider = mDividers.get(i);
            int index = indexOfChild(prevDivider);
            removeView(prevDivider);
            View divider = inflateDivider();
            addView(divider, index);
            mDividers.set(i, divider);
        }
    }

    public void setUserLocked(boolean userLocked) {
        mUserLocked = userLocked;
        int childCount = mChildren.size();
        for (int i = 0; i < childCount; i++) {
            ExpandableNotificationRow child = mChildren.get(i);
            child.setUserLocked(userLocked);
        }
    }
}
