#-----------------------------------------------------------------------------
# Copyright (c) Anaconda, Inc., and Bokeh Contributors.
# All rights reserved.
#
# The full license is in the file LICENSE.txt, distributed with this software.
#-----------------------------------------------------------------------------

# Standard library imports
from dataclasses import dataclass

# Bokeh imports
from .._specs import (
    AngleSpec,
    DataSpec,
    DistanceSpec,
    FloatSpec,
    MarkerSpec,
    NullDistanceSpec,
    NumberSpec,
    SizeSpec,
    StringSpec,
)
from .._types import NonNegative
from ..core.enums import (
    DirectionType as Direction,
    HexTileOrientationType as HexTileOrientation,
    ImageOriginType as ImageOrigin,
    OutlineShapeNameType as OutlineShapeName,
    PaletteType as Palette,
    RadiusDimensionType as RadiusDimension,
    StepModeType as StepMode,
    TeXDisplayType as TeXDisplay,
)
from ..core.has_props import abstract
from ..core.property_aliases import (
    Anchor,
    BorderRadius,
    Padding,
    TextAnchor,
)
from ..core.property_mixins import (
    BackgroundFillProps,
    BackgroundHatchProps,
    BorderLineProps,
    FillProps,
    HatchProps,
    ImageProps,
    LineProps,
    ScalarFillProps,
    ScalarHatchProps,
    ScalarLineProps,
    TextProps,
)
from .callbacks import CustomJS
from .glyph import (
    ConnectedXYGlyph,
    Glyph,
    RadialGlyph,
    XYGlyph,
)
from .mappers import ColorMapper, StackColorMapper

@abstract
@dataclass(init=False)
class Marker(XYGlyph, LineProps, FillProps, HatchProps):

    x: NumberSpec = ...

    y: NumberSpec = ...

    hit_dilation: NonNegative[float] = ...

    size: SizeSpec = ...

    angle: AngleSpec = ...

@abstract
@dataclass(init=False)
class LRTBGlyph(Glyph, LineProps, FillProps, HatchProps):

    border_radius: BorderRadius = ...

@dataclass
class AnnularWedge(XYGlyph, LineProps, FillProps, HatchProps):

    x: NumberSpec = ...

    y: NumberSpec = ...

    inner_radius: DistanceSpec = ...

    outer_radius: DistanceSpec = ...

    start_angle: AngleSpec = ...

    end_angle: AngleSpec = ...

    direction: Direction = ...

@dataclass
class Annulus(XYGlyph, LineProps, FillProps, HatchProps):

    x: NumberSpec = ...

    y: NumberSpec = ...

    inner_radius: DistanceSpec = ...

    outer_radius: DistanceSpec = ...

@dataclass
class Arc(XYGlyph, LineProps):

    x: NumberSpec = ...

    y: NumberSpec = ...

    radius: DistanceSpec = ...

    start_angle: AngleSpec = ...

    end_angle: AngleSpec = ...

    direction: Direction = ...

@dataclass
class Bezier(Glyph, LineProps):

    x0: NumberSpec = ...

    y0: NumberSpec = ...

    x1: NumberSpec = ...

    y1: NumberSpec = ...

    cx0: NumberSpec = ...

    cy0: NumberSpec = ...

    cx1: NumberSpec = ...

    cy1: NumberSpec = ...

@dataclass
class Block(LRTBGlyph):

    x: NumberSpec = ...

    y: NumberSpec = ...

    width: DistanceSpec = ...

    height: DistanceSpec = ...

@dataclass
class Circle(RadialGlyph, LineProps, FillProps, HatchProps):

    x: NumberSpec = ...

    y: NumberSpec = ...

    radius: DistanceSpec = ...

    radius_dimension: RadiusDimension = ...

    hit_dilation: NonNegative[float] = ...

@dataclass
class Ellipse(XYGlyph, LineProps, FillProps, HatchProps):

    x: NumberSpec = ...

    y: NumberSpec = ...

    width: DistanceSpec = ...

    height: DistanceSpec = ...

    angle: AngleSpec = ...

@dataclass
class HArea(Glyph, ScalarFillProps, HatchProps):

    x1: NumberSpec = ...

    x2: NumberSpec = ...

    y: NumberSpec = ...

@dataclass
class HAreaStep(Glyph, ScalarFillProps, HatchProps):

    x1: NumberSpec = ...

    x2: NumberSpec = ...

    y: NumberSpec = ...

    step_mode: StepMode = ...

@dataclass
class HBar(LRTBGlyph):

    y: NumberSpec = ...

    height: DistanceSpec = ...

    left: NumberSpec = ...

    right: NumberSpec = ...

@dataclass
class HSpan(Glyph, LineProps):

    y: NumberSpec = ...

@dataclass
class HStrip(Glyph, LineProps, FillProps, HatchProps):

    y0: NumberSpec = ...

    y1: NumberSpec = ...

@dataclass
class HexTile(Glyph, LineProps, FillProps, HatchProps):

    size: float = ...

    aspect_scale: float = ...

    r: NumberSpec = ...

    q: NumberSpec = ...

    scale: NumberSpec = ...

    orientation: HexTileOrientation = ...

@abstract
@dataclass(init=False)
class ImageBase(XYGlyph, ImageProps):

    x: NumberSpec = ...

    y: NumberSpec = ...

    dw: DistanceSpec = ...

    dh: DistanceSpec = ...

    dilate: bool = ...

    origin: ImageOrigin = ...

    anchor: Anchor = ...

