// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.

// THIS FILE WAS AUTO-GENERATED BY ./wpilibj/generate_hids.py. DO NOT MODIFY

package edu.wpi.first.wpilibj;

// import edu.wpi.first.hal.FRCNetComm.tResourceType;
// import edu.wpi.first.hal.HAL;
import edu.wpi.first.util.sendable.Sendable;
import edu.wpi.first.util.sendable.SendableBuilder;
import edu.wpi.first.wpilibj.event.BooleanEvent;
import edu.wpi.first.wpilibj.event.EventLoop;

/**
 * Handle input from Stadia controllers connected to the Driver Station.
 *
 * <p>This class handles Stadia input that comes from the Driver Station. Each time a value is
 * requested the most recent value is returned. There is a single class instance for each controller
 * and the mapping of ports to hardware buttons depends on the code in the Driver Station.
 *
 * <p>Only first party controllers from Google are guaranteed to have the correct mapping, and
 * only through the official NI DS. Sim is not guaranteed to have the same mapping, as well as any
 * 3rd party controllers.
 */
public class StadiaController extends GenericHID implements Sendable {
  /** Represents a digital button on a StadiaController. */
  public enum Button {
    /** A button. */
    kA(1),
    /** B button. */
    kB(2),
    /** X button. */
    kX(3),
    /** Y button. */
    kY(4),
    /** Left bumper button. */
    kLeftBumper(5),
    /** Right bumper button. */
    kRightBumper(6),
    /** Left stick button. */
    kLeftStick(7),
    /** Right stick button. */
    kRightStick(8),
    /** Ellipses button. */
    kEllipses(9),
    /** Hamburger button. */
    kHamburger(10),
    /** Stadia button. */
    kStadia(11),
    /** Right trigger button. */
    kRightTrigger(12),
    /** Left trigger button. */
    kLeftTrigger(13),
    /** Google button. */
    kGoogle(14),
    /** Frame button. */
    kFrame(15);

    /** Button value. */
    public final int value;

    Button(int value) {
      this.value = value;
    }

    /**
     * Get the human-friendly name of the button, matching the relevant methods. This is done by
     * stripping the leading `k`, and appending `Button`.
     *
     * <p>Primarily used for automated unit tests.
     *
     * @return the human-friendly name of the button.
     */
    @Override
    public String toString() {
      // Remove leading `k`
      return this.name().substring(1) + "Button";
    }
  }

  /** Represents an axis on an StadiaController. */
  public enum Axis {
    /** Left X axis. */
    kLeftX(0),
    /** Right X axis. */
    kRightX(3),
    /** Left Y axis. */
    kLeftY(1),
    /** Right Y axis. */
    kRightY(4);

    /** Axis value. */
    public final int value;

    Axis(int value) {
      this.value = value;
    }

    /**
     * Get the human-friendly name of the axis, matching the relevant methods. This is done by
     * stripping the leading `k`, and appending `Axis` if the name ends with `Trigger`.
     *
     * <p>Primarily used for automated unit tests.
     *
     * @return the human-friendly name of the axis.
     */
    @Override
    public String toString() {
      var name = this.name().substring(1); // Remove leading `k`
      if (name.endsWith("Trigger")) {
        return name + "Axis";
      }
      return name;
    }
  }

  /**
   * Construct an instance of a controller.
   *
   * @param port The port index on the Driver Station that the controller is plugged into (0-5).
   */
  public StadiaController(final int port) {
    super(port);
    // HAL.report(tResourceType.kResourceType_StadiaController, port + 1);
  }

  /**
   * Get the X axis value of left side of the controller.
   *
   * @return The axis value.
   */
  public double getLeftX() {
    return getRawAxis(Axis.kLeftX.value);
  }

  /**
   * Get the X axis value of right side of the controller.
   *
   * @return The axis value.
   */
  public double getRightX() {
    return getRawAxis(Axis.kRightX.value);
  }

