/*
 * Copyright (C) 2018 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 android.view;

import static android.view.ViewRootImpl.NEW_INSETS_MODE_FULL;
import static android.view.ViewRootImpl.NEW_INSETS_MODE_NONE;
import static android.view.WindowInsets.Type.MANDATORY_SYSTEM_GESTURES;
import static android.view.WindowInsets.Type.SIZE;
import static android.view.WindowInsets.Type.SYSTEM_GESTURES;
import static android.view.WindowInsets.Type.indexOf;

import android.annotation.IntDef;
import android.annotation.Nullable;
import android.graphics.Insets;
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.SparseIntArray;
import android.view.WindowInsets.Type;
import android.view.WindowInsets.Type.InsetType;
import android.view.WindowManager.LayoutParams;

import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Objects;

/**
 * Holder for state of system windows that cause window insets for all other windows in the system.
 * @hide
 */
public class InsetsState implements Parcelable {

    /**
     * Internal representation of inset source types. This is different from the public API in
     * {@link WindowInsets.Type} as one type from the public API might indicate multiple windows
     * at the same time.
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = "TYPE", value = {
            TYPE_TOP_BAR,
            TYPE_SIDE_BAR_1,
            TYPE_SIDE_BAR_2,
            TYPE_SIDE_BAR_3,
            TYPE_TOP_GESTURES,
            TYPE_BOTTOM_GESTURES,
            TYPE_LEFT_GESTURES,
            TYPE_RIGHT_GESTURES,
            TYPE_TOP_TAPPABLE_ELEMENT,
            TYPE_BOTTOM_TAPPABLE_ELEMENT,
            TYPE_IME
    })
    public @interface InternalInsetType {}

    static final int FIRST_TYPE = 0;

    /** Top bar. Can be status bar or caption in freeform windowing mode. */
    public static final int TYPE_TOP_BAR = FIRST_TYPE;

    /**
     * Up to 3 side bars that appear on left/right/bottom. On phones there is only one side bar
     * (the navigation bar, see {@link #TYPE_NAVIGATION_BAR}), but other form factors might have
     * multiple, like Android Auto.
     */
    public static final int TYPE_SIDE_BAR_1 = 1;
    public static final int TYPE_SIDE_BAR_2 = 2;
    public static final int TYPE_SIDE_BAR_3 = 3;

    public static final int TYPE_TOP_GESTURES = 4;
    public static final int TYPE_BOTTOM_GESTURES = 5;
    public static final int TYPE_LEFT_GESTURES = 6;
    public static final int TYPE_RIGHT_GESTURES = 7;
    public static final int TYPE_TOP_TAPPABLE_ELEMENT = 8;
    public static final int TYPE_BOTTOM_TAPPABLE_ELEMENT = 9;

    /** Input method window. */
    public static final int TYPE_IME = 10;

    static final int LAST_TYPE = TYPE_IME;

    // Derived types

    /** First side bar is navigation bar. */
    public static final int TYPE_NAVIGATION_BAR = TYPE_SIDE_BAR_1;

