from abc import ABC, abstractmethod
from typing import Literal

from pygame.surface import Surface
from pygame.typing import IntPoint

def get_backends() -> list[str]: ...
def init(backend: str | None = None) -> None: ...
def quit() -> None: ...
def list_cameras() -> list[str] | list[int]: ...
def colorspace(
    surface: Surface, color: Literal["YUV", "HSV"], dest_surface: Surface = ..., /
) -> Surface: ...

class AbstractCamera(ABC):
    @abstractmethod
    def __init__(self, *args, **kwargs) -> None: ...
    @abstractmethod
    def start(self) -> None: ...
    @abstractmethod
    def stop(self) -> None: ...
    @abstractmethod
    def get_size(self) -> tuple[int, int]: ...
    @abstractmethod
    def query_image(self) -> bool: ...
    @abstractmethod
    def get_image(self, dest_surf: Surface | None = None) -> Surface: ...
    @abstractmethod
    def get_raw(self) -> bytes: ...
    # set_controls and get_controls are not a part of the AbstractCamera ABC,
    # because implementations of the same can vary across different Camera
    # types

class Camera(AbstractCamera):
    def __init__(
        self,
        device: str | int,
        size: IntPoint = (640, 480),
        format: str = "RGB",
    ) -> None: ...
    def start(self) -> None: ...
    def stop(self) -> None: ...
    def get_controls(self) -> tuple[bool, bool, int]: ...
    def set_controls(
        self,
        hflip: bool = ...,
        vflip: bool = ...,
        brightness: int = ...,
    ) -> tuple[bool, bool, int]: ...
    def get_size(self) -> tuple[int, int]: ...
    def query_image(self) -> bool: ...
    def get_image(self, surface: Surface | None = None) -> Surface: ...
    def get_raw(self) -> bytes: ...
