/*
 * Copyright (C) 2022 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 android.annotation.IntRange;
import android.annotation.NonNull;
import android.graphics.Insets;
import android.graphics.Rect;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;
import android.view.InsetsSource.Flags;
import android.view.WindowInsets.Type.InsetsType;

import java.util.Arrays;
import java.util.Objects;

/**
 * Insets provided by a window.
 *
 * The insets frame will by default as the window frame size. If the providers are set, the
 * calculation result based on the source size will be used as the insets frame.
 *
 * The InsetsFrameProvider should be self-contained. Nothing describing the window itself, such as
 * contentInsets, visibleInsets, etc. won't affect the insets providing to other windows when this
 * is set.
 * @hide
 */
public class InsetsFrameProvider implements Parcelable {

    /**
     * Uses the display frame as the source.
     */
    public static final int SOURCE_DISPLAY = 0;

    /**
     * Uses the window bounds as the source.
     */
    public static final int SOURCE_CONTAINER_BOUNDS = 1;

    /**
     * Uses the window frame as the source.
     */
    public static final int SOURCE_FRAME = 2;

    /**
     * Uses {@link #mArbitraryRectangle} as the source.
     */
    public static final int SOURCE_ARBITRARY_RECTANGLE = 3;

    private final int mId;

    /**
     * The selection of the starting rectangle to be converted into source frame.
     */
    private int mSource = SOURCE_FRAME;

    /**
     * This is used as the source frame only if SOURCE_ARBITRARY_RECTANGLE is applied.
     */
    private Rect mArbitraryRectangle;

    /**
     * Modifies the starting rectangle selected by {@link #mSource}.
     *
     * For example, when the given source frame is (0, 0) - (100, 200), and the insetsSize is null,
     * the source frame will be directly used as the final insets frame. If the insetsSize is set to
     * (0, 0, 0, 50) instead, the insets frame will be a frame starting from the bottom side of the
     * source frame with height of 50, i.e., (0, 150) - (100, 200).
     */
    private Insets mInsetsSize = null;

    /**
     * Various behavioral options/flags. Default is none.
     *
     * @see Flags
     */
    private @Flags int mFlags;

    /**
     * If null, the size set in insetsSize will be applied to all window types. If it contains
     * element of some types, the insets reported to the window with that types will be overridden.
     */
    private InsetsSizeOverride[] mInsetsSizeOverrides = null;

    /**
     * This field, if set, is indicating the insets needs to be at least the given size inside the
     * display cutout safe area. This will be compared to the insets size calculated based on other
     * attributes, and will be applied when this is larger. This is independent of the
     * PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT in LayoutParams, as this is not going to change
     * the layout of the window, but only change the insets frame. This can be applied to insets
     * calculated based on all three source frames.
     *
     * Be cautious, this will not be in effect for the window types whose insets size is overridden.
     */
    private Insets mMinimalInsetsSizeInDisplayCutoutSafe = null;

    /**
     * Creates an InsetsFrameProvider which describes what frame an insets source should have.
     *
     * @param owner the owner of this provider. We might have multiple sources with the same type on
     *              a display, this is used to identify them.
     * @param index the index of this provider. An owner might provide multiple sources with the
     *              same type, this is used to identify them.
     *              The value must be in a range of [0, 2047].
     * @param type the {@link InsetsType}.
     * @see InsetsSource#createId(Object, int, int)
     */
    public InsetsFrameProvider(Object owner, @IntRange(from = 0, to = 2047) int index,
            @InsetsType int type) {
        mId = InsetsSource.createId(owner, index, type);
    }

    /**
     * Returns an unique integer which identifies the insets source.
     */
    public int getId() {
        return mId;
    }

    /**
     * Returns the index specified in {@link #InsetsFrameProvider(IBinder, int, int)}.
     */
    public int getIndex() {
        return InsetsSource.getIndex(mId);
    }

    /**
     * Returns the {@link InsetsType} specified in {@link #InsetsFrameProvider(IBinder, int, int)}.
     */
    public int getType() {
        return InsetsSource.getType(mId);
    }

    public InsetsFrameProvider setSource(int source) {
        mSource = source;
        return this;
    }

    public int getSource() {
        return mSource;
    }

    public InsetsFrameProvider setFlags(@Flags int flags, @Flags int mask) {
        mFlags = (mFlags & ~mask) | (flags & mask);
        return this;
    }

    public @Flags int getFlags() {
        return mFlags;
    }

    public boolean hasFlags(@Flags int mask) {
        return (mFlags & mask) == mask;
    }

    public InsetsFrameProvider setInsetsSize(Insets insetsSize) {
        mInsetsSize = insetsSize;
        return this;
    }

    public Insets getInsetsSize() {
        return mInsetsSize;
    }

    public InsetsFrameProvider setArbitraryRectangle(Rect rect) {
        mArbitraryRectangle = new Rect(rect);
        return this;
    }

    public Rect getArbitraryRectangle() {
        return mArbitraryRectangle;
    }

    public InsetsFrameProvider setInsetsSizeOverrides(InsetsSizeOverride[] insetsSizeOverrides) {
        mInsetsSizeOverrides = insetsSizeOverrides;
        return this;
    }

    public InsetsSizeOverride[] getInsetsSizeOverrides() {
        return mInsetsSizeOverrides;
    }

    public InsetsFrameProvider setMinimalInsetsSizeInDisplayCutoutSafe(
            Insets minimalInsetsSizeInDisplayCutoutSafe) {
        mMinimalInsetsSizeInDisplayCutoutSafe = minimalInsetsSizeInDisplayCutoutSafe;
        return this;
    }

