/*
 * Copyright (C) 2014 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.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import com.android.systemui.R;
import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.ExpandableView;

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

/**
 * The Algorithm of the {@link com.android.systemui.statusbar.stack
 * .NotificationStackScrollLayout} which can be queried for {@link com.android.systemui.statusbar
 * .stack.StackScrollState}
 */
public class StackScrollAlgorithm {

    private static final String LOG_TAG = "StackScrollAlgorithm";

    private static final int MAX_ITEMS_IN_BOTTOM_STACK = 3;
    private static final int MAX_ITEMS_IN_TOP_STACK = 3;

    public static final float DIMMED_SCALE = 0.98f;

    private int mPaddingBetweenElements;
    private int mCollapsedSize;
    private int mTopStackPeekSize;
    private int mBottomStackPeekSize;
    private int mZDistanceBetweenElements;
    private int mZBasicHeight;
    private int mRoundedRectCornerRadius;

    private StackIndentationFunctor mTopStackIndentationFunctor;
    private StackIndentationFunctor mBottomStackIndentationFunctor;

    private StackScrollAlgorithmState mTempAlgorithmState = new StackScrollAlgorithmState();
    private boolean mIsExpansionChanging;
    private int mFirstChildMaxHeight;
    private boolean mIsExpanded;
    private ExpandableView mFirstChildWhileExpanding;
    private boolean mExpandedOnStart;
    private int mTopStackTotalSize;
    private int mPaddingBetweenElementsDimmed;
    private int mPaddingBetweenElementsNormal;
    private int mNotificationsTopPadding;
    private int mBottomStackSlowDownLength;
    private int mTopStackSlowDownLength;
    private int mCollapseSecondCardPadding;
    private boolean mScaleDimmed;
    private ExpandableView mFirstChild;
    private int mFirstChildMinHeight;
    private boolean mDimmed;

    public StackScrollAlgorithm(Context context) {
        initView(context);
    }

    public void initView(Context context) {
        initConstants(context);
        updatePadding();
    }

    private void updatePadding() {
        mPaddingBetweenElements = mDimmed && mScaleDimmed
                ? mPaddingBetweenElementsDimmed
                : mPaddingBetweenElementsNormal;
        mTopStackTotalSize = mTopStackSlowDownLength + mPaddingBetweenElements
                + mTopStackPeekSize;
        mTopStackIndentationFunctor = new PiecewiseLinearIndentationFunctor(
                MAX_ITEMS_IN_TOP_STACK,
                mTopStackPeekSize,
                mTopStackTotalSize - mTopStackPeekSize,
                0.5f);
        mBottomStackIndentationFunctor = new PiecewiseLinearIndentationFunctor(
                MAX_ITEMS_IN_BOTTOM_STACK,
                mBottomStackPeekSize,
                getBottomStackSlowDownLength(),
                0.5f);
    }

    public int getBottomStackSlowDownLength() {
        return mBottomStackSlowDownLength + mPaddingBetweenElements;
    }

    private void initConstants(Context context) {
        mPaddingBetweenElementsDimmed = context.getResources()
                .getDimensionPixelSize(R.dimen.notification_padding_dimmed);
        mPaddingBetweenElementsNormal = context.getResources()
                .getDimensionPixelSize(R.dimen.notification_padding);
        mNotificationsTopPadding = context.getResources()
                .getDimensionPixelSize(R.dimen.notifications_top_padding);
        mCollapsedSize = context.getResources()
                .getDimensionPixelSize(R.dimen.notification_min_height);
        mTopStackPeekSize = context.getResources()
                .getDimensionPixelSize(R.dimen.top_stack_peek_amount);
        mBottomStackPeekSize = context.getResources()
                .getDimensionPixelSize(R.dimen.bottom_stack_peek_amount);
        mZDistanceBetweenElements = context.getResources()
                .getDimensionPixelSize(R.dimen.z_distance_between_notifications);
        mZBasicHeight = (MAX_ITEMS_IN_BOTTOM_STACK + 1) * mZDistanceBetweenElements;
        mBottomStackSlowDownLength = context.getResources()
                .getDimensionPixelSize(R.dimen.bottom_stack_slow_down_length);
        mTopStackSlowDownLength = context.getResources()
                .getDimensionPixelSize(R.dimen.top_stack_slow_down_length);
        mRoundedRectCornerRadius = context.getResources().getDimensionPixelSize(
                R.dimen.notification_material_rounded_rect_radius);
        mCollapseSecondCardPadding = context.getResources().getDimensionPixelSize(
                R.dimen.notification_collapse_second_card_padding);
        mScaleDimmed = context.getResources().getDisplayMetrics().densityDpi
                >= DisplayMetrics.DENSITY_420;
    }

    public boolean shouldScaleDimmed() {
        return mScaleDimmed;
    }