  /**
   * Get the Y axis value of left side of the controller.
   *
   * @return The axis value.
   */
  public double getLeftY() {
    return getRawAxis(Axis.kLeftY.value);
  }

  /**
   * Get the Y axis value of right side of the controller.
   *
   * @return The axis value.
   */
  public double getRightY() {
    return getRawAxis(Axis.kRightY.value);
  }

  /**
   * Read the value of the A button on the controller.
   *
   * @return The state of the button.
   */
  public boolean getAButton() {
    return getRawButton(Button.kA.value);
  }

  /**
   * Whether the A button was pressed since the last check.
   *
   * @return Whether the button was pressed since the last check.
   */
  public boolean getAButtonPressed() {
    return getRawButtonPressed(Button.kA.value);
  }

  /**
   * Whether the A button was released since the last check.
   *
   * @return Whether the button was released since the last check.
   */
  public boolean getAButtonReleased() {
    return getRawButtonReleased(Button.kA.value);
  }

  /**
   * Constructs an event instance around the A button's digital signal.
   *
   * @param loop the event loop instance to attach the event to.
   * @return an event instance representing the A button's digital signal
   *     attached to the given loop.
   */
  public BooleanEvent a(EventLoop loop) {
    return button(Button.kA.value, loop);
  }

  /**
   * Read the value of the B button on the controller.
   *
   * @return The state of the button.
   */
  public boolean getBButton() {
    return getRawButton(Button.kB.value);
  }

  /**
   * Whether the B button was pressed since the last check.
   *
   * @return Whether the button was pressed since the last check.
   */
  public boolean getBButtonPressed() {
    return getRawButtonPressed(Button.kB.value);
  }

  /**
   * Whether the B button was released since the last check.
   *
   * @return Whether the button was released since the last check.
   */
  public boolean getBButtonReleased() {
    return getRawButtonReleased(Button.kB.value);
  }

  /**
   * Constructs an event instance around the B button's digital signal.
   *
   * @param loop the event loop instance to attach the event to.
   * @return an event instance representing the B button's digital signal
   *     attached to the given loop.
   */
  public BooleanEvent b(EventLoop loop) {
    return button(Button.kB.value, loop);
  }

  /**
   * Read the value of the X button on the controller.
   *
   * @return The state of the button.
   */
  public boolean getXButton() {
    return getRawButton(Button.kX.value);
  }

  /**
   * Whether the X button was pressed since the last check.
   *
   * @return Whether the button was pressed since the last check.
   */
  public boolean getXButtonPressed() {
    return getRawButtonPressed(Button.kX.value);
  }

  /**
   * Whether the X button was released since the last check.
   *
   * @return Whether the button was released since the last check.
   */
  public boolean getXButtonReleased() {
    return getRawButtonReleased(Button.kX.value);
  }

  /**
   * Constructs an event instance around the X button's digital signal.
   *
   * @param loop the event loop instance to attach the event to.
   * @return an event instance representing the X button's digital signal
   *     attached to the given loop.
   */
  public BooleanEvent x(EventLoop loop) {
    return button(Button.kX.value, loop);
  }

  /**
   * Read the value of the Y button on the controller.
   *
   * @return The state of the button.
   */
  public boolean getYButton() {
    return getRawButton(Button.kY.value);
  }

  /**
   * Whether the Y button was pressed since the last check.
   *
   * @return Whether the button was pressed since the last check.
   */
  public boolean getYButtonPressed() {
    return getRawButtonPressed(Button.kY.value);
  }

  /**
   * Whether the Y button was released since the last check.
   *
   * @return Whether the button was released since the last check.
   */
  public boolean getYButtonReleased() {
    return getRawButtonReleased(Button.kY.value);
  }

  /**
   * Constructs an event instance around the Y button's digital signal.
   *
   * @param loop the event loop instance to attach the event to.
   * @return an event instance representing the Y button's digital signal
   *     attached to the given loop.
   */
  public BooleanEvent y(EventLoop loop) {
    return button(Button.kY.value, loop);
  }

