from collections.abc import Iterable
from typing import Any, Literal, Optional, Union, overload
from typing_extensions import deprecated  # added in 3.13

from pygame.bufferproxy import BufferProxy
from pygame.color import Color
from pygame.rect import FRect, Rect

from pygame.typing import (
    ColorLike,
    Point,
    RectLike,
    SequenceLike,
)

_ViewKind = Literal[
    "0",
    "1",
    "2",
    "3",
    b"0",
    b"1",
    b"2",
    b"3",
    "r",
    "g",
    "b",
    "a",
    "R",
    "G",
    "B",
    "A",
    b"r",
    b"g",
    b"b",
    b"a",
    b"R",
    b"G",
    b"B",
    b"A",
]

class Surface:
    _pixels_address: int
    @property
    def width(self) -> int: ...
    @property
    def height(self) -> int: ...
    @property
    def size(self) -> tuple[int, int]: ...
    @overload
    def __init__(
        self,
        size: Point,
        flags: int = 0,
        depth: int = 0,
        masks: Optional[ColorLike] = None,
    ) -> None: ...
    @overload
    def __init__(
        self,
        size: Point,
        flags: int = 0,
        surface: Surface = ...,
    ) -> None: ...
    def __copy__(self) -> Surface: ...
    def __deepcopy__(self, memo) -> Surface: ...
    def copy(self) -> Surface: ...
    def blit(
        self,
        source: Surface,
        dest: Union[Point, RectLike] = (0, 0),
        area: Optional[RectLike] = None,
        special_flags: int = 0,
    ) -> Rect: ...
    def blits(
        self,
        blit_SequenceLike: Iterable[
            Union[
                tuple[Surface, Union[Point, RectLike]],
                tuple[Surface, Union[Point, RectLike], Union[RectLike, int]],
                tuple[Surface, Union[Point, RectLike], RectLike, int],
            ]
        ],
        doreturn: Union[int, bool] = 1,
    ) -> Union[list[Rect], None]: ...
    def fblits(
        self,
        blit_SequenceLike: Iterable[tuple[Surface, Union[Point, RectLike]]],
        special_flags: int = 0, /
    ) -> None: ...
    @overload
    def convert(self, surface: Surface, /) -> Surface: ...
    @overload
    def convert(self, depth: int, flags: int = 0, /) -> Surface: ...
    @overload
    def convert(self, masks: ColorLike, flags: int = 0, /) -> Surface: ...
    @overload
    def convert(self) -> Surface: ...
    def convert_alpha(self) -> Surface: ...
    def fill(
        self,
        color: ColorLike,
        rect: Optional[RectLike] = None,
        special_flags: int = 0,
    ) -> Rect: ...
    def scroll(
        self, dx: int = 0, dy: int = 0, scroll_flag: int = 0, /
    ) -> None: ...
    @overload
    def set_colorkey(self, color: ColorLike, flags: int = 0, /) -> None: ...
    @overload
    def set_colorkey(self, color: None, /) -> None: ...
    def get_colorkey(self) -> Optional[tuple[int, int, int, int]]: ...
    @overload
    def set_alpha(self, value: int, flags: int = 0, /) -> None: ...
    @overload
    def set_alpha(self, value: None, /) -> None: ...
    def get_alpha(self) -> Optional[int]: ...
    def lock(self) -> None: ...
    def unlock(self) -> None: ...
    def mustlock(self) -> bool: ...
    def get_locked(self) -> bool: ...
    def get_locks(self) -> tuple[Any, ...]: ...
    def get_at(self, x_y: Point, /) -> Color: ...
    def set_at(self, x_y: Point, color: ColorLike, /) -> None: ...
    def get_at_mapped(self, x_y: Point, /) -> int: ...
    def get_palette(self) -> list[Color]: ...
    def get_palette_at(self, index: int, /) -> Color: ...
    def set_palette(self, palette: SequenceLike[ColorLike], /) -> None: ...
    def set_palette_at(self, index: int, color: ColorLike, /) -> None: ...
    def map_rgb(self, color: ColorLike, /) -> int: ...
    def unmap_rgb(self, mapped_int: int, /) -> Color: ...
    def set_clip(self, rect: Optional[RectLike], /) -> None: ...
    def get_clip(self) -> Rect: ...
    @overload
    def subsurface(self, rect: RectLike, /) -> Surface: ...
    @overload
    def subsurface(self, left_top: Point, width_height: Point, /) -> Surface: ...
    @overload
    def subsurface(
        self, left: float, top: float, width: float, height: float, /
    ) -> Surface: ...
    def get_parent(self) -> Surface: ...
    def get_abs_parent(self) -> Surface: ...
    def get_offset(self) -> tuple[int, int]: ...
    def get_abs_offset(self) -> tuple[int, int]: ...
    def get_size(self) -> tuple[int, int]: ...
    def get_width(self) -> int: ...
    def get_height(self) -> int: ...
    def get_rect(self, **kwargs: Any) -> Rect: ...
    def get_frect(self, **kwargs: Any) -> FRect: ...
    def get_bitsize(self) -> int: ...
    def get_bytesize(self) -> int: ...
    def get_flags(self) -> int: ...
    def get_pitch(self) -> int: ...
    def get_masks(self) -> tuple[int, int, int, int]: ...
    @deprecated("since 2.0.0. Immutable in SDL2")
    def set_masks(self, color: ColorLike, /) -> None: ...
    def get_shifts(self) -> tuple[int, int, int, int]: ...
    @deprecated("since 2.0.0. Immutable in SDL2")
    def set_shifts(self, color: ColorLike, /) -> None: ...
    def get_losses(self) -> tuple[int, int, int, int]: ...
    def get_bounding_rect(self, min_alpha: int = 1) -> Rect: ...
    def get_view(self, kind: _ViewKind = "2", /) -> BufferProxy: ...
    def get_buffer(self) -> BufferProxy: ...
    def get_blendmode(self) -> int: ...
    def premul_alpha(self) -> Surface: ...
    def premul_alpha_ip(self) -> Surface: ...

@deprecated("Use `Surface` instead (SurfaceType is an old alias)")
class SurfaceType(Surface): ...