    public void getStackScrollState(AmbientState ambientState, StackScrollState resultState) {
        // The state of the local variables are saved in an algorithmState to easily subdivide it
        // into multiple phases.
        StackScrollAlgorithmState algorithmState = mTempAlgorithmState;

        // First we reset the view states to their default values.
        resultState.resetViewStates();

        algorithmState.itemsInTopStack = 0.0f;
        algorithmState.partialInTop = 0.0f;
        algorithmState.lastTopStackIndex = 0;
        algorithmState.scrolledPixelsTop = 0;
        algorithmState.itemsInBottomStack = 0.0f;
        algorithmState.partialInBottom = 0.0f;
        mFirstChildMinHeight = mFirstChild == null ? 0 : mFirstChild.getMinHeight();
        float bottomOverScroll = ambientState.getOverScrollAmount(false /* onTop */);

        int scrollY = ambientState.getScrollY();

        // Due to the overScroller, the stackscroller can have negative scroll state. This is
        // already accounted for by the top padding and doesn't need an additional adaption
        scrollY = Math.max(0, scrollY);
        algorithmState.scrollY = (int) (scrollY + mFirstChildMinHeight + bottomOverScroll);

        updateVisibleChildren(resultState, algorithmState);

        // Phase 1:
        findNumberOfItemsInTopStackAndUpdateState(resultState, algorithmState, ambientState);

        // Phase 2:
        updatePositionsForState(resultState, algorithmState, ambientState);

        // Phase 3:
        updateZValuesForState(resultState, algorithmState);

        handleDraggedViews(ambientState, resultState, algorithmState);
        updateDimmedActivatedHideSensitive(ambientState, resultState, algorithmState);
        updateClipping(resultState, algorithmState, ambientState);
        updateSpeedBumpState(resultState, algorithmState, ambientState.getSpeedBumpIndex());
        getNotificationChildrenStates(resultState, algorithmState);
    }

    private void getNotificationChildrenStates(StackScrollState resultState,
            StackScrollAlgorithmState algorithmState) {
        int childCount = algorithmState.visibleChildren.size();
        for (int i = 0; i < childCount; i++) {
            ExpandableView v = algorithmState.visibleChildren.get(i);
            if (v instanceof ExpandableNotificationRow) {
                ExpandableNotificationRow row = (ExpandableNotificationRow) v;
                row.getChildrenStates(resultState);
            }
        }
    }

    private void updateSpeedBumpState(StackScrollState resultState,
            StackScrollAlgorithmState algorithmState, int speedBumpIndex) {
        int childCount = algorithmState.visibleChildren.size();
        for (int i = 0; i < childCount; i++) {
            View child = algorithmState.visibleChildren.get(i);
            StackViewState childViewState = resultState.getViewStateForView(child);

            // The speed bump can also be gone, so equality needs to be taken when comparing
            // indices.
            childViewState.belowSpeedBump = speedBumpIndex != -1 && i >= speedBumpIndex;
        }
    }

    private void updateClipping(StackScrollState resultState,
            StackScrollAlgorithmState algorithmState, AmbientState ambientState) {
        boolean dismissAllInProgress = ambientState.isDismissAllInProgress();
        float previousNotificationEnd = 0;
        float previousNotificationStart = 0;
        boolean previousNotificationIsSwiped = false;
        int childCount = algorithmState.visibleChildren.size();
        for (int i = 0; i < childCount; i++) {
            ExpandableView child = algorithmState.visibleChildren.get(i);
            StackViewState state = resultState.getViewStateForView(child);
            float newYTranslation = state.yTranslation + state.height * (1f - state.scale) / 2f;
            float newHeight = state.height * state.scale;
            // apply clipping and shadow
            float newNotificationEnd = newYTranslation + newHeight;

            float clipHeight;
            if (previousNotificationIsSwiped) {
                // When the previous notification is swiped, we don't clip the content to the
                // bottom of it.
                clipHeight = newHeight;
            } else {
                clipHeight = newNotificationEnd - previousNotificationEnd;
                clipHeight = Math.max(0.0f, clipHeight);
                if (clipHeight != 0.0f) {

                    // In the unlocked shade we have to clip a little bit higher because of the rounded
                    // corners of the notifications, but only if we are not fully overlapped by
                    // the top card.
                    float clippingCorrection = state.dimmed
                            ? 0
                            : mRoundedRectCornerRadius * state.scale;
                    clipHeight += clippingCorrection;
                }
            }

            updateChildClippingAndBackground(state, newHeight, clipHeight,
                    newHeight - (previousNotificationStart - newYTranslation));

            if (dismissAllInProgress) {
                state.clipTopAmount = Math.max(child.getMinClipTopAmount(), state.clipTopAmount);
            }

            if (!child.isTransparent()) {
                // Only update the previous values if we are not transparent,
                // otherwise we would clip to a transparent view.
                if ((dismissAllInProgress && canChildBeDismissed(child))) {
                    previousNotificationIsSwiped = true;
                } else {
                    previousNotificationIsSwiped = ambientState.getDraggedViews().contains(child);
                    previousNotificationEnd = newNotificationEnd;
                    previousNotificationStart = newYTranslation + state.clipTopAmount * state.scale;
                }
            }
        }
    }

