# SPDX-License-Identifier: MIT
# Copyright (c) 2020 The Pybricks Authors

from typing import Iterable, List, Optional, Tuple, Union, overload

from .parameters import Button, Color, Direction, Stop, Port
from .media.ev3dev import SoundFile

class DCMotor:
    def __init__(
        self, port: Port, positive_direction: Direction = Direction.CLOCKWISE
    ): ...
    def dc(self, duty: int) -> None: ...
    def stop(self) -> None: ...
    def brake(self) -> None: ...

class Control:
    @overload
    def limits(self) -> Tuple[int, int, int]: ...
    @overload
    def limits(
        self,
        speed: Optional[int] = None,
        acceleration: Optional[int] = None,
        actuation: Optional[int] = None,
    ) -> None: ...
    def pid(self) -> Tuple[int, int, int, int, int, int]: ...
    @overload
    def pid(
        self,
        kp: Optional[int] = None,
        ki: Optional[int] = None,
        kd: Optional[int] = None,
        integral_range: Optional[int] = None,
        integral_rate: Optional[int] = None,
        feed_forward: Optional[int] = None,
    ) -> None: ...
    @overload
    def target_tolerances(self) -> Tuple[int, int]: ...
    @overload
    def target_tolerances(
        self, speed: Optional[int] = None, position: Optional[int] = None
    ) -> None: ...
    @overload
    def stall_tolerances(self) -> Tuple[int, int]: ...
    @overload
    def stall_tolerances(
        self, speed: Optional[int] = None, time: Optional[int] = None
    ) -> None: ...
    def trajectory(
        self,
    ) -> Tuple[int, int, int, int, int, int, int, int, int, int, int, int]: ...
    def stalled(self) -> bool: ...
    def done(self) -> bool: ...

class Motor(DCMotor):
    control: Control
    def __init__(
        self,
        port: Port,
        positive_direction: Direction = Direction.CLOCKWISE,
        gears: Optional[Union[List[int], List[List[int]]]] = None,
    ): ...
    def angle(self) -> int: ...
    def speed(self) -> int: ...
    def reset_angle(self, angle: int) -> None: ...
    def hold(self) -> None: ...
    def run(self, speed: int) -> None: ...
    def run_time(
        self, speed: int, time: int, then: Stop = Stop.HOLD, wait: bool = True
    ) -> None: ...
    def run_angle(
        self, speed: int, rotation_angle: int, then: Stop = Stop.HOLD, wait: bool = True
    ) -> None: ...
    def run_target(
        self, speed: int, target_angle: int, then: Stop = Stop.HOLD, wait: bool = True
    ) -> None: ...
    def run_until_stalled(
        self, speed: int, then: Stop = Stop.COAST, duty_limit: Optional[int] = None
    ) -> int: ...
    def track_target(self, target_angle: int) -> None: ...

class Speaker:
    def beep(self, frequency: int = 500, duration: int = 100) -> None: ...
    def play_notes(self, notes: Iterable[str], tempo: int = 120) -> None: ...
    def play_file(self, file_name: Union[SoundFile, str]) -> None: ...
    def say(self, text: str) -> None: ...
    def set_speech_options(
        self,
        language: Optional[str] = None,
        voice: Optional[str] = None,
        speed: Optional[int] = None,
        pitch: Optional[int] = None,
    ): ...
    def set_volume(self, volume: int, which: str = "_all_") -> None: ...

class Light:
    def on(self, brightness: int = 100) -> None: ...
    def off(self) -> None: ...

class ColorLight:
    def on(self, color: Optional[Color]) -> None: ...
    def off(self) -> None: ...
    def rgb(self, red: int, green: int, blue: int) -> None: ...

class KeyPad:
    def pressed(self) -> List[Button]:...

class Battery:
    def voltage(self) -> int: ...
    def current(self) -> int: ...