  /**
   * Read the value of the left bumper button on the controller.
   *
   * @return The state of the button.
   */
  public boolean getLeftBumperButton() {
    return getRawButton(Button.kLeftBumper.value);
  }

  /**
   * Whether the left bumper button was pressed since the last check.
   *
   * @return Whether the button was pressed since the last check.
   */
  public boolean getLeftBumperButtonPressed() {
    return getRawButtonPressed(Button.kLeftBumper.value);
  }

  /**
   * Whether the left bumper button was released since the last check.
   *
   * @return Whether the button was released since the last check.
   */
  public boolean getLeftBumperButtonReleased() {
    return getRawButtonReleased(Button.kLeftBumper.value);
  }

  /**
   * Constructs an event instance around the left bumper button's digital signal.
   *
   * @param loop the event loop instance to attach the event to.
   * @return an event instance representing the left bumper button's digital signal
   *     attached to the given loop.
   */
  public BooleanEvent leftBumper(EventLoop loop) {
    return button(Button.kLeftBumper.value, loop);
  }

  /**
   * Read the value of the right bumper button on the controller.
   *
   * @return The state of the button.
   */
  public boolean getRightBumperButton() {
    return getRawButton(Button.kRightBumper.value);
  }

  /**
   * Whether the right bumper button was pressed since the last check.
   *
   * @return Whether the button was pressed since the last check.
   */
  public boolean getRightBumperButtonPressed() {
    return getRawButtonPressed(Button.kRightBumper.value);
  }

  /**
   * Whether the right bumper button was released since the last check.
   *
   * @return Whether the button was released since the last check.
   */
  public boolean getRightBumperButtonReleased() {
    return getRawButtonReleased(Button.kRightBumper.value);
  }

  /**
   * Constructs an event instance around the right bumper button's digital signal.
   *
   * @param loop the event loop instance to attach the event to.
   * @return an event instance representing the right bumper button's digital signal
   *     attached to the given loop.
   */
  public BooleanEvent rightBumper(EventLoop loop) {
    return button(Button.kRightBumper.value, loop);
  }

  /**
   * Read the value of the left stick button on the controller.
   *
   * @return The state of the button.
   */
  public boolean getLeftStickButton() {
    return getRawButton(Button.kLeftStick.value);
  }

  /**
   * Whether the left stick button was pressed since the last check.
   *
   * @return Whether the button was pressed since the last check.
   */
  public boolean getLeftStickButtonPressed() {
    return getRawButtonPressed(Button.kLeftStick.value);
  }

  /**
   * Whether the left stick button was released since the last check.
   *
   * @return Whether the button was released since the last check.
   */
  public boolean getLeftStickButtonReleased() {
    return getRawButtonReleased(Button.kLeftStick.value);
  }

  /**
   * Constructs an event instance around the left stick button's digital signal.
   *
   * @param loop the event loop instance to attach the event to.
   * @return an event instance representing the left stick button's digital signal
   *     attached to the given loop.
   */
  public BooleanEvent leftStick(EventLoop loop) {
    return button(Button.kLeftStick.value, loop);
  }

  /**
   * Read the value of the right stick button on the controller.
   *
   * @return The state of the button.
   */
  public boolean getRightStickButton() {
    return getRawButton(Button.kRightStick.value);
  }

  /**
   * Whether the right stick button was pressed since the last check.
   *
   * @return Whether the button was pressed since the last check.
   */
  public boolean getRightStickButtonPressed() {
    return getRawButtonPressed(Button.kRightStick.value);
  }

  /**
   * Whether the right stick button was released since the last check.
   *
   * @return Whether the button was released since the last check.
   */
  public boolean getRightStickButtonReleased() {
    return getRawButtonReleased(Button.kRightStick.value);
  }