    public static boolean canChildBeDismissed(View v) {
        final View veto = v.findViewById(R.id.veto);
        return (veto != null && veto.getVisibility() != View.GONE);
    }

    /**
     * Updates the shadow outline and the clipping for a view.
     *
     * @param state the viewState to update
     * @param realHeight the currently applied height of the view
     * @param clipHeight the desired clip height, the rest of the view will be clipped from the top
     * @param backgroundHeight the desired background height. The shadows of the view will be
     *                         based on this height and the content will be clipped from the top
     */
    private void updateChildClippingAndBackground(StackViewState state, float realHeight,
            float clipHeight, float backgroundHeight) {
        if (realHeight > clipHeight) {
            // Rather overlap than create a hole.
            state.topOverLap = (int) Math.floor((realHeight - clipHeight) / state.scale);
        } else {
            state.topOverLap = 0;
        }
        if (realHeight > backgroundHeight) {
            // Rather overlap than create a hole.
            state.clipTopAmount = (int) Math.floor((realHeight - backgroundHeight) / state.scale);
        } else {
            state.clipTopAmount = 0;
        }
    }

    /**
     * Updates the dimmed, activated and hiding sensitive states of the children.
     */
    private void updateDimmedActivatedHideSensitive(AmbientState ambientState,
            StackScrollState resultState, StackScrollAlgorithmState algorithmState) {
        boolean dimmed = ambientState.isDimmed();
        boolean dark = ambientState.isDark();
        boolean hideSensitive = ambientState.isHideSensitive();
        View activatedChild = ambientState.getActivatedChild();
        int childCount = algorithmState.visibleChildren.size();
        for (int i = 0; i < childCount; i++) {
            View child = algorithmState.visibleChildren.get(i);
            StackViewState childViewState = resultState.getViewStateForView(child);
            childViewState.dimmed = dimmed;
            childViewState.dark = dark;
            childViewState.hideSensitive = hideSensitive;
            boolean isActivatedChild = activatedChild == child;
            childViewState.scale = !mScaleDimmed || !dimmed || isActivatedChild
                    ? 1.0f
                    : DIMMED_SCALE;
            if (dimmed && isActivatedChild) {
                childViewState.zTranslation += 2.0f * mZDistanceBetweenElements;
            }
        }
    }

    /**
     * Handle the special state when views are being dragged
     */
    private void handleDraggedViews(AmbientState ambientState, StackScrollState resultState,
            StackScrollAlgorithmState algorithmState) {
        ArrayList<View> draggedViews = ambientState.getDraggedViews();
        for (View draggedView : draggedViews) {
            int childIndex = algorithmState.visibleChildren.indexOf(draggedView);
            if (childIndex >= 0 && childIndex < algorithmState.visibleChildren.size() - 1) {
                View nextChild = algorithmState.visibleChildren.get(childIndex + 1);
                if (!draggedViews.contains(nextChild)) {
                    // only if the view is not dragged itself we modify its state to be fully
                    // visible
                    StackViewState viewState = resultState.getViewStateForView(
                            nextChild);
                    // The child below the dragged one must be fully visible
                    if (ambientState.isShadeExpanded()) {
                        viewState.alpha = 1;
                    }
                }

                // Lets set the alpha to the one it currently has, as its currently being dragged
                StackViewState viewState = resultState.getViewStateForView(draggedView);
                // The dragged child should keep the set alpha
                viewState.alpha = draggedView.getAlpha();
            }
        }
    }

    /**
     * Update the visible children on the state.
     */
    private void updateVisibleChildren(StackScrollState resultState,
            StackScrollAlgorithmState state) {
        ViewGroup hostView = resultState.getHostView();
        int childCount = hostView.getChildCount();
        state.visibleChildren.clear();
        state.visibleChildren.ensureCapacity(childCount);
        int notGoneIndex = 0;
        for (int i = 0; i < childCount; i++) {
            ExpandableView v = (ExpandableView) hostView.getChildAt(i);
            if (v.getVisibility() != View.GONE) {
                notGoneIndex = updateNotGoneIndex(resultState, state, notGoneIndex, v);
                if (v instanceof ExpandableNotificationRow) {
                    ExpandableNotificationRow row = (ExpandableNotificationRow) v;

                    // handle the notgoneIndex for the children as well
                    List<ExpandableNotificationRow> children =
                            row.getNotificationChildren();
                    if (row.isSummaryWithChildren() && children != null) {
                        for (ExpandableNotificationRow childRow : children) {
                            if (childRow.getVisibility() != View.GONE) {
                                StackViewState childState
                                        = resultState.getViewStateForView(childRow);
                                childState.notGoneIndex = notGoneIndex;
                                notGoneIndex++;
                            }
                        }
                    }
                }
            }
        }
    }