    public Insets getMinimalInsetsSizeInDisplayCutoutSafe() {
        return mMinimalInsetsSizeInDisplayCutoutSafe;
    }

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

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("InsetsFrameProvider: {");
        sb.append("id=#").append(Integer.toHexString(mId));
        sb.append(", index=").append(getIndex());
        sb.append(", type=").append(WindowInsets.Type.toString(getType()));
        sb.append(", source=").append(sourceToString(mSource));
        sb.append(", flags=[").append(InsetsSource.flagsToString(mFlags)).append("]");
        if (mInsetsSize != null) {
            sb.append(", insetsSize=").append(mInsetsSize);
        }
        if (mInsetsSizeOverrides != null) {
            sb.append(", insetsSizeOverrides=").append(Arrays.toString(mInsetsSizeOverrides));
        }
        if (mArbitraryRectangle != null) {
            sb.append(", mArbitraryRectangle=").append(mArbitraryRectangle.toShortString());
        }
        if (mMinimalInsetsSizeInDisplayCutoutSafe != null) {
            sb.append(", mMinimalInsetsSizeInDisplayCutoutSafe=")
                    .append(mMinimalInsetsSizeInDisplayCutoutSafe);
        }
        sb.append("}");
        return sb.toString();
    }

    private static String sourceToString(int source) {
        switch (source) {
            case SOURCE_DISPLAY:
                return "DISPLAY";
            case SOURCE_CONTAINER_BOUNDS:
                return "CONTAINER_BOUNDS";
            case SOURCE_FRAME:
                return "FRAME";
            case SOURCE_ARBITRARY_RECTANGLE:
                return "ARBITRARY_RECTANGLE";
        }
        return "UNDEFINED";
    }

    public InsetsFrameProvider(Parcel in) {
        mId = in.readInt();
        mSource = in.readInt();
        mFlags = in.readInt();
        mInsetsSize = in.readTypedObject(Insets.CREATOR);
        mInsetsSizeOverrides = in.createTypedArray(InsetsSizeOverride.CREATOR);
        mArbitraryRectangle = in.readTypedObject(Rect.CREATOR);
        mMinimalInsetsSizeInDisplayCutoutSafe = in.readTypedObject(Insets.CREATOR);
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mId);
        out.writeInt(mSource);
        out.writeInt(mFlags);
        out.writeTypedObject(mInsetsSize, flags);
        out.writeTypedArray(mInsetsSizeOverrides, flags);
        out.writeTypedObject(mArbitraryRectangle, flags);
        out.writeTypedObject(mMinimalInsetsSizeInDisplayCutoutSafe, flags);
    }

    public boolean idEquals(InsetsFrameProvider o) {
        return mId == o.mId;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        final InsetsFrameProvider other = (InsetsFrameProvider) o;
        return mId == other.mId && mSource == other.mSource && mFlags == other.mFlags
                && Objects.equals(mInsetsSize, other.mInsetsSize)
                && Arrays.equals(mInsetsSizeOverrides, other.mInsetsSizeOverrides)
                && Objects.equals(mArbitraryRectangle, other.mArbitraryRectangle)
                && Objects.equals(mMinimalInsetsSizeInDisplayCutoutSafe,
                        other.mMinimalInsetsSizeInDisplayCutoutSafe);
    }

    @Override
    public int hashCode() {
        return Objects.hash(mId, mSource, mFlags, mInsetsSize,
                Arrays.hashCode(mInsetsSizeOverrides), mArbitraryRectangle,
                mMinimalInsetsSizeInDisplayCutoutSafe);
    }

    public static final @NonNull Parcelable.Creator<InsetsFrameProvider> CREATOR =
            new Parcelable.Creator<>() {
                @Override
                public InsetsFrameProvider createFromParcel(Parcel in) {
                    return new InsetsFrameProvider(in);
                }

                @Override
                public InsetsFrameProvider[] newArray(int size) {
                    return new InsetsFrameProvider[size];
                }
            };

    /**
     * Class to describe the insets size to be provided to window with specific window type. If not
     * used, same insets size will be sent as instructed in the insetsSize and source.
     *
     * If the insetsSize of given type is set to {@code null}, the insets source frame will be used
     * directly for that window type.
     */
    public static class InsetsSizeOverride implements Parcelable {

        private final int mWindowType;
        private final Insets mInsetsSize;

        protected InsetsSizeOverride(Parcel in) {
            mWindowType = in.readInt();
            mInsetsSize = in.readTypedObject(Insets.CREATOR);
        }

        public InsetsSizeOverride(int windowType, Insets insetsSize) {
            mWindowType = windowType;
            mInsetsSize = insetsSize;
        }
        public int getWindowType() {
            return mWindowType;
        }

        public Insets getInsetsSize() {
            return mInsetsSize;
        }

        public static final Creator<InsetsSizeOverride> CREATOR = new Creator<>() {
            @Override
            public InsetsSizeOverride createFromParcel(Parcel in) {
                return new InsetsSizeOverride(in);
            }

            @Override
            public InsetsSizeOverride[] newArray(int size) {
                return new InsetsSizeOverride[size];
            }
        };

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

        @Override
        public void writeToParcel(Parcel out, int flags) {
            out.writeInt(mWindowType);
            out.writeTypedObject(mInsetsSize, flags);
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder(32);
            sb.append("TypedInsetsSize: {");
            sb.append("windowType=").append(ViewDebug.intToString(
                    WindowManager.LayoutParams.class, "type", mWindowType));
            sb.append(", insetsSize=").append(mInsetsSize);
            sb.append("}");
            return sb.toString();
        }

        @Override
        public int hashCode() {
            return Objects.hash(mWindowType, mInsetsSize);
        }
    }
}