  /**
   * Constructs an event instance around the right stick button's digital signal.
   *
   * @param loop the event loop instance to attach the event to.
   * @return an event instance representing the right stick button's digital signal
   *     attached to the given loop.
   */
  public BooleanEvent rightStick(EventLoop loop) {
    return button(Button.kRightStick.value, loop);
  }

  /**
   * Read the value of the ellipses button on the controller.
   *
   * @return The state of the button.
   */
  public boolean getEllipsesButton() {
    return getRawButton(Button.kEllipses.value);
  }

  /**
   * Whether the ellipses button was pressed since the last check.
   *
   * @return Whether the button was pressed since the last check.
   */
  public boolean getEllipsesButtonPressed() {
    return getRawButtonPressed(Button.kEllipses.value);
  }

  /**
   * Whether the ellipses button was released since the last check.
   *
   * @return Whether the button was released since the last check.
   */
  public boolean getEllipsesButtonReleased() {
    return getRawButtonReleased(Button.kEllipses.value);
  }

  /**
   * Constructs an event instance around the ellipses button's digital signal.
   *
   * @param loop the event loop instance to attach the event to.
   * @return an event instance representing the ellipses button's digital signal
   *     attached to the given loop.
   */
  public BooleanEvent ellipses(EventLoop loop) {
    return button(Button.kEllipses.value, loop);
  }

  /**
   * Read the value of the hamburger button on the controller.
   *
   * @return The state of the button.
   */
  public boolean getHamburgerButton() {
    return getRawButton(Button.kHamburger.value);
  }

  /**
   * Whether the hamburger button was pressed since the last check.
   *
   * @return Whether the button was pressed since the last check.
   */
  public boolean getHamburgerButtonPressed() {
    return getRawButtonPressed(Button.kHamburger.value);
  }

  /**
   * Whether the hamburger button was released since the last check.
   *
   * @return Whether the button was released since the last check.
   */
  public boolean getHamburgerButtonReleased() {
    return getRawButtonReleased(Button.kHamburger.value);
  }

  /**
   * Constructs an event instance around the hamburger button's digital signal.
   *
   * @param loop the event loop instance to attach the event to.
   * @return an event instance representing the hamburger button's digital signal
   *     attached to the given loop.
   */
  public BooleanEvent hamburger(EventLoop loop) {
    return button(Button.kHamburger.value, loop);
  }

  /**
   * Read the value of the stadia button on the controller.
   *
   * @return The state of the button.
   */
  public boolean getStadiaButton() {
    return getRawButton(Button.kStadia.value);
  }

  /**
   * Whether the stadia button was pressed since the last check.
   *
   * @return Whether the button was pressed since the last check.
   */
  public boolean getStadiaButtonPressed() {
    return getRawButtonPressed(Button.kStadia.value);
  }

  /**
   * Whether the stadia button was released since the last check.
   *
   * @return Whether the button was released since the last check.
   */
  public boolean getStadiaButtonReleased() {
    return getRawButtonReleased(Button.kStadia.value);
  }

  /**
   * Constructs an event instance around the stadia button's digital signal.
   *
   * @param loop the event loop instance to attach the event to.
   * @return an event instance representing the stadia button's digital signal
   *     attached to the given loop.
   */
  public BooleanEvent stadia(EventLoop loop) {
    return button(Button.kStadia.value, loop);
  }

  /**
   * Read the value of the right trigger button on the controller.
   *
   * @return The state of the button.
   */
  public boolean getRightTriggerButton() {
    return getRawButton(Button.kRightTrigger.value);
  }

  /**
   * Whether the right trigger button was pressed since the last check.
   *
   * @return Whether the button was pressed since the last check.
   */
  public boolean getRightTriggerButtonPressed() {
    return getRawButtonPressed(Button.kRightTrigger.value);
  }

  /**
   * Whether the right trigger button was released since the last check.
   *
   * @return Whether the button was released since the last check.
   */
  public boolean getRightTriggerButtonReleased() {
    return getRawButtonReleased(Button.kRightTrigger.value);
  }