    private int updateNotGoneIndex(StackScrollState resultState,
            StackScrollAlgorithmState state, int notGoneIndex,
            ExpandableView v) {
        StackViewState viewState = resultState.getViewStateForView(v);
        viewState.notGoneIndex = notGoneIndex;
        state.visibleChildren.add(v);
        notGoneIndex++;
        return notGoneIndex;
    }

    /**
     * Determine the positions for the views. This is the main part of the algorithm.
     *
     * @param resultState The result state to update if a change to the properties of a child occurs
     * @param algorithmState The state in which the current pass of the algorithm is currently in
     * @param ambientState The current ambient state
     */
    private void updatePositionsForState(StackScrollState resultState,
            StackScrollAlgorithmState algorithmState, AmbientState ambientState) {

        // The starting position of the bottom stack peek
        float bottomPeekStart = ambientState.getInnerHeight() - mBottomStackPeekSize;

        // The position where the bottom stack starts.
        float bottomStackStart = bottomPeekStart - mBottomStackSlowDownLength;

        // The y coordinate of the current child.
        float currentYPosition = 0.0f;

        // How far in is the element currently transitioning into the bottom stack.
        float yPositionInScrollView = 0.0f;

        int childCount = algorithmState.visibleChildren.size();
        int numberOfElementsCompletelyIn = algorithmState.partialInTop == 1.0f
                ? algorithmState.lastTopStackIndex
                : (int) algorithmState.itemsInTopStack;
        for (int i = 0; i < childCount; i++) {
            ExpandableView child = algorithmState.visibleChildren.get(i);
            StackViewState childViewState = resultState.getViewStateForView(child);
            childViewState.location = StackViewState.LOCATION_UNKNOWN;
            int childHeight = getMaxAllowedChildHeight(child);
            int minHeight = child.getMinHeight();
            float yPositionInScrollViewAfterElement = yPositionInScrollView
                    + childHeight
                    + mPaddingBetweenElements;
            float scrollOffset = yPositionInScrollView - algorithmState.scrollY +
                    mFirstChildMinHeight;

            if (i == algorithmState.lastTopStackIndex + 1) {
                // Normally the position of this child is the position in the regular scrollview,
                // but if the two stacks are very close to each other,
                // then have have to push it even more upwards to the position of the bottom
                // stack start.
                currentYPosition = Math.min(scrollOffset, bottomStackStart);
            }
            childViewState.yTranslation = currentYPosition;

            // The y position after this element
            float nextYPosition = currentYPosition + childHeight +
                    mPaddingBetweenElements;

            if (i <= algorithmState.lastTopStackIndex) {
                // Case 1:
                // We are in the top Stack
                updateStateForTopStackChild(algorithmState,
                        numberOfElementsCompletelyIn, i, childHeight, childViewState, scrollOffset);
                clampPositionToTopStackEnd(childViewState, childHeight);

                // check if we are overlapping with the bottom stack
                if (childViewState.yTranslation + childHeight + mPaddingBetweenElements
                        >= bottomStackStart && !mIsExpansionChanging && i != 0) {
                    // we just collapse this element slightly
                    int newSize = (int) Math.max(bottomStackStart - mPaddingBetweenElements -
                            childViewState.yTranslation, minHeight);
                    childViewState.height = newSize;
                    updateStateForChildTransitioningInBottom(algorithmState, bottomStackStart,
                            child, childViewState.yTranslation, childViewState,
                            childHeight);
                }
                clampPositionToBottomStackStart(childViewState, childViewState.height,
                        minHeight, ambientState);
            } else if (nextYPosition >= bottomStackStart) {
                // Case 2:
                // We are in the bottom stack.
                if (currentYPosition >= bottomStackStart) {
                    // According to the regular scroll view we are fully translated out of the
                    // bottom of the screen so we are fully in the bottom stack
                    updateStateForChildFullyInBottomStack(algorithmState,
                            bottomStackStart, childViewState, minHeight, ambientState);
                } else {
                    // According to the regular scroll view we are currently translating out of /
                    // into the bottom of the screen
                    updateStateForChildTransitioningInBottom(algorithmState,
                            bottomStackStart, child, currentYPosition,
                            childViewState, childHeight);
                }
            } else {
                // Case 3:
                // We are in the regular scroll area.
                childViewState.location = StackViewState.LOCATION_MAIN_AREA;
                clampYTranslation(childViewState, childHeight, ambientState);
            }

            // The first card is always rendered.
            if (i == 0) {
                childViewState.alpha = 1.0f;
                childViewState.yTranslation = Math.max(
                        mFirstChildMinHeight - algorithmState.scrollY, 0);
                if (childViewState.yTranslation + childViewState.height
                        > bottomPeekStart - mCollapseSecondCardPadding) {
                    childViewState.height = (int) Math.max(
                            bottomPeekStart - mCollapseSecondCardPadding
                                    - childViewState.yTranslation, mFirstChildMinHeight);
                }
                childViewState.location = StackViewState.LOCATION_FIRST_CARD;
            }
            if (childViewState.location == StackViewState.LOCATION_UNKNOWN) {
                Log.wtf(LOG_TAG, "Failed to assign location for child " + i);
            }
            currentYPosition = childViewState.yTranslation + childHeight + mPaddingBetweenElements;
            yPositionInScrollView = yPositionInScrollViewAfterElement;

            childViewState.yTranslation += ambientState.getTopPadding()
                    + ambientState.getStackTranslation();
        }
        updateHeadsUpStates(resultState, algorithmState, ambientState);
    }

