#-----------------------------------------------------------------------------
# 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
from typing import Sequence

# Bokeh imports
from ..._specs import CoordinateSpec
from ..._types import (
    Coordinate,
    CoordinateLike,
    NonNegative,
    Positive,
)
from ...core.enums import (
    CoordinateUnitsType as CoordinateUnits,
    DimensionType as Dimension,
    MovableType as Movable,
    ResizableType as Resizable,
)
from ...core.property_aliases import BorderRadius
from ...core.property_mixins import (
    LineProps,
    ScalarAboveFillProps,
    ScalarAboveHatchProps,
    ScalarBelowFillProps,
    ScalarBelowHatchProps,
    ScalarFillProps,
    ScalarHatchProps,
    ScalarHoverFillProps,
    ScalarHoverHatchProps,
    ScalarHoverLineProps,
    ScalarLineProps,
)
from ...model import Model
from ..nodes import BoxNodes
from .annotation import Annotation, DataAnnotation
from .arrows import ArrowHead

@dataclass
class AreaVisuals(Model, ScalarLineProps, ScalarFillProps, ScalarHatchProps,
                  ScalarHoverLineProps, ScalarHoverFillProps, ScalarHoverHatchProps):
    ...

@dataclass
class BoxInteractionHandles(Model):

    all: AreaVisuals = ...

    move: AreaVisuals | None = ...
    resize: AreaVisuals | None = ...

    sides: AreaVisuals | None = ...
    corners: AreaVisuals | None = ...

    left: AreaVisuals | None = ...
    right: AreaVisuals | None = ...
    top: AreaVisuals | None = ...
    bottom: AreaVisuals | None = ...

    top_left: AreaVisuals | None = ...
    top_right: AreaVisuals | None = ...
    bottom_left: AreaVisuals | None = ...
    bottom_right: AreaVisuals | None = ...

@dataclass
class BoxAnnotation(Annotation, AreaVisuals):

    left: Coordinate = ...

    right: Coordinate = ...

    top: Coordinate = ...

    bottom: Coordinate = ...

    left_units: CoordinateUnits = ...

    right_units: CoordinateUnits = ...

    top_units: CoordinateUnits = ...

    bottom_units: CoordinateUnits = ...

    left_limit: Coordinate | None = ...

    right_limit: Coordinate | None = ...

    top_limit: Coordinate | None = ...

    bottom_limit: Coordinate | None = ...

    min_width: NonNegative[float] = ...

    min_height: NonNegative[float] = ...

    max_width: Positive[float] = ...

    max_height: Positive[float] = ...

    border_radius: BorderRadius = ...

    editable: bool = ...

    resizable: Resizable = ...

    movable: Movable = ...

    symmetric: bool = ...

    use_handles: bool = ...

    handles: BoxInteractionHandles | AreaVisuals = ...

    inverted: bool = ...

    @property
    def nodes(self) -> BoxNodes: ...

@dataclass
class Band(DataAnnotation, ScalarLineProps, ScalarFillProps, ScalarHatchProps):

    lower: CoordinateSpec = ...

    upper: CoordinateSpec = ...

    base: CoordinateSpec = ...

    dimension: Dimension = ...

@dataclass
class PolyAnnotation(Annotation, ScalarLineProps, ScalarFillProps, ScalarHatchProps,
                     ScalarHoverLineProps, ScalarHoverFillProps, ScalarHoverHatchProps):

    xs: Sequence[CoordinateLike] = ...

    xs_units: CoordinateUnits = ...

    ys: Sequence[CoordinateLike] = ...

    ys_units: CoordinateUnits = ...

    editable: bool = ...

@dataclass
class Slope(Annotation, ScalarLineProps, ScalarAboveFillProps, ScalarAboveHatchProps, ScalarBelowFillProps, ScalarBelowHatchProps):

    gradient: float | None = ...

    y_intercept: float | None = ...

@dataclass
class Span(Annotation, ScalarLineProps, ScalarHoverLineProps):

    location: CoordinateLike | None = ...

    location_units: CoordinateUnits = ...

    dimension: Dimension = ...

    editable: bool = ...

@dataclass
class Whisker(DataAnnotation, LineProps ):

    lower: CoordinateSpec = ...

    lower_head: ArrowHead | None = ...

    upper: CoordinateSpec = ...

    upper_head: ArrowHead | None = ...

    base: CoordinateSpec = ...

    dimension: Dimension = ...
