from collections.abc import Iterator, Sequence
from typing import Self


class DefaultColor:
    """The default foreground or background color."""
    Foreground: DefaultColor = ...
    Background: DefaultColor = ...

    def name(self) -> str: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __gt__(self, other: object) -> bool: ...
    def __ge__(self, other: object) -> bool: ...
    def __lt__(self, other: object) -> bool: ...
    def __le__(self, other: object) -> bool: ...


class AnsiColor:
    """
    The 16 extended ANSI colors.

    The ANSI color comprise eight base colors and their eight bright versions.
    Unlike most other colors, the ANSI colors have no intrinsic color values and
    hence are abstract colors. At the same time, they do have semantics.
    """
    Black: AnsiColor = ...
    Red: AnsiColor = ...
    Green: AnsiColor = ...
    Yellow: AnsiColor = ...
    Blue: AnsiColor = ...
    Magenta: AnsiColor = ...
    Cyan: AnsiColor = ...
    White: AnsiColor = ...
    BrightBlack: AnsiColor = ...
    BrightRed: AnsiColor = ...
    BrightGreen: AnsiColor = ...
    BrightYellow: AnsiColor = ...
    BrightBlue: AnsiColor = ...
    BrightMagenta: AnsiColor = ...
    BrightCyan: AnsiColor = ...
    BrightWhite: AnsiColor = ...

    @staticmethod
    def try_from_8bit(value: int) -> AnsiColor: ...
    def to_8bit(self) -> int: ...
    def is_gray(self) -> bool: ...
    def is_bright(self) -> bool: ...
    def to_3bit(self) -> AnsiColor: ...
    def name(self) -> str: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __gt__(self, other: object) -> bool: ...
    def __ge__(self, other: object) -> bool: ...
    def __lt__(self, other: object) -> bool: ...
    def __le__(self, other: object) -> bool: ...


class EmbeddedRgb:
    """The 6x6x6 RGB cube embedded in 8-bit color."""
    def __new__(cls, r: int, g: int, b:int) -> Self: ...
    @staticmethod
    def try_from_8bit(value: int) -> EmbeddedRgb: ...
    def to_8bit(self) -> int: ...
    def to_24bit(self) -> list[int]: ...
    def to_color(self) -> Color: ...
    def coordinates(self) -> list[int]: ...
    def __len__(self) -> int: ...
    def __getitem__(self, index: int) -> int: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __repr__(self) -> str: ...


class GrayGradient:
    """The 24-step gray gradient embedded in 8-bit color."""
    def __new__(cls, value: int) -> Self: ...
    @staticmethod
    def try_from_8bit(value: int) -> GrayGradient: ...
    def to_8bit(self) -> int: ...
    def to_24bit(self) -> list[int]: ...
    def to_color(self) -> Color: ...
    def level(self) -> int: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __gt__(self, other: object) -> bool: ...
    def __ge__(self, other: object) -> bool: ...
    def __lt__(self, other: object) -> bool: ...
    def __le__(self, other: object) -> bool: ...
    def __repr__(self) -> str: ...


class TrueColor:
    """24-bit RGB colors."""
    def __new__(cls, r: int, g: int, b: int) -> Self: ...
    @staticmethod
    def from_color(color: Color) -> TrueColor: ...
    def to_color(self) -> Color: ...
    def coordinates(self) -> list[int]: ...
    def __len__(self) -> int: ...
    def __getitem__(self, index: int) -> int: ...
    def weighted_euclidian_distance(self, other: TrueColor) -> int: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __repr__(self) -> str: ...
    def __str__(self) -> str: ...


class TerminalColor_Default(TerminalColor):
    """The default foreground and background colors."""
    def __new__(cls, color: DefaultColor) -> Self: ...
    @property
    def color(self) -> DefaultColor: ...


class TerminalColor_Ansi(TerminalColor):
    """The 16 extended ANSI colors."""
    def __new__(cls, color: AnsiColor) -> Self: ...
    @property
    def color(self) -> AnsiColor: ...


class TerminalColor_Rgb6(TerminalColor):
    """The 6x6x6 RGB cube embedded in 8-bit colors."""
    def __new__(cls, color: EmbeddedRgb) -> Self: ...
    @property
    def color(self) -> EmbeddedRgb: ...


