/*
 * 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 com.android.internal.view;

import android.annotation.NonNull;
import android.graphics.Rect;
import android.os.Parcelable;
import android.view.InsetsFlags;
import android.view.ViewDebug;

import com.android.internal.util.DataClass;

/**
 * Specifies which region applies which appearance.
 */
@DataClass
public class AppearanceRegion implements Parcelable {

    private int mAppearance;
    private @NonNull Rect mBounds;

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        final AppearanceRegion sa = (AppearanceRegion) o;
        return mAppearance == sa.mAppearance && mBounds.equals(sa.mBounds);
    }

    @Override
    public String toString() {
        final String appearanceString =
                ViewDebug.flagsToString(InsetsFlags.class, "appearance", mAppearance);
        return "AppearanceRegion{" + appearanceString + " bounds=" + mBounds.toShortString() + "}";
    }



    // Code below generated by codegen v1.0.7.
    //
    // DO NOT MODIFY!
    // CHECKSTYLE:OFF Generated code
    //
    // To regenerate run:
    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/com/android/internal/view/AppearanceRegion.java


    @DataClass.Generated.Member
    public AppearanceRegion(
            int appearance,
            @NonNull Rect bounds) {
        this.mAppearance = appearance;
        this.mBounds = bounds;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mBounds);

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

    @DataClass.Generated.Member
    public int getAppearance() {
        return mAppearance;
    }

    @DataClass.Generated.Member
    public @NonNull Rect getBounds() {
        return mBounds;
    }

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

        dest.writeInt(mAppearance);
        dest.writeTypedObject(mBounds, flags);
    }

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

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

        int appearance = in.readInt();
        Rect bounds = (Rect) in.readTypedObject(Rect.CREATOR);

        this.mAppearance = appearance;
        this.mBounds = bounds;
        com.android.internal.util.AnnotationValidations.validate(
                NonNull.class, null, mBounds);

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

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

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

    @DataClass.Generated(
            time = 1570909617357L,
            codegenVersion = "1.0.7",
            sourceFile = "frameworks/base/core/java/com/android/internal/view/AppearanceRegion.java",
            inputSignatures = "private  int mAppearance\nprivate @android.annotation.NonNull android.graphics.Rect mBounds\npublic @java.lang.Override boolean equals(java.lang.Object)\npublic @java.lang.Override java.lang.String toString()\nclass AppearanceRegion extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass")
    @Deprecated
    private void __metadata() {}

}
