/*
 * Copyright (C) 2013 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.server.wm;

import android.graphics.Rect;
import android.util.Slog;

import static com.android.server.am.ActivityStackSupervisor.HOME_STACK_ID;
import static com.android.server.wm.WindowManagerService.DEBUG_STACK;
import static com.android.server.wm.WindowManagerService.TAG;

import java.io.PrintWriter;

public class StackBox {
    /** Used with {@link WindowManagerService#createStack}. Dependent on Configuration LTR/RTL. */
    public static final int TASK_STACK_GOES_BEFORE = 0;
    /** Used with {@link WindowManagerService#createStack}. Dependent on Configuration LTR/RTL. */
    public static final int TASK_STACK_GOES_AFTER = 1;
    /** Used with {@link WindowManagerService#createStack}. Horizontal to left of. */
    public static final int TASK_STACK_TO_LEFT_OF = 2;
    /** Used with {@link WindowManagerService#createStack}. Horizontal to right of. */
    public static final int TASK_STACK_TO_RIGHT_OF = 3;
    /** Used with {@link WindowManagerService#createStack}. Vertical: lower t/b Rect values. */
    public static final int TASK_STACK_GOES_ABOVE = 4;
    /** Used with {@link WindowManagerService#createStack}. Vertical: higher t/b Rect values. */
    public static final int TASK_STACK_GOES_BELOW = 5;
    /** Used with {@link WindowManagerService#createStack}. Put on a higher layer on display. */
    public static final int TASK_STACK_GOES_OVER = 6;
    /** Used with {@link WindowManagerService#createStack}. Put on a lower layer on display. */
    public static final int TASK_STACK_GOES_UNDER = 7;

    static int sCurrentBoxId = 0;

    /** Unique id for this box */
    final int mStackBoxId;

    /** The service */
    final WindowManagerService mService;

    /** The display this box sits in. */
    final DisplayContent mDisplayContent;

    /** Non-null indicates this is mFirst or mSecond of a parent StackBox. Null indicates this
     * is this entire size of mDisplayContent. */
    StackBox mParent;

    /** First child, this is null exactly when mStack is non-null. */
    StackBox mFirst;

    /** Second child, this is null exactly when mStack is non-null. */
    StackBox mSecond;

    /** Stack of Tasks, this is null exactly when mFirst and mSecond are non-null. */
    TaskStack mStack;

    /** Content limits relative to the DisplayContent this sits in. */
    Rect mBounds = new Rect();

    /** Relative orientation of mFirst and mSecond. */
    boolean mVertical;

    /** Fraction of mBounds to devote to mFirst, remainder goes to mSecond */
    float mWeight;

    /** Dirty flag. Something inside this or some descendant of this has changed. */
    boolean layoutNeeded;

    /** True if this StackBox sits below the Status Bar. */
    boolean mUnderStatusBar;

    /** Used to keep from reallocating a temporary Rect for propagating bounds to child boxes */
    Rect mTmpRect = new Rect();

    StackBox(WindowManagerService service, DisplayContent displayContent, StackBox parent) {
        synchronized (StackBox.class) {
            mStackBoxId = sCurrentBoxId++;
        }

        mService = service;
        mDisplayContent = displayContent;
        mParent = parent;
    }

    /** Propagate #layoutNeeded bottom up. */
    void makeDirty() {
        layoutNeeded = true;
        if (mParent != null) {
            mParent.makeDirty();
        }
    }

    /**
     * Determine if a particular StackBox is this one or a descendant of this one.
     * @param stackBoxId The StackBox being searched for.
     * @return true if the specified StackBox matches this or one of its descendants.
     */
    boolean contains(int stackBoxId) {
        return mStackBoxId == stackBoxId || mFirst.contains(stackBoxId)
                || mSecond.contains(stackBoxId);
    }

    /**
     * Return the stackId of the stack that intersects the passed point.
     * @param x coordinate of point.
     * @param y coordinate of point.
     * @return -1 if point is outside of mBounds, otherwise the stackId of the containing stack.
     */
    int stackIdFromPoint(int x, int y) {
        if (!mBounds.contains(x, y)) {
            return -1;
        }
        if (mStack != null) {
            return mStack.mStackId;
        }
        int stackId = mFirst.stackIdFromPoint(x, y);
        if (stackId >= 0) {
            return stackId;
        }
        return mSecond.stackIdFromPoint(x, y);
    }

    /** Determine if this StackBox is the first child or second child.
     * @return true if this is the first child.
     */
    boolean isFirstChild() {
        return mParent != null && mParent.mFirst == this;
    }

    /** Returns the bounds of the specified TaskStack if it is contained in this StackBox.
     * @param stackId the TaskStack to find the bounds of.
     * @return a new Rect with the bounds of stackId if it is within this StackBox, null otherwise.
     */
    Rect getStackBounds(int stackId) {
        if (mStack != null) {
            return mStack.mStackId == stackId ? new Rect(mBounds) : null;
        }
        Rect bounds = mFirst.getStackBounds(stackId);
        if (bounds != null) {
            return bounds;
        }
        return mSecond.getStackBounds(stackId);
    }

    /**
     * Create a new TaskStack relative to a specified one by splitting the StackBox containing
     * the specified TaskStack into two children. The size and position each of the new StackBoxes
     * is determined by the passed parameters.
     * @param stackId The id of the new TaskStack to create.
     * @param relativeStackBoxId The id of the StackBox to place the new TaskStack next to.
     * @param position One of the static TASK_STACK_GOES_xxx positions defined in this class.
     * @param weight The percentage size of the parent StackBox to devote to the new TaskStack.
     * @return The new TaskStack.
     */
    TaskStack split(int stackId, int relativeStackBoxId, int position, float weight) {
        if (mStackBoxId != relativeStackBoxId) {
            // This is not the targeted StackBox.
            if (mStack != null) {
                return null;
            }
            // Propagate the split to see if the targeted StackBox is in either sub box.
            TaskStack stack = mFirst.split(stackId, relativeStackBoxId, position, weight);
            if (stack != null) {
                return stack;
            }
            return mSecond.split(stackId, relativeStackBoxId, position, weight);
        }

        // Found it!
        TaskStack stack = new TaskStack(mService, stackId, mDisplayContent);
        TaskStack firstStack;
        TaskStack secondStack;
        if (position == TASK_STACK_GOES_BEFORE) {
            // TODO: Test Configuration here for LTR/RTL.
            position = TASK_STACK_TO_LEFT_OF;
        } else if (position == TASK_STACK_GOES_AFTER) {
            // TODO: Test Configuration here for LTR/RTL.
            position = TASK_STACK_TO_RIGHT_OF;
        }
        switch (position) {
            default:
            case TASK_STACK_TO_LEFT_OF:
            case TASK_STACK_TO_RIGHT_OF:
                mVertical = false;
                if (position == TASK_STACK_TO_LEFT_OF) {
                    mWeight = weight;
                    firstStack = stack;
                    secondStack = mStack;
                } else {
                    mWeight = 1.0f - weight;
                    firstStack = mStack;
                    secondStack = stack;
                }
                break;
            case TASK_STACK_GOES_ABOVE:
            case TASK_STACK_GOES_BELOW:
                mVertical = true;
                if (position == TASK_STACK_GOES_ABOVE) {
                    mWeight = weight;
                    firstStack = stack;
                    secondStack = mStack;
                } else {
                    mWeight = 1.0f - weight;
                    firstStack = mStack;
                    secondStack = stack;
                }
                break;
        }

        mFirst = new StackBox(mService, mDisplayContent, this);
        firstStack.mStackBox = mFirst;
        mFirst.mStack = firstStack;

        mSecond = new StackBox(mService, mDisplayContent, this);
        secondStack.mStackBox = mSecond;
        mSecond.mStack = secondStack;

        mStack = null;
        return stack;
    }

    /** Return the stackId of the first mFirst StackBox with a non-null mStack */
    int getStackId() {
        if (mStack != null) {
            return mStack.mStackId;
        }
        return mFirst.getStackId();
    }

    /** Remove this box and propagate its sibling's content up to their parent.
     * @return The first stackId of the resulting StackBox. */
    int remove() {
        if (mStack != null) {
            if (DEBUG_STACK) Slog.i(TAG, "StackBox.remove: removing stackId=" + mStack.mStackId);
            mDisplayContent.mStackHistory.remove(mStack);
        }
        mDisplayContent.layoutNeeded = true;

        if (mParent == null) {
            // This is the top-plane stack.
            if (DEBUG_STACK) Slog.i(TAG, "StackBox.remove: removing top plane.");
            mDisplayContent.removeStackBox(this);
            return HOME_STACK_ID;
        }

        StackBox sibling = isFirstChild() ? mParent.mSecond : mParent.mFirst;
        StackBox grandparent = mParent.mParent;
        sibling.mParent = grandparent;
        if (grandparent == null) {
            // mParent is a top-plane stack. Now sibling will be.
            if (DEBUG_STACK) Slog.i(TAG, "StackBox.remove: grandparent null");
            mDisplayContent.removeStackBox(mParent);
            mDisplayContent.addStackBox(sibling, true);
        } else {
            if (DEBUG_STACK) Slog.i(TAG, "StackBox.remove: grandparent getting sibling");
            if (mParent.isFirstChild()) {
                grandparent.mFirst = sibling;
            } else {
                grandparent.mSecond = sibling;
            }
        }
        return sibling.getStackId();
    }

    boolean resize(int stackBoxId, float weight) {
        if (mStackBoxId != stackBoxId) {
            return mStack == null &&
                    (mFirst.resize(stackBoxId, weight) || mSecond.resize(stackBoxId, weight));
        }
        // Don't change weight on topmost stack.
        if (mParent != null) {
            mParent.mWeight = isFirstChild() ? weight : 1.0f - weight;
        }
        return true;
    }

    /** If this is a terminal StackBox (contains a TaskStack) set the bounds.
     * @param bounds The rectangle to set the bounds to.
     * @param underStatusBar True if the StackBox is directly below the Status Bar.
     * @return True if the bounds changed, false otherwise. */
    boolean setStackBoxSizes(Rect bounds, boolean underStatusBar) {
        boolean change = false;
        if (mUnderStatusBar != underStatusBar) {
            change = true;
            mUnderStatusBar = underStatusBar;
        }
        if (mStack != null) {
            change |= !mBounds.equals(bounds);
            if (change) {
                mBounds.set(bounds);
                mStack.setBounds(bounds, underStatusBar);
            }
        } else {
            mTmpRect.set(bounds);
            if (mVertical) {
                final int height = bounds.height();
                int firstHeight = (int)(height * mWeight);
                mTmpRect.bottom = bounds.top + firstHeight;
                change |= mFirst.setStackBoxSizes(mTmpRect, underStatusBar);
                mTmpRect.top = mTmpRect.bottom;
                mTmpRect.bottom = bounds.top + height;
                change |= mSecond.setStackBoxSizes(mTmpRect, false);
            } else {
                final int width = bounds.width();
                int firstWidth = (int)(width * mWeight);
                mTmpRect.right = bounds.left + firstWidth;
                change |= mFirst.setStackBoxSizes(mTmpRect, underStatusBar);
                mTmpRect.left = mTmpRect.right;
                mTmpRect.right = bounds.left + width;
                change |= mSecond.setStackBoxSizes(mTmpRect, underStatusBar);
            }
        }
        return change;
    }

    void resetAnimationBackgroundAnimator() {
        if (mStack != null) {
            mStack.resetAnimationBackgroundAnimator();
            return;
        }
        mFirst.resetAnimationBackgroundAnimator();
        mSecond.resetAnimationBackgroundAnimator();
    }

    boolean animateDimLayers() {
        if (mStack != null) {
            return mStack.animateDimLayers();
        }
        boolean result = mFirst.animateDimLayers();
        result |= mSecond.animateDimLayers();
        return result;
    }

    void resetDimming() {
        if (mStack != null) {
            mStack.resetDimmingTag();
            return;
        }
        mFirst.resetDimming();
        mSecond.resetDimming();
    }

    boolean isDimming() {
        if (mStack != null) {
            return mStack.isDimming();
        }
        boolean result = mFirst.isDimming();
        result |= mSecond.isDimming();
        return result;
    }

    void stopDimmingIfNeeded() {
        if (mStack != null) {
            mStack.stopDimmingIfNeeded();
            return;
        }
        mFirst.stopDimmingIfNeeded();
        mSecond.stopDimmingIfNeeded();
    }

    public void dump(String prefix, PrintWriter pw) {
        pw.print(prefix); pw.print("mParent="); pw.println(mParent);
        pw.print(prefix); pw.print("mBounds="); pw.print(mBounds.toShortString());
            pw.print(" mVertical="); pw.print(mVertical);
            pw.print(" layoutNeeded="); pw.println(layoutNeeded);
        if (mFirst != null) {
            pw.print(prefix); pw.print("mFirst="); pw.println(System.identityHashCode(mFirst));
            mFirst.dump(prefix + "  ", pw);
            pw.print(prefix); pw.print("mSecond="); pw.println(System.identityHashCode(mSecond));
            mSecond.dump(prefix + "  ", pw);
        } else {
            pw.print(prefix); pw.print("mStack="); pw.println(mStack);
            mStack.dump(prefix + "  ", pw);
        }
    }

    @Override
    public String toString() {
        if (mStack != null) {
            return "Box{" + hashCode() + " stack=" + mStack.mStackId + "}";
        }
        return "Box{" + hashCode() + " parent=" + System.identityHashCode(mParent)
                + " first=" + System.identityHashCode(mFirst)
                + " second=" + System.identityHashCode(mSecond) + "}";
    }
}
