from .artist import Artist
from .backend_bases import RendererBase
from .font_manager import FontProperties
from .offsetbox import DraggableAnnotation
from .path import Path
from .patches import FancyArrowPatch, FancyBboxPatch
from .textpath import (  # noqa: reexported API
    TextPath as TextPath,
    TextToPath as TextToPath,
)
from .transforms import (
    Bbox,
    BboxBase,
    Transform,
)

from collections.abc import Callable, Iterable
from typing import Any, Literal
from .typing import ColorType

class Text(Artist):
    zorder: float
    def __init__(
        self,
        x: float = ...,
        y: float = ...,
        text: Any = ...,
        *,
        color: ColorType | None = ...,
        verticalalignment: Literal[
            "bottom", "baseline", "center", "center_baseline", "top"
        ] = ...,
        horizontalalignment: Literal["left", "center", "right"] = ...,
        multialignment: Literal["left", "center", "right"] | None = ...,
        fontproperties: str | Path | FontProperties | None = ...,
        rotation: float | Literal["vertical", "horizontal"] | None = ...,
        linespacing: float | None = ...,
        rotation_mode: Literal["default", "anchor"] | None = ...,
        usetex: bool | None = ...,
        wrap: bool = ...,
        transform_rotates_text: bool = ...,
        parse_math: bool | None = ...,
        antialiased: bool | None = ...,
        **kwargs
    ) -> None: ...
    def update(self, kwargs: dict[str, Any]) -> list[Any]: ...
    def get_rotation(self) -> float: ...
    def get_transform_rotates_text(self) -> bool: ...
    def set_rotation_mode(self, m: None | Literal["default", "anchor"]) -> None: ...
    def get_rotation_mode(self) -> Literal["default", "anchor"]: ...
    def set_bbox(self, rectprops: dict[str, Any]) -> None: ...
    def get_bbox_patch(self) -> None | FancyBboxPatch: ...
    def update_bbox_position_size(self, renderer: RendererBase) -> None: ...
    def get_wrap(self) -> bool: ...
    def set_wrap(self, wrap: bool) -> None: ...
    def get_color(self) -> ColorType: ...
    def get_fontproperties(self) -> FontProperties: ...
    def get_fontfamily(self) -> list[str]: ...
    def get_fontname(self) -> str: ...
    def get_fontstyle(self) -> Literal["normal", "italic", "oblique"]: ...
    def get_fontsize(self) -> float | str: ...
    def get_fontvariant(self) -> Literal["normal", "small-caps"]: ...
    def get_fontweight(self) -> int | str: ...
    def get_stretch(self) -> int | str: ...
    def get_horizontalalignment(self) -> Literal["left", "center", "right"]: ...
    def get_unitless_position(self) -> tuple[float, float]: ...
    def get_position(self) -> tuple[float, float]: ...
    def get_text(self) -> str: ...
    def get_verticalalignment(
        self,
    ) -> Literal["bottom", "baseline", "center", "center_baseline", "top"]: ...
    def get_window_extent(
        self, renderer: RendererBase | None = ..., dpi: float | None = ...
    ) -> Bbox: ...
    def set_backgroundcolor(self, color: ColorType) -> None: ...
    def set_color(self, color: ColorType) -> None: ...
    def set_horizontalalignment(
        self, align: Literal["left", "center", "right"]
    ) -> None: ...
    def set_multialignment(self, align: Literal["left", "center", "right"]) -> None: ...
    def set_linespacing(self, spacing: float) -> None: ...
    def set_fontfamily(self, fontname: str | Iterable[str]) -> None: ...
    def set_fontvariant(self, variant: Literal["normal", "small-caps"]) -> None: ...
    def set_fontstyle(
        self, fontstyle: Literal["normal", "italic", "oblique"]
    ) -> None: ...
    def set_fontsize(self, fontsize: float | str) -> None: ...
    def get_math_fontfamily(self) -> str: ...
    def set_math_fontfamily(self, fontfamily: str) -> None: ...
    def set_fontweight(self, weight: int | str) -> None: ...
    def set_fontstretch(self, stretch: int | str) -> None: ...
    def set_position(self, xy: tuple[float, float]) -> None: ...
    def set_x(self, x: float) -> None: ...
    def set_y(self, y: float) -> None: ...
    def set_rotation(self, s: float) -> None: ...
    def set_transform_rotates_text(self, t: bool) -> None: ...
    def set_verticalalignment(
        self, align: Literal["bottom", "baseline", "center", "center_baseline", "top"]
    ) -> None: ...
    def set_text(self, s: Any) -> None: ...
    def set_fontproperties(self, fp: FontProperties | str | Path | None) -> None: ...
    def set_usetex(self, usetex: bool | None) -> None: ...
    def get_usetex(self) -> bool: ...
    def set_parse_math(self, parse_math: bool) -> None: ...
    def get_parse_math(self) -> bool: ...
    def set_fontname(self, fontname: str | Iterable[str]) -> None: ...
    def get_antialiased(self) -> bool: ...
    def set_antialiased(self, antialiased: bool) -> None: ...

