/*
 * Copyright 2024 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.input;

import com.android.internal.util.DataClass;
import com.android.tools.r8.keepanno.annotations.KeepItemKind;
import com.android.tools.r8.keepanno.annotations.UsedByNative;

/**
 * A Java representation of hardware properties for a touchpad or mouse device.
 * This class mirrors the Gestures library HardwareProperties C++ struct used for representing
 * touchpad and mouse device properties, including touch area, resolution, and features like haptic
 * feedback, multitouch, and scroll wheels. It facilitates interaction between native and managed
 * code in Android.
 */
@DataClass(
        genToString = true
)
@UsedByNative(
        description = "Called from JNI in jni/com_android_server_input_InputManagerService.cpp",
        kind = KeepItemKind.CLASS_AND_MEMBERS)
public class TouchpadHardwareProperties {
    /**
     * The minimum X coordinate that the device can report.
     */
    private float mLeft;

    /**
     * The minimum Y coordinate that the device can report.
     */
    private float mTop;

    /**
     * The maximum X coordinate that the device can report.
     */
    private float mRight;

    /**
     * The maximum Y coordinate that the device can report.
     */
    private float mBottom;

    /**
     * The resolution of the X axis, in units per mm. Set to 0 if the
     * resolution is unknown.
     */
    private float mResX;
    /**
     * The resolutions of the Y axis, in units per mm. Set to 0 if the
     * resolution is unknown.
     */
    private float mResY;

    /**
     * The minimum orientation value.
     */
    private float mOrientationMinimum;
    /**
     * The maximum orientation value.
     */
    private float mOrientationMaximum;

    /**
     * The maximum number of finger slots that the device can report in one
     * HardwareState struct.
     */
    private short mMaxFingerCount;

    /**
     * Whether the touchpad has a button under its touch surface, allowing the
     * user to click by pressing (almost) anywhere on the pad, as opposed to
     * having one or more separate buttons for clicking.
     */
    private boolean mIsButtonPad;

    /**
     * Whether the touchpad is haptic, meaning that it reports true pressure (not
     * just touch area) via the pressure axis, and can provide haptic feedback.
     */
    private boolean mIsHapticPad;

    /**
     * Whether the touchpad reports pressure values in any way.
     */
    private boolean mReportsPressure = true;

    /**
     * Returns a string representation of this instance, including all fields.
     */
    public String toString() {
        return "HardwareProperties{"
                + "left=" + mLeft
                + ", top=" + mTop
                + ", right=" + mRight
                + ", bottom=" + mBottom
                + ", resX=" + mResX
                + ", resY=" + mResY
                + ", orientationMinimum=" + mOrientationMinimum
                + ", orientationMaximum=" + mOrientationMaximum
                + ", maxFingerCount=" + mMaxFingerCount
                + ", isButtonPad=" + mIsButtonPad
                + ", isHapticPad=" + mIsHapticPad
                + ", reportsPressure=" + mReportsPressure
                + '}';
    }


