// 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 ./wpilibc/generate_hids.py. DO NOT MODIFY
{% macro capitalize_first(string) -%}
{{ string[0]|capitalize + string[1:] }}
{%- endmacro %}
#pragma once

#include "wpi/util/sendable/Sendable.hpp"
#include "wpi/util/sendable/SendableHelper.hpp"

#include "wpi/driverstation/GenericHID.hpp"

namespace wpi {

/**
 * Handle input from {{ ConsoleName }} controllers connected to the Driver Station.
 *
 * This class handles {{ ConsoleName }} 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.
 *
 * Only first party controllers from {{ Manufacturer }} 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.
 */
class {{ ConsoleName }}Controller : public GenericHID,
                                    public wpi::util::Sendable,
                                    public wpi::util::SendableHelper<{{ ConsoleName }}Controller> {
 public:
  /**
   * Construct an instance of a controller.
   *
   * The controller index is the USB port on the Driver Station.
   *
   * @param port The port on the Driver Station that the controller is plugged
   *             into (0-5).
   */
  explicit {{ ConsoleName }}Controller(int port);

  ~{{ ConsoleName }}Controller() override = default;

  {{ ConsoleName }}Controller({{ ConsoleName }}Controller&&) = default;
  {{ ConsoleName }}Controller& operator=({{ ConsoleName }}Controller&&) = default;
{% for stick in sticks %}
  /**
   * Get the {{ stick.NameParts[1] }} axis value of {{ stick.NameParts[0] }} side of the controller. {{ stick.PositiveDirection }} is positive.
   *
   * @return the axis value.
   */
  double Get{{ stick.NameParts|map("capitalize")|join }}() const;
{% endfor -%}
{% for trigger in triggers %}
  /**
   * Get the {{ trigger.DocName }} axis value of the controller. Note that this axis
   * is bound to the range of [0, 1] as opposed to the usual [-1, 1].
   *
   * @return the axis value.
   */
  double Get{{ capitalize_first(trigger.name) }}Axis() const;
{% if trigger.UseThresholdMethods %}
  /**
   * Constructs an event instance around the axis value of the {{ trigger.DocName }}.
   * The returned trigger will be true when the axis value is greater than
   * {@code threshold}.
   * @param threshold the minimum axis value for the returned event to be true.
   * This value should be in the range [0, 1] where 0 is the unpressed state of
   * the axis.
   * @param loop the event loop instance to attach the event to.
   * @return an event instance that is true when the {{ trigger.DocName }}'s axis
   * exceeds the provided threshold, attached to the given event loop
   */
  BooleanEvent {{ capitalize_first(trigger.name) }}(double threshold, EventLoop* loop) const;

  /**
   * Constructs an event instance around the axis value of the {{ trigger.DocName }}.
   * The returned trigger will be true when the axis value is greater than 0.5.
   * @param loop the event loop instance to attach the event to.
   * @return an event instance that is true when the {{ trigger.DocName }}'s axis
   * exceeds 0.5, attached to the given event loop
   */
  BooleanEvent {{ capitalize_first(trigger.name) }}(EventLoop* loop) const;
{% endif -%}
{% endfor -%}
{% for button in buttons %}
  /**
   * Read the value of the {{ button.DocName|default(button.name) }} button on the controller.
   *
   * @return The state of the button.
   */
  bool Get{{ capitalize_first(button.name) }}Button() const;

  /**
   * Whether the {{ button.DocName|default(button.name) }} button was pressed since the last check.
   *
   * @return Whether the button was pressed since the last check.
   */
  bool Get{{ capitalize_first(button.name) }}ButtonPressed();

  /**
   * Whether the {{ button.DocName|default(button.name) }} button was released since the last check.
   *
   * @return Whether the button was released since the last check.
   */
  bool Get{{ capitalize_first(button.name) }}ButtonReleased();

  /**
   * Constructs an event instance around the {{ button.DocName|default(button.name) }} button's
   * digital signal.
   *
   * @param loop the event loop instance to attach the event to.
   * @return an event instance representing the {{ button.DocName|default(button.name) }} button's
   * digital signal attached to the given loop.
   */
  BooleanEvent {{ capitalize_first(button.name) }}(EventLoop* loop) const;
{% endfor %}
  /** Represents a digital button on an {{ ConsoleName }}Controller. */
  struct Button {
{%- for button in buttons %}
    /// {{ capitalize_first(button.DocName|default(button.name)) }} button.
    static constexpr int k{{ capitalize_first(button.name) }} = {{ button.value }};
{%- endfor %}
  };

  /** Represents an axis on an {{ ConsoleName }}Controller. */
  struct Axis {
{%- for stick in sticks %}
    /// {{ stick.NameParts|map("capitalize")|join(" ") }} axis.
    static constexpr int k{{ stick.NameParts|map("capitalize")|join }} = {{ stick.value }};
{%- endfor %}
{%- for trigger in triggers %}
    /// {{ trigger.DocName|capitalize }}.
    static constexpr int k{{ capitalize_first(trigger.name) }} = {{ trigger.value }};
{%- endfor %}
  };

  void InitSendable(wpi::util::SendableBuilder& builder) override;
};

}  // namespace wpi