    /** A shelf is the same as the navigation bar. */
    public static final int TYPE_SHELF = TYPE_NAVIGATION_BAR;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = "INSET_SIDE", value = {
            INSET_SIDE_LEFT,
            INSET_SIDE_TOP,
            INSET_SIDE_RIGHT,
            INSET_SIDE_BOTTOM,
            INSET_SIDE_UNKNWON
    })
    public @interface InsetSide {}
    static final int INSET_SIDE_LEFT = 0;
    static final int INSET_SIDE_TOP = 1;
    static final int INSET_SIDE_RIGHT = 2;
    static final int INSET_SIDE_BOTTOM = 3;
    static final int INSET_SIDE_UNKNWON = 4;

    private final ArrayMap<Integer, InsetsSource> mSources = new ArrayMap<>();

    /**
     * The frame of the display these sources are relative to.
     */
    private final Rect mDisplayFrame = new Rect();

    public InsetsState() {
    }

    public InsetsState(InsetsState copy) {
        set(copy);
    }

    public InsetsState(InsetsState copy, boolean copySources) {
        set(copy, copySources);
    }

    /**
     * Calculates {@link WindowInsets} based on the current source configuration.
     *
     * @param frame The frame to calculate the insets relative to.
     * @return The calculated insets.
     */
    public WindowInsets calculateInsets(Rect frame, boolean isScreenRound,
            boolean alwaysConsumeSystemBars, DisplayCutout cutout,
            @Nullable Rect legacyContentInsets, @Nullable Rect legacyStableInsets,
            int legacySoftInputMode, @Nullable @InsetSide SparseIntArray typeSideMap) {
        Insets[] typeInsetsMap = new Insets[Type.SIZE];
        Insets[] typeMaxInsetsMap = new Insets[Type.SIZE];
        boolean[] typeVisibilityMap = new boolean[SIZE];
        final Rect relativeFrame = new Rect(frame);
        final Rect relativeFrameMax = new Rect(frame);
        if (ViewRootImpl.sNewInsetsMode != NEW_INSETS_MODE_FULL
                && legacyContentInsets != null && legacyStableInsets != null) {
            WindowInsets.assignCompatInsets(typeInsetsMap, legacyContentInsets);
            WindowInsets.assignCompatInsets(typeMaxInsetsMap, legacyStableInsets);
        }
        for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) {
            InsetsSource source = mSources.get(type);
            if (source == null) {
                continue;
            }

            boolean skipSystemBars = ViewRootImpl.sNewInsetsMode != NEW_INSETS_MODE_FULL
                    && (type == TYPE_TOP_BAR || type == TYPE_NAVIGATION_BAR);
            boolean skipIme = source.getType() == TYPE_IME
                    && (legacySoftInputMode & LayoutParams.SOFT_INPUT_ADJUST_RESIZE) == 0;
            boolean skipLegacyTypes = ViewRootImpl.sNewInsetsMode == NEW_INSETS_MODE_NONE
                    && (toPublicType(type) & Type.compatSystemInsets()) != 0;
            if (skipSystemBars || skipIme || skipLegacyTypes) {
                typeVisibilityMap[indexOf(toPublicType(type))] = source.isVisible();
                continue;
            }

            processSource(source, relativeFrame, false /* ignoreVisibility */, typeInsetsMap,
                    typeSideMap, typeVisibilityMap);

            // IME won't be reported in max insets as the size depends on the EditorInfo of the IME
            // target.
            if (source.getType() != TYPE_IME) {
                processSource(source, relativeFrameMax, true /* ignoreVisibility */,
                        typeMaxInsetsMap, null /* typeSideMap */, null /* typeVisibilityMap */);
            }
        }
        return new WindowInsets(typeInsetsMap, typeMaxInsetsMap, typeVisibilityMap, isScreenRound,
                alwaysConsumeSystemBars, cutout);
    }

    private void processSource(InsetsSource source, Rect relativeFrame, boolean ignoreVisibility,
            Insets[] typeInsetsMap, @Nullable @InsetSide SparseIntArray typeSideMap,
            @Nullable boolean[] typeVisibilityMap) {
        Insets insets = source.calculateInsets(relativeFrame, ignoreVisibility);

        int type = toPublicType(source.getType());
        processSourceAsPublicType(source, typeInsetsMap, typeSideMap, typeVisibilityMap,
                insets, type);

        if (type == MANDATORY_SYSTEM_GESTURES) {
            // Mandatory system gestures are also system gestures.
            // TODO: find a way to express this more generally. One option would be to define
            //       Type.systemGestureInsets() as NORMAL | MANDATORY, but then we lose the
            //       ability to set systemGestureInsets() independently from
            //       mandatorySystemGestureInsets() in the Builder.
            processSourceAsPublicType(source, typeInsetsMap, typeSideMap, typeVisibilityMap,
                    insets, SYSTEM_GESTURES);
        }
    }

    private void processSourceAsPublicType(InsetsSource source, Insets[] typeInsetsMap,
            @InsetSide @Nullable SparseIntArray typeSideMap,
            @Nullable boolean[] typeVisibilityMap, Insets insets, int type) {
        int index = indexOf(type);
        Insets existing = typeInsetsMap[index];
        if (existing == null) {
            typeInsetsMap[index] = insets;
        } else {
            typeInsetsMap[index] = Insets.max(existing, insets);
        }

        if (typeVisibilityMap != null) {
            typeVisibilityMap[index] = source.isVisible();
        }

        if (typeSideMap != null && !Insets.NONE.equals(insets)) {
            @InsetSide int insetSide = getInsetSide(insets);
            if (insetSide != INSET_SIDE_UNKNWON) {
                typeSideMap.put(source.getType(), getInsetSide(insets));
            }
        }
    }

    /**
     * Retrieves the side for a certain {@code insets}. It is required that only one field l/t/r/b
     * is set in order that this method returns a meaningful result.
     */
    private @InsetSide int getInsetSide(Insets insets) {
        if (insets.left != 0) {
            return INSET_SIDE_LEFT;
        }
        if (insets.top != 0) {
            return INSET_SIDE_TOP;
        }
        if (insets.right != 0) {
            return INSET_SIDE_RIGHT;
        }
        if (insets.bottom != 0) {
            return INSET_SIDE_BOTTOM;
        }
        return INSET_SIDE_UNKNWON;
    }

    public InsetsSource getSource(@InternalInsetType int type) {
        return mSources.computeIfAbsent(type, InsetsSource::new);
    }

    public void setDisplayFrame(Rect frame) {
        mDisplayFrame.set(frame);
    }

    public Rect getDisplayFrame() {
        return mDisplayFrame;
    }

    /**
     * Modifies the state of this class to exclude a certain type to make it ready for dispatching
     * to the client.
     *
     * @param type The {@link InternalInsetType} of the source to remove
     */
    public void removeSource(int type) {
        mSources.remove(type);
    }

    public void set(InsetsState other) {
        set(other, false /* copySources */);
    }

    public void set(InsetsState other, boolean copySources) {
        mDisplayFrame.set(other.mDisplayFrame);
        mSources.clear();
        if (copySources) {
            for (int i = 0; i < other.mSources.size(); i++) {
                InsetsSource source = other.mSources.valueAt(i);
                mSources.put(source.getType(), new InsetsSource(source));
            }
        } else {
            mSources.putAll(other.mSources);
        }
    }

    public void addSource(InsetsSource source) {
        mSources.put(source.getType(), source);
    }

    public int getSourcesCount() {
        return mSources.size();
    }

    public InsetsSource sourceAt(int index) {
        return mSources.valueAt(index);
    }

    public static @InternalInsetType ArraySet<Integer> toInternalType(@InsetType int insetTypes) {
        final ArraySet<Integer> result = new ArraySet<>();
        if ((insetTypes & Type.TOP_BAR) != 0) {
            result.add(TYPE_TOP_BAR);
        }
        if ((insetTypes & Type.SIDE_BARS) != 0) {
            result.add(TYPE_SIDE_BAR_1);
            result.add(TYPE_SIDE_BAR_2);
            result.add(TYPE_SIDE_BAR_3);
        }
        if ((insetTypes & Type.IME) != 0) {
            result.add(TYPE_IME);
        }
        return result;
    }

    static @InsetType int toPublicType(@InternalInsetType int type) {
        switch (type) {
            case TYPE_TOP_BAR:
                return Type.TOP_BAR;
            case TYPE_SIDE_BAR_1:
            case TYPE_SIDE_BAR_2:
            case TYPE_SIDE_BAR_3:
                return Type.SIDE_BARS;
            case TYPE_IME:
                return Type.IME;
            case TYPE_TOP_GESTURES:
            case TYPE_BOTTOM_GESTURES:
                return Type.MANDATORY_SYSTEM_GESTURES;
            case TYPE_LEFT_GESTURES:
            case TYPE_RIGHT_GESTURES:
                return Type.SYSTEM_GESTURES;
            case TYPE_TOP_TAPPABLE_ELEMENT:
            case TYPE_BOTTOM_TAPPABLE_ELEMENT:
                return Type.TAPPABLE_ELEMENT;
            default:
                throw new IllegalArgumentException("Unknown type: " + type);
        }
    }

    public static boolean getDefaultVisibility(@InsetType int type) {
        switch (type) {
            case TYPE_TOP_BAR:
            case TYPE_SIDE_BAR_1:
            case TYPE_SIDE_BAR_2:
            case TYPE_SIDE_BAR_3:
                return true;
            case TYPE_IME:
                return false;
            default:
                return true;
        }
    }

    public void dump(String prefix, PrintWriter pw) {
        pw.println(prefix + "InsetsState");
        for (int i = mSources.size() - 1; i >= 0; i--) {
            mSources.valueAt(i).dump(prefix + "  ", pw);
        }
    }

    public static String typeToString(int type) {
        switch (type) {
            case TYPE_TOP_BAR:
                return "TYPE_TOP_BAR";
            case TYPE_SIDE_BAR_1:
                return "TYPE_SIDE_BAR_1";
            case TYPE_SIDE_BAR_2:
                return "TYPE_SIDE_BAR_2";
            case TYPE_SIDE_BAR_3:
                return "TYPE_SIDE_BAR_3";
            case TYPE_TOP_GESTURES:
                return "TYPE_TOP_GESTURES";
            case TYPE_BOTTOM_GESTURES:
                return "TYPE_BOTTOM_GESTURES";
            case TYPE_LEFT_GESTURES:
                return "TYPE_LEFT_GESTURES";
            case TYPE_RIGHT_GESTURES:
                return "TYPE_RIGHT_GESTURES";
            case TYPE_TOP_TAPPABLE_ELEMENT:
                return "TYPE_TOP_TAPPABLE_ELEMENT";
            case TYPE_BOTTOM_TAPPABLE_ELEMENT:
                return "TYPE_BOTTOM_TAPPABLE_ELEMENT";
            default:
                return "TYPE_UNKNOWN_" + type;
        }
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) { return true; }
        if (o == null || getClass() != o.getClass()) { return false; }

        InsetsState state = (InsetsState) o;

        if (!mDisplayFrame.equals(state.mDisplayFrame)) {
            return false;
        }
        if (mSources.size() != state.mSources.size()) {
            return false;
        }
        for (int i = mSources.size() - 1; i >= 0; i--) {
            InsetsSource source = mSources.valueAt(i);
            InsetsSource otherSource = state.mSources.get(source.getType());
            if (otherSource == null) {
                return false;
            }
            if (!otherSource.equals(source)) {
                return false;
            }
        }
        return true;
    }

    @Override
    public int hashCode() {
        return Objects.hash(mDisplayFrame, mSources);
    }

    public InsetsState(Parcel in) {
        readFromParcel(in);
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeParcelable(mDisplayFrame, flags);
        dest.writeInt(mSources.size());
        for (int i = 0; i < mSources.size(); i++) {
            dest.writeParcelable(mSources.valueAt(i), flags);
        }
    }

    public static final @android.annotation.NonNull Creator<InsetsState> CREATOR = new Creator<InsetsState>() {

        public InsetsState createFromParcel(Parcel in) {
            return new InsetsState(in);
        }

        public InsetsState[] newArray(int size) {
            return new InsetsState[size];
        }
    };

    public void readFromParcel(Parcel in) {
        mSources.clear();
        mDisplayFrame.set(in.readParcelable(null /* loader */));
        final int size = in.readInt();
        for (int i = 0; i < size; i++) {
            final InsetsSource source = in.readParcelable(null /* loader */);
            mSources.put(source.getType(), source);
        }
    }
}