class OffsetFrom:
    def __init__(
        self,
        artist: Artist | BboxBase | Transform,
        ref_coord: tuple[float, float],
        unit: Literal["points", "pixels"] = ...,
    ) -> None: ...
    def set_unit(self, unit: Literal["points", "pixels"]) -> None: ...
    def get_unit(self) -> Literal["points", "pixels"]: ...
    def __call__(self, renderer: RendererBase) -> Transform: ...

class _AnnotationBase:
    xy: tuple[float, float]
    xycoords: str | tuple[str, str] | Artist | Transform | Callable[
        [RendererBase], Bbox | Transform
    ]
    def __init__(
        self,
        xy,
        xycoords: str
        | tuple[str, str]
        | Artist
        | Transform
        | Callable[[RendererBase], Bbox | Transform] = ...,
        annotation_clip: bool | None = ...,
    ) -> None: ...
    def set_annotation_clip(self, b: bool | None) -> None: ...
    def get_annotation_clip(self) -> bool | None: ...
    def draggable(
        self, state: bool | None = ..., use_blit: bool = ...
    ) -> DraggableAnnotation | None: ...

class Annotation(Text, _AnnotationBase):
    arrowprops: dict[str, Any] | None
    arrow_patch: FancyArrowPatch | None
    def __init__(
        self,
        text: str,
        xy: tuple[float, float],
        xytext: tuple[float, float] | None = ...,
        xycoords: str
        | tuple[str, str]
        | Artist
        | Transform
        | Callable[[RendererBase], Bbox | Transform] = ...,
        textcoords: str
        | tuple[str, str]
        | Artist
        | Transform
        | Callable[[RendererBase], Bbox | Transform]
        | None = ...,
        arrowprops: dict[str, Any] | None = ...,
        annotation_clip: bool | None = ...,
        **kwargs
    ) -> None: ...
    @property
    def xycoords(
        self,
    ) -> str | tuple[str, str] | Artist | Transform | Callable[
        [RendererBase], Bbox | Transform
    ]: ...
    @xycoords.setter
    def xycoords(
        self,
        xycoords: str
        | tuple[str, str]
        | Artist
        | Transform
        | Callable[[RendererBase], Bbox | Transform],
    ) -> None: ...
    @property
    def xyann(self) -> tuple[float, float]: ...
    @xyann.setter
    def xyann(self, xytext: tuple[float, float]) -> None: ...
    def get_anncoords(
        self,
    ) -> str | tuple[str, str] | Artist | Transform | Callable[
        [RendererBase], Bbox | Transform
    ]: ...
    def set_anncoords(
        self,
        coords: str
        | tuple[str, str]
        | Artist
        | Transform
        | Callable[[RendererBase], Bbox | Transform],
    ) -> None: ...
    @property
    def anncoords(
        self,
    ) -> str | tuple[str, str] | Artist | Transform | Callable[
        [RendererBase], Bbox | Transform
    ]: ...
    @anncoords.setter
    def anncoords(
        self,
        coords: str
        | tuple[str, str]
        | Artist
        | Transform
        | Callable[[RendererBase], Bbox | Transform],
    ) -> None: ...
    def update_positions(self, renderer: RendererBase) -> None: ...
    # Drops `dpi` parameter from superclass
    def get_window_extent(self, renderer: RendererBase | None = ...) -> Bbox: ...  # type: ignore[override]
