/*
 * Copyright (C) 2019 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.inline;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Size;

import com.android.internal.util.DataClass;

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

/**
 * This class represents the presentation specification by which an inline suggestion
 * should abide when constructing its UI. Since suggestions are inlined in a
 * host application while provided by another source, they need to be consistent
 * with the host's look at feel to allow building smooth and integrated UIs.
 *
 * @hide
 * @removed
 */
@DataClass(genEqualsHashCode = true, genToString = true, genBuilder = true)
public final class InlinePresentationSpec implements Parcelable {

    /** The minimal size of the suggestion. */
    @NonNull
    private final Size mMinSize;
    /** The maximal size of the suggestion. */
    @NonNull
    private final Size mMaxSize;

    /**
     * The extras encoding the UI style information. Defaults to {@code Bundle.EMPTY} in which case
     * the default system UI style will be used.
     */
    @NonNull
    private final Bundle mStyle;

    private static Bundle defaultStyle() {
        return Bundle.EMPTY;
    }

    /** @hide */
    @DataClass.Suppress({"setMaxSize", "setMinSize"})
    abstract static class BaseBuilder {
    }

    /**
     * @hide
     */
    public android.widget.inline.InlinePresentationSpec toWidget() {
        final android.widget.inline.InlinePresentationSpec.Builder builder =
                new android.widget.inline.InlinePresentationSpec.Builder(
                        getMinSize(), getMaxSize());
        final Bundle style = getStyle();
        if (style != null) {
            builder.setStyle(style);
        }
        return builder.build();
    }

    /**
     * @hide
     */
    public static android.view.inline.InlinePresentationSpec fromWidget(
            android.widget.inline.InlinePresentationSpec widget) {
        final android.view.inline.InlinePresentationSpec.Builder builder =
                new android.view.inline.InlinePresentationSpec.Builder(
                        widget.getMinSize(), widget.getMaxSize());
        final Bundle style = widget.getStyle();
        if (style != null) {
            builder.setStyle(style);
        }
        return builder.build();
    }

    /**
     * @hide
     */
    public static List<android.view.inline.InlinePresentationSpec> fromWidgets(
            List<android.widget.inline.InlinePresentationSpec> widgets) {
        final ArrayList<android.view.inline.InlinePresentationSpec> convertedSpecs =
                new ArrayList<>();
        for (int i = 0; i < widgets.size(); i++) {
            convertedSpecs.add(fromWidget(widgets.get(i)));
        }
        return convertedSpecs;
    }



    // Code below generated by codegen v1.0.15.
    //
    // DO NOT MODIFY!
    // CHECKSTYLE:OFF Generated code
    //
    // To regenerate run:
    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/view/inline/InlinePresentationSpec.java
    //
    // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
    //   Settings > Editor > Code Style > Formatter Control
    //@formatter:off