    // Code below generated by codegen v1.0.23.
    //
    // DO NOT MODIFY!
    // CHECKSTYLE:OFF Generated code
    //
    // To regenerate run:
    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/services/core/java/com/android/server/input
    // /TouchpadHardwareProperties.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 */ TouchpadHardwareProperties(
            float left,
            float top,
            float right,
            float bottom,
            float resX,
            float resY,
            float orientationMinimum,
            float orientationMaximum,
            short maxFingerCount,
            boolean isButtonPad,
            boolean isHapticPad,
            boolean reportsPressure) {
        this.mLeft = left;
        this.mTop = top;
        this.mRight = right;
        this.mBottom = bottom;
        this.mResX = resX;
        this.mResY = resY;
        this.mOrientationMinimum = orientationMinimum;
        this.mOrientationMaximum = orientationMaximum;
        this.mMaxFingerCount = maxFingerCount;
        this.mIsButtonPad = isButtonPad;
        this.mIsHapticPad = isHapticPad;
        this.mReportsPressure = reportsPressure;

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

    /**
     * The minimum X coordinate that the device can report.
     */
    @DataClass.Generated.Member
    public float getLeft() {
        return mLeft;
    }

    /**
     * The minimum Y coordinate that the device can report.
     */
    @DataClass.Generated.Member
    public float getTop() {
        return mTop;
    }

    /**
     * The maximum X coordinate that the device can report.
     */
    @DataClass.Generated.Member
    public float getRight() {
        return mRight;
    }

    /**
     * The maximum Y coordinate that the device can report.
     */
    @DataClass.Generated.Member
    public float getBottom() {
        return mBottom;
    }

    /**
     * The resolution of the X axis, in units per mm. Set to 0 if the
     * resolution is unknown.
     */
    @DataClass.Generated.Member
    public float getResX() {
        return mResX;
    }

    /**
     * The resolutions of the Y axis, in units per mm. Set to 0 if the
     * resolution is unknown.
     */
    @DataClass.Generated.Member
    public float getResY() {
        return mResY;
    }

    /**
     * The minimum orientation value.
     */
    @DataClass.Generated.Member
    public float getOrientationMinimum() {
        return mOrientationMinimum;
    }

    /**
     * The maximum orientation value.
     */
    @DataClass.Generated.Member
    public float getOrientationMaximum() {
        return mOrientationMaximum;
    }

    /**
     * The maximum number of finger slots that the device can report in one
     * HardwareState struct.
     */
    @DataClass.Generated.Member
    public short getMaxFingerCount() {
        return mMaxFingerCount;
    }

    /**
     * Whether the touchpad has a button under its touch surface, allowing the
     * user to click by pressing (almost) anywhere on the pad, as opposed to
     * having one or more separate buttons for clicking.
     */
    @DataClass.Generated.Member
    public boolean isIsButtonPad() {
        return mIsButtonPad;
    }

    /**
     * Whether the touchpad is haptic, meaning that it reports true pressure (not
     * just touch area) via the pressure axis, and can provide haptic feedback.
     */
    @DataClass.Generated.Member
    public boolean isIsHapticPad() {
        return mIsHapticPad;
    }

    /**
     * Whether the touchpad reports pressure values in any way.
     */
    @DataClass.Generated.Member
    public boolean isReportsPressure() {
        return mReportsPressure;
    }

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

        private float mLeft;
        private float mTop;
        private float mRight;
        private float mBottom;
        private float mResX;
        private float mResY;
        private float mOrientationMinimum;
        private float mOrientationMaximum;
        private short mMaxFingerCount;
        private boolean mIsButtonPad;
        private boolean mIsHapticPad;
        private boolean mReportsPressure;

        private long mBuilderFieldsSet = 0L;

        /**
         * Creates a new Builder.
         *
         * @param left
         *   The minimum X coordinate that the device can report.
         * @param top
         *   The minimum Y coordinate that the device can report.
         * @param right
         *   The maximum X coordinate that the device can report.
         * @param bottom
         *   The maximum Y coordinate that the device can report.
         * @param resX
         *   The resolution of the X axis, in units per mm. Set to 0 if the
         *   resolution is unknown.
         * @param resY
         *   The resolutions of the Y axis, in units per mm. Set to 0 if the
         *   resolution is unknown.
         * @param orientationMinimum
         *   The minimum orientation value.
         * @param orientationMaximum
         *   The maximum orientation value.
         * @param maxFingerCount
         *   The maximum number of finger slots that the device can report in one
         *   HardwareState struct.
         * @param isButtonPad
         *   Whether the touchpad has a button under its touch surface, allowing the
         *   user to click by pressing (almost) anywhere on the pad, as opposed to
         *   having one or more separate buttons for clicking.
         * @param isHapticPad
         *   Whether the touchpad is haptic, meaning that it reports true pressure (not
         *   just touch area) via the pressure axis, and can provide haptic feedback.
         */
        public Builder(
                float left,
                float top,
                float right,
                float bottom,
                float resX,
                float resY,
                float orientationMinimum,
                float orientationMaximum,
                short maxFingerCount,
                boolean isButtonPad,
                boolean isHapticPad) {
            mLeft = left;
            mTop = top;
            mRight = right;
            mBottom = bottom;
            mResX = resX;
            mResY = resY;
            mOrientationMinimum = orientationMinimum;
            mOrientationMaximum = orientationMaximum;
            mMaxFingerCount = maxFingerCount;
            mIsButtonPad = isButtonPad;
            mIsHapticPad = isHapticPad;
        }

        /**
         * The minimum X coordinate that the device can report.
         */
        @DataClass.Generated.Member
        public @android.annotation.NonNull Builder setLeft(float value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x1;
            mLeft = value;
            return this;
        }

        /**
         * The minimum Y coordinate that the device can report.
         */
        @DataClass.Generated.Member
        public @android.annotation.NonNull Builder setTop(float value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x2;
            mTop = value;
            return this;
        }

        /**
         * The maximum X coordinate that the device can report.
         */
        @DataClass.Generated.Member
        public @android.annotation.NonNull Builder setRight(float value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x4;
            mRight = value;
            return this;
        }

        /**
         * The maximum Y coordinate that the device can report.
         */
        @DataClass.Generated.Member
        public @android.annotation.NonNull Builder setBottom(float value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x8;
            mBottom = value;
            return this;
        }

        /**
         * The resolution of the X axis, in units per mm. Set to 0 if the
         * resolution is unknown.
         */
        @DataClass.Generated.Member
        public @android.annotation.NonNull Builder setResX(float value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x10;
            mResX = value;
            return this;
        }

        /**
         * The resolutions of the Y axis, in units per mm. Set to 0 if the
         * resolution is unknown.
         */
        @DataClass.Generated.Member
        public @android.annotation.NonNull Builder setResY(float value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x20;
            mResY = value;
            return this;
        }

        /**
         * The minimum orientation value.
         */
        @DataClass.Generated.Member
        public @android.annotation.NonNull Builder setOrientationMinimum(float value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x40;
            mOrientationMinimum = value;
            return this;
        }

        /**
         * The maximum orientation value.
         */
        @DataClass.Generated.Member
        public @android.annotation.NonNull Builder setOrientationMaximum(float value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x80;
            mOrientationMaximum = value;
            return this;
        }

        /**
         * The maximum number of finger slots that the device can report in one
         * HardwareState struct.
         */
        @DataClass.Generated.Member
        public @android.annotation.NonNull Builder setMaxFingerCount(short value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x100;
            mMaxFingerCount = value;
            return this;
        }

        /**
         * Whether the touchpad has a button under its touch surface, allowing the
         * user to click by pressing (almost) anywhere on the pad, as opposed to
         * having one or more separate buttons for clicking.
         */
        @DataClass.Generated.Member
        public @android.annotation.NonNull Builder setIsButtonPad(boolean value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x200;
            mIsButtonPad = value;
            return this;
        }

        /**
         * Whether the touchpad is haptic, meaning that it reports true pressure (not
         * just touch area) via the pressure axis, and can provide haptic feedback.
         */
        @DataClass.Generated.Member
        public @android.annotation.NonNull Builder setIsHapticPad(boolean value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x400;
            mIsHapticPad = value;
            return this;
        }

        /**
         * Whether the touchpad reports pressure values in any way.
         */
        @DataClass.Generated.Member
        public @android.annotation.NonNull Builder setReportsPressure(boolean value) {
            checkNotUsed();
            mBuilderFieldsSet |= 0x800;
            mReportsPressure = value;
            return this;
        }

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

            if ((mBuilderFieldsSet & 0x800) == 0) {
                mReportsPressure = true;
            }
            TouchpadHardwareProperties o = new TouchpadHardwareProperties(
                    mLeft,
                    mTop,
                    mRight,
                    mBottom,
                    mResX,
                    mResY,
                    mOrientationMinimum,
                    mOrientationMaximum,
                    mMaxFingerCount,
                    mIsButtonPad,
                    mIsHapticPad,
                    mReportsPressure);
            return o;
        }

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

    @DataClass.Generated(
            time = 1723570664889L,
            codegenVersion = "1.0.23",
            sourceFile = "frameworks/base/services/core"
                    + "/java/com/android/server/input/TouchpadHardwareProperties.java",
            inputSignatures = "private  float mLeft\nprivate  float mTop\nprivate  float mRight\n"
                    + "private  float mBottom\nprivate  float mResX\nprivate  float mResY\n"
                    + "private  float mOrientationMinimum\nprivate  float mOrientationMaximum\n"
                    + "private  short mMaxFingerCount\nprivate  boolean mIsButtonPad\n"
                    + "private  boolean mIsHapticPad\nprivate  boolean mReportsPressure\n"
                    + "public  java.lang.String toString()\n"
                    + "class TouchpadHardwareProperties extends java.lang.Object implements []\n"
                    + "@com.android.internal.util.DataClass(genToString=true)")
    @Deprecated
    private void __metadata() {}

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