from dataclasses import dataclass
from typing import Union


# Frames
@dataclass(frozen = True)
class FrameIndex:
    """
    *Dataclass*

    Dataclass to represent a the index of a frame.
    """
    value: int
    """
    The index of the frame.
    """

    def __post_init__(
        self
    ):
        if self.value < 0:
            raise ValueError('FrameIndex must be >= 0')
        
    def __int__(
        self
    ) -> int:
        return self.value
        
@dataclass(frozen = True)
class FramesNumber:
    """
    The total amount of frames.
    """
    value: int
    """
    The amount of frames.
    """

    def __post_init__(
        self
    ):
        if self.value < 0:
            raise ValueError('FramesNumber must be >= 0')
        
    def __int__(
        self
    ) -> int:
        return self.value
    
# Time
@dataclass(frozen = True)
class TimeMoment:
    """
    *Dataclass*

    Dataclass to represent a time moment.
    """
    value: Union[float, 'Fraction']
    """
    The time moment.
    """

    def __post_init__(
        self
    ):
        if self.value < 0:
            raise ValueError('TimeMoment must be >= 0')
        
    def __float__(
        self
    ) -> float:
        return float(self.value)
        
@dataclass(frozen = True)
class TimeDuration:
    """
    *Dataclass*

    Dataclass to represent a total time duration (in
    seconds).
    """
    value: Union[float, 'Fraction']
    """
    The total duration (in seconds).
    """

    def __post_init__(
        self
    ):
        if self.value < 0:
            raise ValueError('TimeDuration must be >= 0')
        
    def __float__(
        self
    ) -> float:
        return float(self.value)
    
@dataclass(frozen = True)
class Fps:
    """
    *Dataclass*

    Dataclass to represent an amount of frames per
    second.
    """
    value: Union[float, 'Fraction']
    """
    The amount of frames per second.
    """

    def __post_init__(
        self
    ):
        if self.value < 0:
            raise ValueError('Fps must be >= 0')
        
    def __float__(
        self
    ) -> float:
        return float(self.value)
        
# Progress
@dataclass(frozen = True)
class ProgressValue:
    """
    *Dataclass*

    Dataclass to represent a progress value, that will
    be always in the `[0.0, 1.0]` range.
    """
    value: Union[float, 'Fraction']
    """
    The progress value in the `[0.0, 1.0]` range.
    """

    def __post_init__(
        self
    ):
        if (
            self.value < 0.0 or
            self.value > 1.0
        ):
            raise ValueError('ProgressValue must be in a [0.0, 1.0] range.')
        
    def __float__(
        self
    ) -> float:
        return float(self.value)