    @DataClass.Generated.Member
    /* package-private */ InlinePresentationSpec(
            @NonNull Size minSize,
            @NonNull Size maxSize,
            @NonNull Bundle style) {
        this.mMinSize = minSize;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mMinSize);
        this.mMaxSize = maxSize;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mMaxSize);
        this.mStyle = style;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mStyle);

        // onConstructed(); // You can define this method to get a callback
    }

    /**
     * The minimal size of the suggestion.
     */
    @UnsupportedAppUsage
    @DataClass.Generated.Member
    public @NonNull Size getMinSize() {
        return mMinSize;
    }

    /**
     * The maximal size of the suggestion.
     */
    @UnsupportedAppUsage
    @DataClass.Generated.Member
    public @NonNull Size getMaxSize() {
        return mMaxSize;
    }

    /**
     * The extras encoding the UI style information. Defaults to {@code Bundle.EMPTY} in which case
     * the default system UI style will be used.
     */
    @DataClass.Generated.Member
    public @NonNull Bundle getStyle() {
        return mStyle;
    }

    @Override
    @DataClass.Generated.Member
    public String toString() {
        // You can override field toString logic by defining methods like:
        // String fieldNameToString() { ... }

        return "InlinePresentationSpec { " +
                "minSize = " + mMinSize + ", " +
                "maxSize = " + mMaxSize + ", " +
                "style = " + mStyle +
        " }";
    }

    @Override
    @DataClass.Generated.Member
    public boolean equals(@Nullable Object o) {
        // You can override field equality logic by defining either of the methods like:
        // boolean fieldNameEquals(InlinePresentationSpec other) { ... }
        // boolean fieldNameEquals(FieldType otherValue) { ... }

        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        @SuppressWarnings("unchecked")
        InlinePresentationSpec that = (InlinePresentationSpec) o;
        //noinspection PointlessBooleanExpression
        return true
                && java.util.Objects.equals(mMinSize, that.mMinSize)
                && java.util.Objects.equals(mMaxSize, that.mMaxSize)
                && java.util.Objects.equals(mStyle, that.mStyle);
    }

    @Override
    @DataClass.Generated.Member
    public int hashCode() {
        // You can override field hashCode logic by defining methods like:
        // int fieldNameHashCode() { ... }

        int _hash = 1;
        _hash = 31 * _hash + java.util.Objects.hashCode(mMinSize);
        _hash = 31 * _hash + java.util.Objects.hashCode(mMaxSize);
        _hash = 31 * _hash + java.util.Objects.hashCode(mStyle);
        return _hash;
    }

    @Override
    @DataClass.Generated.Member
    public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
        // You can override field parcelling by defining methods like:
        // void parcelFieldName(Parcel dest, int flags) { ... }

        dest.writeSize(mMinSize);
        dest.writeSize(mMaxSize);
        dest.writeBundle(mStyle);
    }

    @Override
    @DataClass.Generated.Member
    public int describeContents() { return 0; }

    /** @hide */
    @SuppressWarnings({"unchecked", "RedundantCast"})
    @DataClass.Generated.Member
    /* package-private */ InlinePresentationSpec(@NonNull android.os.Parcel in) {
        // You can override field unparcelling by defining methods like:
        // static FieldType unparcelFieldName(Parcel in) { ... }

        Size minSize = (Size) in.readSize();
        Size maxSize = (Size) in.readSize();
        Bundle style = in.readBundle();

        this.mMinSize = minSize;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mMinSize);
        this.mMaxSize = maxSize;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mMaxSize);
        this.mStyle = style;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mStyle);

        // onConstructed(); // You can define this method to get a callback
    }

    @DataClass.Generated.Member
    public static final @NonNull Parcelable.Creator<InlinePresentationSpec> CREATOR
            = new Parcelable.Creator<InlinePresentationSpec>() {
        @Override
        public InlinePresentationSpec[] newArray(int size) {
            return new InlinePresentationSpec[size];
        }

        @Override
        public InlinePresentationSpec createFromParcel(@NonNull android.os.Parcel in) {
            return new InlinePresentationSpec(in);
        }
    };

    /**
     * A builder for {@link InlinePresentationSpec}
     */
    @SuppressWarnings("WeakerAccess")
    @DataClass.Generated.Member
    public static final class Builder extends BaseBuilder {

        private @NonNull Size mMinSize;
        private @NonNull Size mMaxSize;
        private @NonNull Bundle mStyle;

        private long mBuilderFieldsSet = 0L;

        /**
         * Creates a new Builder.
         *
         * @param minSize
         *   The minimal size of the suggestion.
         * @param maxSize
         *   The maximal size of the suggestion.
         */
        @UnsupportedAppUsage
        public Builder(
                @NonNull Size minSize,
                @NonNull Size maxSize) {
            mMinSize = minSize;
            com.android.internal.util.AnnotationValidations.validate(
                    NonNull.class, null, mMinSize);
            mMaxSize = maxSize;
            com.android.internal.util.AnnotationValidations.validate(
                    NonNull.class, null, mMaxSize);
        }

        /**
         * The extras encoding the UI style information. Defaults to {@code Bundle.EMPTY} in which case
         * the default system UI style will be used.
         */
        @DataClass.Generated.Member
        public @NonNull Builder setStyle(@NonNull Bundle value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x4;
            mStyle = value;
            return this;
        }

        /** Builds the instance. This builder should not be touched after calling this! */
        @UnsupportedAppUsage
        @NonNull
        public InlinePresentationSpec build() {
            checkNotUsed();
            mBuilderFieldsSet |= 0x8; // Mark builder used

            if ((mBuilderFieldsSet & 0x4) == 0) {
                mStyle = defaultStyle();
            }
            InlinePresentationSpec o = new InlinePresentationSpec(
                    mMinSize,
                    mMaxSize,
                    mStyle);
            return o;
        }

        private void checkNotUsed() {
            if ((mBuilderFieldsSet & 0x8) != 0) {
                throw new IllegalStateException(
                        "This Builder should not be reused. Use a new Builder instance instead");
            }
        }
    }

    @DataClass.Generated(
            time = 1585691139012L,
            codegenVersion = "1.0.15",
            sourceFile = "frameworks/base/core/java/android/view/inline/InlinePresentationSpec.java",
            inputSignatures = "private final @android.annotation.NonNull android.util.Size mMinSize\nprivate final @android.annotation.NonNull android.util.Size mMaxSize\nprivate final @android.annotation.NonNull android.os.Bundle mStyle\nprivate static  android.os.Bundle defaultStyle()\npublic  android.widget.inline.InlinePresentationSpec toWidget()\npublic static  android.view.inline.InlinePresentationSpec fromWidget(android.widget.inline.InlinePresentationSpec)\npublic static  java.util.List<android.view.inline.InlinePresentationSpec> fromWidgets(java.util.List<android.widget.inline.InlinePresentationSpec>)\nclass InlinePresentationSpec extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genBuilder=true)\nclass BaseBuilder extends java.lang.Object implements []")
    @Deprecated
    private void __metadata() {}


    //@formatter:on
    // End of generated code

}