    private void updateHeadsUpStates(StackScrollState resultState,
            StackScrollAlgorithmState algorithmState, AmbientState ambientState) {
        int childCount = algorithmState.visibleChildren.size();
        ExpandableNotificationRow topHeadsUpEntry = null;
        for (int i = 0; i < childCount; i++) {
            View child = algorithmState.visibleChildren.get(i);
            if (!(child instanceof ExpandableNotificationRow)) {
                break;
            }
            ExpandableNotificationRow row = (ExpandableNotificationRow) child;
            if (!row.isHeadsUp()) {
                break;
            } else if (topHeadsUpEntry == null) {
                topHeadsUpEntry = row;
            }
            StackViewState childState = resultState.getViewStateForView(row);
            boolean isTopEntry = topHeadsUpEntry == row;
            if (mIsExpanded) {
                // Ensure that the heads up is always visible even when scrolled off from the bottom
                float bottomPosition = ambientState.getMaxHeadsUpTranslation() - childState.height;
                childState.yTranslation = Math.min(childState.yTranslation,
                        bottomPosition);
            }
            if (row.isPinned()) {
                childState.yTranslation = Math.max(childState.yTranslation,
                        mNotificationsTopPadding);
                childState.height = Math.max(row.getIntrinsicHeight(), childState.height);
                if (!isTopEntry) {
                    // Ensure that a headsUp doesn't vertically extend further than the heads-up at
                    // the top most z-position
                    StackViewState topState = resultState.getViewStateForView(topHeadsUpEntry);
                    childState.height = row.getIntrinsicHeight();
                    childState.yTranslation = topState.yTranslation + topState.height
                            - childState.height;
                }
            }
        }
    }

    /**
     * Clamp the yTranslation both up and down to valid positions.
     *
     * @param childViewState the view state of the child
     * @param minHeight the minimum height of this child
     */
    private void clampYTranslation(StackViewState childViewState, int minHeight,
            AmbientState ambientState) {
        clampPositionToBottomStackStart(childViewState, childViewState.height, minHeight,
                ambientState);
        clampPositionToTopStackEnd(childViewState, childViewState.height);
    }

    /**
     * Clamp the yTranslation of the child down such that its end is at most on the beginning of
     * the bottom stack.
     *
     * @param childViewState the view state of the child
     * @param childHeight the height of this child
     * @param minHeight the minumum Height of the View
     */
    private void clampPositionToBottomStackStart(StackViewState childViewState,
            int childHeight, int minHeight, AmbientState ambientState) {

        int bottomStackStart = ambientState.getInnerHeight()
                - mBottomStackPeekSize - mCollapseSecondCardPadding;
        int childStart = bottomStackStart - childHeight;
        if (childStart < childViewState.yTranslation) {
            float newHeight = bottomStackStart - childViewState.yTranslation;
            if (newHeight < minHeight) {
                newHeight = minHeight;
                childViewState.yTranslation = bottomStackStart - minHeight;
            }
            childViewState.height = (int) newHeight;
        }
    }

    /**
     * Clamp the yTranslation of the child up such that its end is at lest on the end of the top
     * stack.
     *
     * @param childViewState the view state of the child
     * @param childHeight the height of this child
     */
    private void clampPositionToTopStackEnd(StackViewState childViewState,
            int childHeight) {
        childViewState.yTranslation = Math.max(childViewState.yTranslation,
                mFirstChildMinHeight - childHeight);
    }

    private int getMaxAllowedChildHeight(View child) {
        if (child instanceof ExpandableView) {
            ExpandableView expandableView = (ExpandableView) child;
            return expandableView.getIntrinsicHeight();
        }
        return child == null? mCollapsedSize : child.getHeight();
    }

