#-----------------------------------------------------------------------------
# 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 Literal, Sequence, TypeAlias

# Bokeh imports
from ..._specs import NullStringSpec
from ..._types import CoordinateLike, TextLike
from ...core.enums import (
    AlignType as Align,
    AlternationPolicyType as AlternationPolicy,
    AnchorType as HVAlign,
    AutoType as Auto,
    HAlignType as HAlign,
    LegendClickPolicyType as LegendClickPolicy,
    LegendLocationType as LegendLocation,
    LocationType as Location,
    OrientationType as Orientation,
    VAlignType as VAlign,
)
from ...core.has_props import abstract
from ...core.property_aliases import AutoAnchor, BorderRadius, Padding
from ...core.property_mixins import (
    GlyphFillProps,
    GlyphHatchProps,
    GlyphLineProps,
    ScalarBackgroundFillProps,
    ScalarBackgroundHatchProps,
    ScalarBarLineProps,
    ScalarBorderLineProps,
    ScalarInactiveFillProps,
    ScalarItemBackgroundFillProps,
    ScalarLabelTextProps,
    ScalarMajorLabelTextProps,
    ScalarMajorTickLineProps,
    ScalarMinorTickLineProps,
    ScalarTitleTextProps,
)
from ...model import Model
from ...util.callback_manager import EventCallback as PyEventCallback
from ..callbacks import Callback as JsEventCallback
from ..formatters import TickFormatter
from ..glyph import Glyph, RadialGlyph
from ..labeling import LabelingPolicy
from ..mappers import ColorMapper
from ..ranges import Range
from ..renderers import GlyphRenderer
from ..tickers import Ticker
from .annotation import Annotation
from .dimensional import Dimensional

@abstract
@dataclass(init=False)
class BaseColorBar(Annotation, ScalarTitleTextProps, ScalarMajorLabelTextProps, ScalarMajorTickLineProps,
                   ScalarMinorTickLineProps, ScalarBarLineProps, ScalarBorderLineProps, ScalarBackgroundFillProps):

    location: HVAlign | tuple[float, float] = ...

    orientation: Orientation | Auto = ...

    height: Auto | int = ...

    width: Auto | int = ...

    title: TextLike | None = ...

    title_standoff: int = ...

    ticker: Ticker | Auto = ...

    formatter: TickFormatter | Auto = ...

    major_label_overrides: dict[float | str, TextLike] = ...

    major_label_policy: LabelingPolicy = ...

    margin: int = ...

    padding: int = ...

    label_standoff: int = ...

    major_tick_in: int = ...

    major_tick_out: int = ...

    minor_tick_in: int = ...

    minor_tick_out: int = ...

@dataclass
class ColorBar(BaseColorBar):

    color_mapper: ColorMapper = ...

    display_low: float | None = ...

    display_high: float | None = ...

    scale_alpha: float = ...

@dataclass
class ContourColorBar(BaseColorBar):

    fill_renderer: GlyphRenderer[Glyph] = ...

    line_renderer: GlyphRenderer[Glyph] = ...

    levels: Sequence[float] = ...

@dataclass
class LegendItem(Model):

    label: NullStringSpec = ...

    renderers: list[GlyphRenderer[Glyph]] = ...

    index: int | None = ...

    visible: bool = ...

@dataclass
class Legend(Annotation, ScalarTitleTextProps, ScalarBorderLineProps, ScalarBackgroundFillProps,
             ScalarItemBackgroundFillProps, ScalarInactiveFillProps, ScalarLabelTextProps):

    location: LegendLocation | tuple[float, float] = ...

    orientation: Orientation = ...

    ncols: int | Auto = ...

    nrows: int | Auto = ...

    title: str | None = ...


    title_location: Location = ...

    title_standoff: int = ...

    click_policy: LegendClickPolicy = ...

    item_background_policy: AlternationPolicy = ...

    label_standoff: int = ...

    label_height: Auto | int = ...

    label_width: int = ...

    glyph_height: int = ...

    glyph_width: int = ...

    margin: int = ...

    padding: Padding = ...

    border_radius: BorderRadius = ...

    spacing: int = ...

    items: list[LegendItem] | list[tuple[str, list[GlyphRenderer[Glyph]]]] = ...

    def on_click(self, handler: PyEventCallback) -> None: ...

    def js_on_click(self, handler: JsEventCallback) -> None: ...

X: TypeAlias = HAlign | float | CoordinateLike
Y: TypeAlias = VAlign | float | CoordinateLike

Position: TypeAlias = HVAlign | tuple[X, Y]
PositionUnits: TypeAlias = Literal["data", "screen", "view", "percent"]

@dataclass
class ScaleBar(Annotation, ScalarBarLineProps, ScalarLabelTextProps, ScalarTitleTextProps,
               ScalarBorderLineProps, ScalarBackgroundFillProps, ScalarBackgroundHatchProps):

    range: Range | Auto = ...

    unit: str = ...

    dimensional: Dimensional = ...

    orientation: Orientation = ...

    location: Position = ...

    x_units: PositionUnits = ...

    y_units: PositionUnits = ...

    anchor: AutoAnchor = ...

    length_sizing: Literal["adaptive", "exact"] = ...

    bar_length: float | int = ...

    bar_length_units: Literal["screen", "data", "percent"] = ...

    margin: int = ...

    padding: int = ...

    label: str = ...

    label_align: Align = ...

    label_location: Location = ...

    label_standoff: int = ...

    title: str = ...

    title_align: Align = ...

    title_location: Location = ...

    title_standoff: int = ...

    ticker: Ticker = ...

@abstract
@dataclass(init=False)
class BaseBar(Annotation, ScalarTitleTextProps, ScalarMajorLabelTextProps, ScalarMajorTickLineProps,
              ScalarMinorTickLineProps, ScalarBarLineProps, ScalarBorderLineProps, ScalarBackgroundFillProps):

    location: HVAlign | tuple[float, float] = ...

    orientation: Orientation | Auto = ...

    height: Literal["max"] | int = ...

    width: Literal["max"] | int = ...

    margin: int = ...

    padding: int = ...

    title: TextLike | None = ...

    title_standoff: int = ...

    ticker: Ticker | Auto = ...

    formatter: TickFormatter | Auto = ...

    major_label_overrides: dict[float | str, TextLike] = ...

    major_label_policy: LabelingPolicy = ...

    label_standoff: int = ...

    major_tick_in: int = ...

    major_tick_out: int = ...

    minor_tick_in: int = ...

    minor_tick_out: int = ...

@dataclass
class SizeBar(BaseBar, GlyphLineProps, GlyphFillProps, GlyphHatchProps):

    renderer: GlyphRenderer[RadialGlyph] | Auto = ...

    bounds: tuple[float, float] | Auto = ...