class TerminalColor_Gray(TerminalColor):
    """The gray gradient embedded in 8-bit colors."""
    def __new__(cls, color: GrayGradient) -> Self: ...
    @property
    def color(self) -> GrayGradient: ...


class TerminalColor_Rgb256(TerminalColor):
    """24-bit RGB colors."""
    def __new__(cls, color: TrueColor) -> Self: ...
    @property
    def color(self) -> TrueColor: ...


class TerminalColor:
    """Terminal colors."""
    Default = TerminalColor_Default
    Ansi = TerminalColor_Ansi
    Rgb6 = TerminalColor_Rgb6
    Gray = TerminalColor_Gray
    Rgb256 = TerminalColor_Rgb256

    @staticmethod
    def from_8bit(color: int) -> TerminalColor: ...
    @staticmethod
    def from_24bit(r: int, g: int, b: int) -> TerminalColor: ...
    @staticmethod
    def from_color(color: Color) -> TerminalColor: ...
    def try_to_8bit(self) -> int: ...
    def try_to_24bit(self) -> list[int]: ...
    def is_default(self) -> bool: ...
    def sgr_parameters(self, layer: Layer) -> list[int]: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __repr__(self) -> str: ...


class Fidelity:
    """
    Levels of support for ANSI escape codes and colors.
    """
    Plain: Fidelity = ...
    NoColor: Fidelity = ...
    Ansi: Fidelity = ...
    EightBit: Fidelity = ...
    Full: Fidelity = ...

    @staticmethod
    def from_color(color: TerminalColor) -> Fidelity: ...
    @staticmethod
    def from_environment(has_tty: bool) -> Fidelity: ...

    def __hash__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __gt__(self, other: object) -> bool: ...
    def __ge__(self, other: object) -> bool: ...
    def __lt__(self, other: object) -> bool: ...
    def __le__(self, other: object) -> bool: ...
    def __str__(self) -> str: ...


class Layer:
    """The render layer."""
    Foreground: Layer = ...
    Background: Layer = ...

    def offset(self) -> int: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __str__(self) -> str: ...


class ColorSpace:
    """A color space."""
    Srgb: ColorSpace = ...
    LinearSrgb: ColorSpace = ...
    DisplayP3: ColorSpace = ...
    LinearDisplayP3: ColorSpace = ...
    Rec2020: ColorSpace = ...
    LinearRec2020: ColorSpace = ...
    Oklab: ColorSpace = ...
    Oklch: ColorSpace = ...
    Oklrab: ColorSpace = ...
    Oklrch: ColorSpace = ...
    Xyz: ColorSpace = ...

    def is_rgb(self) -> bool: ...
    def is_polar(self) -> bool: ...
    def is_ok(self) -> bool: ...
    def is_bounded(self) -> bool: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __str__(self) -> str: ...


class HueInterpolation:
    """The rule for deciding how to interpolate hues."""
    Shorter: HueInterpolation = ...
    Longer: HueInterpolation = ...
    Increasing: HueInterpolation = ...
    Decreasing: HueInterpolation = ...

    def __hash__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...


class OkVersion:
    """The version of the Oklab color space."""
    Original: OkVersion = ...
    Revised: OkVersion = ...

    def cartesian_space(self) -> ColorSpace: ...
    def polar_space(self) -> ColorSpace: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...