    private void updateStateForChildTransitioningInBottom(StackScrollAlgorithmState algorithmState,
            float transitioningPositionStart, ExpandableView child, float currentYPosition,
            StackViewState childViewState, int childHeight) {

        // This is the transitioning element on top of bottom stack, calculate how far we are in.
        algorithmState.partialInBottom = 1.0f - (
                (transitioningPositionStart - currentYPosition) / (childHeight +
                        mPaddingBetweenElements));

        // the offset starting at the transitionPosition of the bottom stack
        float offset = mBottomStackIndentationFunctor.getValue(algorithmState.partialInBottom);
        algorithmState.itemsInBottomStack += algorithmState.partialInBottom;
        int newHeight = childHeight;
        if (childHeight > child.getMinHeight()) {
            newHeight = (int) Math.max(Math.min(transitioningPositionStart + offset -
                    mPaddingBetweenElements - currentYPosition, childHeight),
                    child.getMinHeight());
            childViewState.height = newHeight;
        }
        childViewState.yTranslation = transitioningPositionStart + offset - newHeight
                - mPaddingBetweenElements;

        // We want at least to be at the end of the top stack when collapsing
        clampPositionToTopStackEnd(childViewState, newHeight);
        childViewState.location = StackViewState.LOCATION_MAIN_AREA;
    }

    private void updateStateForChildFullyInBottomStack(StackScrollAlgorithmState algorithmState,
            float transitioningPositionStart, StackViewState childViewState,
            int minHeight, AmbientState ambientState) {
        float currentYPosition;
        algorithmState.itemsInBottomStack += 1.0f;
        if (algorithmState.itemsInBottomStack < MAX_ITEMS_IN_BOTTOM_STACK) {
            // We are visually entering the bottom stack
            currentYPosition = transitioningPositionStart
                    + mBottomStackIndentationFunctor.getValue(algorithmState.itemsInBottomStack)
                    - mPaddingBetweenElements;
            childViewState.location = StackViewState.LOCATION_BOTTOM_STACK_PEEKING;
        } else {
            // we are fully inside the stack
            if (algorithmState.itemsInBottomStack > MAX_ITEMS_IN_BOTTOM_STACK + 2) {
                childViewState.alpha = 0.0f;
            } else if (algorithmState.itemsInBottomStack
                    > MAX_ITEMS_IN_BOTTOM_STACK + 1) {
                childViewState.alpha = 1.0f - algorithmState.partialInBottom;
            }
            childViewState.location = StackViewState.LOCATION_BOTTOM_STACK_HIDDEN;
            currentYPosition = ambientState.getInnerHeight();
        }
        childViewState.height = minHeight;
        childViewState.yTranslation = currentYPosition - minHeight;
        clampPositionToTopStackEnd(childViewState, minHeight);
    }

    private void updateStateForTopStackChild(StackScrollAlgorithmState algorithmState,
            int numberOfElementsCompletelyIn, int i, int childHeight,
            StackViewState childViewState, float scrollOffset) {


        // First we calculate the index relative to the current stack window of size at most
        // {@link #MAX_ITEMS_IN_TOP_STACK}
        int paddedIndex = i - 1
                - Math.max(numberOfElementsCompletelyIn - MAX_ITEMS_IN_TOP_STACK, 0);
        if (paddedIndex >= 0) {

            // We are currently visually entering the top stack
            float distanceToStack = (childHeight + mPaddingBetweenElements)
                    - algorithmState.scrolledPixelsTop;
            if (i == algorithmState.lastTopStackIndex
                    && distanceToStack > (mTopStackTotalSize + mPaddingBetweenElements)) {

                // Child is currently translating into stack but not yet inside slow down zone.
                // Handle it like the regular scrollview.
                childViewState.yTranslation = scrollOffset;
            } else {
                // Apply stacking logic.
                float numItemsBefore;
                if (i == algorithmState.lastTopStackIndex) {
                    numItemsBefore = 1.0f
                            - (distanceToStack / (mTopStackTotalSize + mPaddingBetweenElements));
                } else {
                    numItemsBefore = algorithmState.itemsInTopStack - i;
                }
                // The end position of the current child
                float currentChildEndY = mFirstChildMinHeight + mTopStackTotalSize
                        - mTopStackIndentationFunctor.getValue(numItemsBefore);
                childViewState.yTranslation = currentChildEndY - childHeight;
            }
            childViewState.location = StackViewState.LOCATION_TOP_STACK_PEEKING;
        } else {
            if (paddedIndex == -1) {
                childViewState.alpha = 1.0f - algorithmState.partialInTop;
            } else {
                // We are hidden behind the top card and faded out, so we can hide ourselves.
                childViewState.alpha = 0.0f;
            }
            childViewState.yTranslation = mFirstChildMinHeight - childHeight;
            childViewState.location = StackViewState.LOCATION_TOP_STACK_HIDDEN;
        }


    }