@dataclass
class Image(ImageBase):

    image: NumberSpec = ...

    color_mapper: ColorMapper | Palette = ...

@dataclass
class ImageRGBA(ImageBase):

    image: NumberSpec = ...

@dataclass
class ImageStack(ImageBase):

    image: NumberSpec = ...

    color_mapper: StackColorMapper = ...

@dataclass
class ImageURL(XYGlyph):

    url: StringSpec = ...

    x: NumberSpec = ...

    y: NumberSpec = ...

    w: NullDistanceSpec = ...

    h: NullDistanceSpec = ...

    angle: AngleSpec = ...

    global_alpha: NumberSpec = ...

    dilate: bool = ...

    anchor: Anchor = ...

    retry_attempts: int = ...

    retry_timeout: int = ...

@dataclass
class Line(ConnectedXYGlyph, ScalarLineProps):

    x: NumberSpec = ...

    y: NumberSpec = ...

@dataclass
class MultiLine(Glyph, LineProps):

    xs: NumberSpec = ...

    ys: NumberSpec = ...

@dataclass
class MultiPolygons(Glyph, LineProps, FillProps, HatchProps):

    xs: NumberSpec = ...

    ys: NumberSpec = ...

@dataclass
class Ngon(RadialGlyph, LineProps, FillProps, HatchProps):

    x: NumberSpec = ...

    y: NumberSpec = ...

    radius: DistanceSpec = ...

    angle: AngleSpec = ...

    n: NumberSpec = ...

    radius_dimension: RadiusDimension = ...

@dataclass
class Patch(ConnectedXYGlyph, ScalarLineProps, ScalarFillProps, ScalarHatchProps):

    x: NumberSpec = ...

    y: NumberSpec = ...

@dataclass
class Patches(Glyph, LineProps, FillProps, HatchProps):

    xs: NumberSpec = ...

    ys: NumberSpec = ...

@dataclass
class Quad(LRTBGlyph):

    left: NumberSpec = ...

    right: NumberSpec = ...

    bottom: NumberSpec = ...

    top: NumberSpec = ...

@dataclass
class Quadratic(Glyph, LineProps):

    x0: NumberSpec = ...

    y0: NumberSpec = ...

    x1: NumberSpec = ...

    y1: NumberSpec = ...

    cx: NumberSpec = ...

    cy: NumberSpec = ...

@dataclass
class Ray(XYGlyph, LineProps):

    x: NumberSpec = ...

    y: NumberSpec = ...

    angle: AngleSpec = ...

    length: DistanceSpec = ...

@dataclass
class Rect(XYGlyph, LineProps, FillProps, HatchProps):

    x: NumberSpec = ...

    y: NumberSpec = ...

    width: DistanceSpec = ...

    height: DistanceSpec = ...

    angle: AngleSpec = ...

    border_radius: BorderRadius = ...

    dilate: bool = ...

@dataclass
class Scatter(Marker):

    marker: MarkerSpec = ...

    defs: dict[str, CustomJS] = ...

@dataclass
class Segment(Glyph, LineProps):

    x0: NumberSpec = ...

    y0: NumberSpec = ...

    x1: NumberSpec = ...

    y1: NumberSpec = ...

@dataclass
class Step(XYGlyph, ScalarLineProps):

    x: NumberSpec = ...

    y: NumberSpec = ...

    mode: StepMode = ...

    pad_before: float = ...

    pad_after: float = ...

@dataclass
class Text(XYGlyph, TextProps, BackgroundFillProps, BackgroundHatchProps, BorderLineProps):

    x: NumberSpec = ...

    y: NumberSpec = ...

    text: StringSpec = ...

    angle: AngleSpec = ...

    x_offset: FloatSpec = ...

    y_offset: FloatSpec = ...

    anchor: DataSpec[TextAnchor] = ...

    padding: Padding = ...

    border_radius: BorderRadius = ...

    outline_shape: DataSpec[OutlineShapeName] = ...

@abstract
@dataclass(init=False)
class MathTextGlyph(Text):
    ...

@dataclass
class MathMLGlyph(MathTextGlyph):
    ...

@dataclass
class TeXGlyph(MathTextGlyph):

    macros: dict[str, str | tuple[str, int]] = ...

    display: TeXDisplay = ...

@dataclass
class VArea(Glyph, ScalarFillProps, HatchProps):

    x: NumberSpec = ...

    y1: NumberSpec = ...

    y2: NumberSpec = ...

@dataclass
class VAreaStep(Glyph, ScalarFillProps, HatchProps):

    x: NumberSpec = ...

    y1: NumberSpec = ...

    y2: NumberSpec = ...

    step_mode: StepMode = ...

@dataclass
class VBar(LRTBGlyph):

    x: NumberSpec = ...

    width: DistanceSpec = ...

    bottom: NumberSpec = ...

    top: NumberSpec = ...

@dataclass
class VSpan(Glyph, LineProps):

    x: NumberSpec = ...

@dataclass
class VStrip(Glyph, LineProps, FillProps, HatchProps):

    x0: NumberSpec = ...

    x1: NumberSpec = ...

@dataclass
class Wedge(XYGlyph, LineProps, FillProps, HatchProps):

    x: NumberSpec = ...

    y: NumberSpec = ...

    radius: DistanceSpec = ...

    start_angle: AngleSpec = ...

    end_angle: AngleSpec = ...

    direction: Direction = ...