class Color:
    """High-resolution colors."""
    def __new__(
        cls, space: ColorSpace, coordinates: Sequence[float]
    ) -> Self:
        """
        Create a new color with the color space and coordinates. The coordinates
        must be a sequence with exactly three elements.
        """
    @staticmethod
    def parse(s: str) -> Color: ...
    @staticmethod
    def srgb(r: float, g: float, b: float) -> Color: ...
    @staticmethod
    def p3(r: float, g: float, b: float) -> Color: ...
    @staticmethod
    def oklab(l: float, a: float, b: float) -> Color: ...
    @staticmethod
    def oklrab(lr: float, a: float, b: float) -> Color: ...
    @staticmethod
    def oklch(l: float, c: float, h: float) -> Color: ...
    @staticmethod
    def oklrch(lr: float, c: float, h: float) -> Color: ...
    @staticmethod
    def from_24bit(r: int, g: int, b: int) -> Color: ...
    def is_default(self) -> bool: ...
    def is_gray(self) -> bool: ...
    def space(self) -> ColorSpace: ...
    def coordinates(self) -> list[float]: ...
    def normalize(self) -> Self: ...
    def to(self, target: ColorSpace) -> Self: ...
    def in_gamut(self) -> bool: ...
    def clip(self) -> Self: ...
    def to_gamut(self) -> Self: ...
    def distance(self, other: Self, version: OkVersion) -> float: ...
    def interpolate(
        self,
        color: Self,
        interpolation_space: ColorSpace,
        interpolation_strategy: HueInterpolation,
    ) -> Interpolator: ...
    def lighten(self, factor: float) -> Self: ...
    def darken(self, factor: float) -> Self: ...
    def contrast_against(self, background: Self) -> float: ...
    def use_black_text(self) -> bool: ...
    def use_black_background(self) -> bool: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __len__(self) -> int: ...
    def __getitem__(self, index: int) -> float: ...
    def __repr__(self) -> str: ...
    def __str__(self) -> str: ...
    def to_24bit(self) -> list[int]: ...
    def to_hex_format(self) -> str: ...


class Interpolator:
    """A color interpolator."""
    def __new__(
        cls,
        color1: Color,
        color2: Color,
        space: ColorSpace,
        strategy: HueInterpolation
    ) -> Self: ...
    def at(self, fraction: float) -> Color: ...


class ThemeEntry_Default(ThemeEntry):
    """A theme entry for one of the default colors."""
    def __new__(cls, color: DefaultColor) -> Self: ...


class ThemeEntry_Ansi(ThemeEntry):
    """A theme entry for one of the ANSI colors."""
    def __new__(cls, color: AnsiColor) -> Self: ...


class ThemeEntry:
    """The 18 colors in a theme."""
    Default = ThemeEntry_Default
    Ansi = ThemeEntry_Ansi

    @staticmethod
    def try_from_index(index: int) -> ThemeEntry: ...
    def name(self) -> str: ...
    def __hash__(self) -> int: ...
    def __eq__(self, other: object) -> bool: ...
    def __ne__(self, other: object) -> bool: ...
    def __gt__(self, other: object) -> bool: ...
    def __ge__(self, other: object) -> bool: ...
    def __lt__(self, other: object) -> bool: ...
    def __le__(self, other: object) -> bool: ...


class ThemeEntryIterator:
    """An iterator over theme entries."""
    def __iter__(self) -> Self: ...
    def __next__(self) -> None | ThemeEntry: ...


class Sampler:
    """A color sampler for translating between terminal and high-resolution colors."""
    @staticmethod
    def theme_entries() -> Iterator[ThemeEntry]: ...
    def __new__(cls, version: OkVersion, theme_colors: Sequence[Color]) -> Self: ...
    def __repr__(self) -> str: ...

    """Interrogate color theme."""
    def is_dark_theme(self) -> bool: ...

    """Translate to high-resolution colors."""
    def resolve(
        self,
        color: TerminalColor|DefaultColor|AnsiColor|EmbeddedRgb|GrayGradient|TrueColor|int,
    ) -> Color: ...

    """Translate to ANSI colors."""
    def to_ansi(self, color: Color) -> Color:
        """
        Translate high-resolution to ANSI colors using the best available
        algorithm.
        """
    def supports_hue_lightness(self) -> bool: ...
    def to_ansi_hue_lightness(self, color: Color) -> None | AnsiColor: ...
    def to_closest_ansi(self, color: Color) -> AnsiColor: ...
    def to_ansi_rgb(self, color: Color) -> AnsiColor: ...

    """Translate to 8-bit colors."""
    def to_closest_8bit(self, color: Color) -> TerminalColor: ...
    def to_closest_8bit_with_ansi(self, color: Color) -> TerminalColor: ...

    """Cap terminal colors."""
    def cap(
        self,
        color: TerminalColor|DefaultColor|AnsiColor|EmbeddedRgb|GrayGradient|TrueColor|int,
        fidelity: Fidelity
    ) -> None | TerminalColor: ...


def close_enough(f1: float, f2: float) -> bool: ...