    /**
     * Find the number of items in the top stack and update the result state if needed.
     *
     * @param resultState The result state to update if a height change of an child occurs
     * @param algorithmState The state in which the current pass of the algorithm is currently in
     */
    private void findNumberOfItemsInTopStackAndUpdateState(StackScrollState resultState,
            StackScrollAlgorithmState algorithmState, AmbientState ambientState) {

        // The y Position if the element would be in a regular scrollView
        float yPositionInScrollView = 0.0f;
        int childCount = algorithmState.visibleChildren.size();

        // find the number of elements in the top stack.
        for (int i = 0; i < childCount; i++) {
            ExpandableView child = algorithmState.visibleChildren.get(i);
            StackViewState childViewState = resultState.getViewStateForView(child);
            int childHeight = getMaxAllowedChildHeight(child);
            float yPositionInScrollViewAfterElement = yPositionInScrollView
                    + childHeight
                    + mPaddingBetweenElements;
            if (yPositionInScrollView < algorithmState.scrollY) {
                if (i == 0 && algorithmState.scrollY <= mFirstChildMinHeight) {

                    // The starting position of the bottom stack peek
                    int bottomPeekStart = ambientState.getInnerHeight() - mBottomStackPeekSize -
                            mCollapseSecondCardPadding;
                    // Collapse and expand the first child while the shade is being expanded
                    float maxHeight = mIsExpansionChanging && child == mFirstChildWhileExpanding
                            ? mFirstChildMaxHeight
                            : childHeight;
                    childViewState.height = (int) Math.max(Math.min(bottomPeekStart, maxHeight),
                            mFirstChildMinHeight);
                    algorithmState.itemsInTopStack = 1.0f;

                } else if (yPositionInScrollViewAfterElement < algorithmState.scrollY) {
                    // According to the regular scroll view we are fully off screen
                    algorithmState.itemsInTopStack += 1.0f;
                    if (i == 0) {
                        childViewState.height = child.getMinHeight();
                    }
                } else {
                    // According to the regular scroll view we are partially off screen

                    // How much did we scroll into this child
                    algorithmState.scrolledPixelsTop = algorithmState.scrollY
                            - yPositionInScrollView;
                    algorithmState.partialInTop = (algorithmState.scrolledPixelsTop) / (childHeight
                            + mPaddingBetweenElements);

                    // Our element can be expanded, so this can get negative
                    algorithmState.partialInTop = Math.max(0.0f, algorithmState.partialInTop);
                    algorithmState.itemsInTopStack += algorithmState.partialInTop;

                    if (i == 0) {
                        // If it is expanded we have to collapse it to a new size
                        float newSize = yPositionInScrollViewAfterElement
                                - mPaddingBetweenElements
                                - algorithmState.scrollY + mFirstChildMinHeight;
                        newSize = Math.max(mFirstChildMinHeight, newSize);
                        algorithmState.itemsInTopStack = 1.0f;
                        childViewState.height = (int) newSize;
                    }
                    algorithmState.lastTopStackIndex = i;
                    break;
                }
            } else {
                algorithmState.lastTopStackIndex = i - 1;
                // We are already past the stack so we can end the loop
                break;
            }
            yPositionInScrollView = yPositionInScrollViewAfterElement;
        }
    }

    /**
     * Calculate the Z positions for all children based on the number of items in both stacks and
     * save it in the resultState
     *
     * @param resultState The result state to update the zTranslation values
     * @param algorithmState The state in which the current pass of the algorithm is currently in
     */
    private void updateZValuesForState(StackScrollState resultState,
            StackScrollAlgorithmState algorithmState) {
        int childCount = algorithmState.visibleChildren.size();
        for (int i = 0; i < childCount; i++) {
            View child = algorithmState.visibleChildren.get(i);
            StackViewState childViewState = resultState.getViewStateForView(child);
            if (i < algorithmState.itemsInTopStack) {
                float stackIndex = algorithmState.itemsInTopStack - i;

                // Ensure that the topmost item is a little bit higher than the rest when fully
                // scrolled, to avoid drawing errors when swiping it out
                float max = MAX_ITEMS_IN_TOP_STACK + (i == 0 ? 2.5f : 2);
                stackIndex = Math.min(stackIndex, max);
                if (i == 0 && algorithmState.itemsInTopStack < 2.0f) {

                    // We only have the top item and an additional item in the top stack,
                    // Interpolate the index from 0 to 2 while the second item is
                    // translating in.
                    stackIndex -= 1.0f;
                    if (algorithmState.scrollY > mFirstChildMinHeight) {

                        // Since there is a shadow treshhold, we cant just interpolate from 0 to
                        // 2 but we interpolate from 0.1f to 2.0f when scrolled in. The jump in
                        // height will not be noticable since we have padding in between.
                        stackIndex = 0.1f + stackIndex * 1.9f;
                    }
                }
                childViewState.zTranslation = mZBasicHeight
                        + stackIndex * mZDistanceBetweenElements;
            } else if (i > (childCount - 1 - algorithmState.itemsInBottomStack)) {
                float numItemsAbove = i - (childCount - 1 - algorithmState.itemsInBottomStack);
                float translationZ = mZBasicHeight
                        - numItemsAbove * mZDistanceBetweenElements;
                childViewState.zTranslation = translationZ;
            } else {
                childViewState.zTranslation = mZBasicHeight;
            }
        }
    }