  /**
   * Constructs an event instance around the right trigger button's digital signal.
   *
   * @param loop the event loop instance to attach the event to.
   * @return an event instance representing the right trigger button's digital signal
   *     attached to the given loop.
   */
  public BooleanEvent rightTrigger(EventLoop loop) {
    return button(Button.kRightTrigger.value, loop);
  }

  /**
   * Read the value of the left trigger button on the controller.
   *
   * @return The state of the button.
   */
  public boolean getLeftTriggerButton() {
    return getRawButton(Button.kLeftTrigger.value);
  }

  /**
   * Whether the left trigger button was pressed since the last check.
   *
   * @return Whether the button was pressed since the last check.
   */
  public boolean getLeftTriggerButtonPressed() {
    return getRawButtonPressed(Button.kLeftTrigger.value);
  }

  /**
   * Whether the left trigger button was released since the last check.
   *
   * @return Whether the button was released since the last check.
   */
  public boolean getLeftTriggerButtonReleased() {
    return getRawButtonReleased(Button.kLeftTrigger.value);
  }

  /**
   * Constructs an event instance around the left trigger button's digital signal.
   *
   * @param loop the event loop instance to attach the event to.
   * @return an event instance representing the left trigger button's digital signal
   *     attached to the given loop.
   */
  public BooleanEvent leftTrigger(EventLoop loop) {
    return button(Button.kLeftTrigger.value, loop);
  }

  /**
   * Read the value of the google button on the controller.
   *
   * @return The state of the button.
   */
  public boolean getGoogleButton() {
    return getRawButton(Button.kGoogle.value);
  }

  /**
   * Whether the google button was pressed since the last check.
   *
   * @return Whether the button was pressed since the last check.
   */
  public boolean getGoogleButtonPressed() {
    return getRawButtonPressed(Button.kGoogle.value);
  }

  /**
   * Whether the google button was released since the last check.
   *
   * @return Whether the button was released since the last check.
   */
  public boolean getGoogleButtonReleased() {
    return getRawButtonReleased(Button.kGoogle.value);
  }

  /**
   * Constructs an event instance around the google button's digital signal.
   *
   * @param loop the event loop instance to attach the event to.
   * @return an event instance representing the google button's digital signal
   *     attached to the given loop.
   */
  public BooleanEvent google(EventLoop loop) {
    return button(Button.kGoogle.value, loop);
  }

  /**
   * Read the value of the frame button on the controller.
   *
   * @return The state of the button.
   */
  public boolean getFrameButton() {
    return getRawButton(Button.kFrame.value);
  }

  /**
   * Whether the frame button was pressed since the last check.
   *
   * @return Whether the button was pressed since the last check.
   */
  public boolean getFrameButtonPressed() {
    return getRawButtonPressed(Button.kFrame.value);
  }

  /**
   * Whether the frame button was released since the last check.
   *
   * @return Whether the button was released since the last check.
   */
  public boolean getFrameButtonReleased() {
    return getRawButtonReleased(Button.kFrame.value);
  }

  /**
   * Constructs an event instance around the frame button's digital signal.
   *
   * @param loop the event loop instance to attach the event to.
   * @return an event instance representing the frame button's digital signal
   *     attached to the given loop.
   */
  public BooleanEvent frame(EventLoop loop) {
    return button(Button.kFrame.value, loop);
  }

  /**
   * Read the value of the left bumper (LB) button on the controller.
   *
   * @return The state of the button.
   * @deprecated Use {@link getLeftBumperButton} instead. This function is deprecated for removal
   *     to make function names consistent to allow the HID classes to be automatically generated.
   */
  @Deprecated(since = "2025", forRemoval = true)
  public boolean getLeftBumper() {
    return getRawButton(Button.kLeftBumper.value);
  }

