from typing import Iterable, Union

import numpy as np
import numpy.typing as npt

Numerical = Union[float, int]

Numerical1D = Union[
    npt.NDArray[np.float32], # preferred
    npt.NDArray[np.float16],
    npt.NDArray[np.float64],
    npt.NDArray[np.int32], # preferred
    npt.NDArray[np.int8],
    npt.NDArray[np.int16],
    npt.NDArray[np.int64],
    Iterable[float],  # preferred
    Iterable[int],  # preferred
]

class ButtonPressedEvent:
    def get_pressed(self) -> bool: ...
    def get_pressed_toggle(self) -> bool: ...
    def get_double_pressed(self) -> bool: ...
    def get_long_pressed(self) -> bool: ...

    def poll_long_pressed(self) -> bool: ...

    def get_repeat_press_duration(self) -> Numerical: ...
    def get_long_press_duration(self) -> Numerical: ...
    def get_double_press_duration(self) -> Numerical: ...

    def set_repeat_press_duration(self, duration: Numerical) -> None: ...
    def set_double_press_duration(self, duration: Numerical) -> None: ...
    def set_long_press_duration(self, duration: Numerical) -> None: ...

class Controller:
    a_button: ButtonPressedEvent
    b_button: ButtonPressedEvent
    x_button: ButtonPressedEvent
    y_button: ButtonPressedEvent
    left_bumper_button: ButtonPressedEvent
    right_bumper_button: ButtonPressedEvent
    back_button: ButtonPressedEvent
    start_button: ButtonPressedEvent
    guide_button: ButtonPressedEvent
    left_thumb_button: ButtonPressedEvent
    right_thumb_button: ButtonPressedEvent
    dpad_up_button: ButtonPressedEvent
    dpad_down_button: ButtonPressedEvent
    dpad_left_button: ButtonPressedEvent
    dpad_right_button: ButtonPressedEvent

    def __init__(self, controller_id: int) -> None: ...

    def get_connected(self) -> bool: ...
    def get_active(self) -> bool: ...

    def get_raw_name(self) -> bool: ...
    def get_gamepad_name(self) -> bool: ...
    def get_GUID(self) -> bool: ...

    def get_axis_decimal(self, axis_id: int) -> Numerical: ...
    def get_axis_percentage(self, axis_id: int) -> Numerical: ...

    def get_raw_button_pressed(self, button_id: int) -> bool: ...

    def get_raw_hat_state(self, hat_id: int) -> str: ...

    def get_right_stick_X_axis_percentage(self) -> Numerical: ...
    def get_right_stick_Y_axis_percentage(self) -> Numerical: ...

    def get_right_stick_X_axis_decimal(self) -> Numerical: ...
    def get_right_stick_Y_axis_decimal(self) -> Numerical: ...

    def get_left_stick_X_axis_percentage(self) -> Numerical: ...
    def get_Left_stick_Y_axis_percentage(self) -> Numerical: ...

    def get_left_stick_X_axis_decimal(self) -> Numerical: ...
    def get_Left_stick_Y_axis_decimal(self) -> Numerical: ...

    def get_right_trigger_axis_percentage(self) -> Numerical: ...
    def get_left_trigger_axis_percentage(self) -> Numerical: ...

    def get_right_trigger_axis_decimal(self) -> Numerical: ...
    def get_left_trigger_axis_decimal(self) -> Numerical: ...

    def get_left_stick_position_percentage(self, dead_zone: float=0, using_numpy_arrays: bool=True) -> Numerical1D: ...
    def get_right_stick_position_percentage(self, dead_zone: float=0, using_numpy_arrays: bool=True) -> Numerical1D: ...

    def get_left_stick_position_decimal(self, dead_zone: float=0, using_numpy_arrays: bool=True) -> Numerical1D: ...
    def get_right_stick_position_decimal(self, dead_zone: float=0, using_numpy_arrays: bool=True) -> Numerical1D: ...