    public void onExpansionStarted(StackScrollState currentState) {
        mIsExpansionChanging = true;
        mExpandedOnStart = mIsExpanded;
        ViewGroup hostView = currentState.getHostView();
        updateFirstChildHeightWhileExpanding(hostView);
    }

    private void updateFirstChildHeightWhileExpanding(ViewGroup hostView) {
        mFirstChildWhileExpanding = (ExpandableView) findFirstVisibleChild(hostView);
        if (mFirstChildWhileExpanding != null) {
            if (mExpandedOnStart) {

                // We are collapsing the shade, so the first child can get as most as high as the
                // current height or the end value of the animation.
                mFirstChildMaxHeight = StackStateAnimator.getFinalActualHeight(
                        mFirstChildWhileExpanding);
            } else {
                updateFirstChildMaxSizeToMaxHeight();
            }
        } else {
            mFirstChildMaxHeight = 0;
        }
    }

    private void updateFirstChildMaxSizeToMaxHeight() {
        // We are expanding the shade, expand it to its full height.
        if (!isMaxSizeInitialized(mFirstChildWhileExpanding)) {

            // This child was not layouted yet, wait for a layout pass
            mFirstChildWhileExpanding
                    .addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
                        @Override
                        public void onLayoutChange(View v, int left, int top, int right,
                                int bottom, int oldLeft, int oldTop, int oldRight,
                                int oldBottom) {
                            if (mFirstChildWhileExpanding != null) {
                                mFirstChildMaxHeight = getMaxAllowedChildHeight(
                                        mFirstChildWhileExpanding);
                            } else {
                                mFirstChildMaxHeight = 0;
                            }
                            v.removeOnLayoutChangeListener(this);
                        }
                    });
        } else {
            mFirstChildMaxHeight = getMaxAllowedChildHeight(mFirstChildWhileExpanding);
        }
    }

    private boolean isMaxSizeInitialized(ExpandableView child) {
        if (child instanceof ExpandableNotificationRow) {
            ExpandableNotificationRow row = (ExpandableNotificationRow) child;
            return row.isMaxExpandHeightInitialized();
        }
        return child == null || child.getWidth() != 0;
    }

    private View findFirstVisibleChild(ViewGroup container) {
        int childCount = container.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = container.getChildAt(i);
            if (child.getVisibility() != View.GONE) {
                return child;
            }
        }
        return null;
    }

    public void onExpansionStopped() {
        mIsExpansionChanging = false;
        mFirstChildWhileExpanding = null;
    }

    public void setIsExpanded(boolean isExpanded) {
        this.mIsExpanded = isExpanded;
    }

    public void notifyChildrenChanged(final NotificationStackScrollLayout hostView) {
        mFirstChild = hostView.getFirstChildNotGone();
        if (mIsExpansionChanging) {
            hostView.post(new Runnable() {
                @Override
                public void run() {
                    updateFirstChildHeightWhileExpanding(hostView);
                }
            });
        }
    }

    public void setDimmed(boolean dimmed) {
        mDimmed = dimmed;
        updatePadding();
    }

    public void onReset(ExpandableView view) {
        if (view.equals(mFirstChildWhileExpanding)) {
            updateFirstChildMaxSizeToMaxHeight();
        }
    }

    class StackScrollAlgorithmState {

        /**
         * The scroll position of the algorithm
         */
        public int scrollY;

        /**
         *  The quantity of items which are in the top stack.
         */
        public float itemsInTopStack;

        /**
         * how far in is the element currently transitioning into the top stack
         */
        public float partialInTop;

        /**
         * The number of pixels the last child in the top stack has scrolled in to the stack
         */
        public float scrolledPixelsTop;

        /**
         * The last item index which is in the top stack.
         */
        public int lastTopStackIndex;

        /**
         * The quantity of items which are in the bottom stack.
         */
        public float itemsInBottomStack;

        /**
         * how far in is the element currently transitioning into the bottom stack
         */
        public float partialInBottom;

        /**
         * The children from the host view which are not gone.
         */
        public final ArrayList<ExpandableView> visibleChildren = new ArrayList<ExpandableView>();
    }

}