  /**
   * Read the value of the right bumper (RB) button on the controller.
   *
   * @return The state of the button.
   * @deprecated Use {@link getRightBumperButton} instead. This function is deprecated for removal
   *     to make function names consistent to allow the HID classes to be automatically generated.
   */
  @Deprecated(since = "2025", forRemoval = true)
  public boolean getRightBumper() {
    return getRawButton(Button.kRightBumper.value);
  }

  /**
   * Whether the left bumper (LB) was pressed since the last check.
   *
   * @return Whether the button was pressed since the last check.
   * @deprecated Use {@link getLeftBumperButtonPressed} instead. This function is deprecated for
   *     removal to make function names consistent to allow the HID classes to be automatically
   *     generated.
   */
  @Deprecated(since = "2025", forRemoval = true)
  public boolean getLeftBumperPressed() {
    return getRawButtonPressed(Button.kLeftBumper.value);
  }

  /**
   * Whether the right bumper (RB) was pressed since the last check.
   *
   * @return Whether the button was pressed since the last check.
   * @deprecated Use {@link getRightBumperButtonPressed} instead. This function is deprecated for
   *     removal to make function names consistent to allow the HID classes to be automatically
   *     generated.
   */
  @Deprecated(since = "2025", forRemoval = true)
  public boolean getRightBumperPressed() {
    return getRawButtonPressed(Button.kRightBumper.value);
  }

  /**
   * Whether the left bumper (LB) was released since the last check.
   *
   * @return Whether the button was released since the last check.
   * @deprecated Use {@link getLeftBumperButtonReleased} instead. This function is deprecated for
   *     removal to make function names consistent to allow the HID classes to be automatically
   *     generated.
   */
  @Deprecated(since = "2025", forRemoval = true)
  public boolean getLeftBumperReleased() {
    return getRawButtonReleased(Button.kLeftBumper.value);
  }

  /**
   * Whether the right bumper (RB) was released since the last check.
   *
   * @return Whether the button was released since the last check.
   * @deprecated Use {@link getRightBumperButtonReleased} instead. This function is deprecated for
   *     removal to make function names consistent to allow the HID classes to be automatically
   *     generated.
   */
  @Deprecated(since = "2025", forRemoval = true)
  public boolean getRightBumperReleased() {
    return getRawButtonReleased(Button.kRightBumper.value);
  }

  @Override
  public void initSendable(SendableBuilder builder) {
    builder.setSmartDashboardType("HID");
    builder.publishConstString("ControllerType", "Stadia");
    builder.addDoubleProperty("LeftX", this::getLeftX, null);
    builder.addDoubleProperty("RightX", this::getRightX, null);
    builder.addDoubleProperty("LeftY", this::getLeftY, null);
    builder.addDoubleProperty("RightY", this::getRightY, null);
    builder.addBooleanProperty("A", this::getAButton, null);
    builder.addBooleanProperty("B", this::getBButton, null);
    builder.addBooleanProperty("X", this::getXButton, null);
    builder.addBooleanProperty("Y", this::getYButton, null);
    builder.addBooleanProperty("LeftBumper", this::getLeftBumperButton, null);
    builder.addBooleanProperty("RightBumper", this::getRightBumperButton, null);
    builder.addBooleanProperty("LeftStick", this::getLeftStickButton, null);
    builder.addBooleanProperty("RightStick", this::getRightStickButton, null);
    builder.addBooleanProperty("Ellipses", this::getEllipsesButton, null);
    builder.addBooleanProperty("Hamburger", this::getHamburgerButton, null);
    builder.addBooleanProperty("Stadia", this::getStadiaButton, null);
    builder.addBooleanProperty("RightTrigger", this::getRightTriggerButton, null);
    builder.addBooleanProperty("LeftTrigger", this::getLeftTriggerButton, null);
    builder.addBooleanProperty("Google", this::getGoogleButton, null);
    builder.addBooleanProperty("Frame", this::getFrameButton, null);
  }
}
