from typing import List, Optional, Sequence, Union
from saleae.data import SaleaeTime
from .measure import Measure


class HorizontalRule:
    """
    An annotation value represented as a horizontal rule.

    This can be assigned to an annotation `value` while processing data in :py:meth:`saleae.measurements.analog_measurer.AnalogMeasurer.measure_range`.

    """

    def __init__(self, *, value: Union[int, float]):
        """
        :param value: The vertical value of the rule.
        """
        self.value = value


class VerticalRule:
    """
    An annotation value represented as a vertical rule, as an absolute time.

    This can be assigned to an annotation `value` while processing data in :py:meth:`saleae.measurements.analog_measurer.AnalogMeasurer.measure_range`.

    """

    def __init__(self, *, time: SaleaeTime):
        """
        :param value: The time value of the rule.
        """
        self.time = time


AnnotationType = Union[HorizontalRule, VerticalRule]


class Annotation:
    """
    Annotation declaration that appears as a class property of an :py:class:`.analog_measurer.AnalogMeasurer`

    """

    def __init__(self, *, measures: List[Measure]):
        """
        :param measures: The list of measures that this annotation depends on. If those measures are all disabled, this anotation will not be shown.
        """
        self.measures = measures


class AnnotationInstance:
    def __init__(self):
        self._value = None

    @property
    def value(self) -> Optional[Union[AnnotationType, Sequence[AnnotationType]]]:
        return self._value

    @value.setter
    def value(self, value: Union[AnnotationType, Sequence[AnnotationType]]):
        if self._value is not None:
            raise RuntimeError('An annotation can only be set once')
        self._value = value
