import warnings
from typing import TypeVar, Union


class SolidColorParams:

    """
    Special configuration class for configure Solid color pattern. Contains information about R (Y) - first,
    G (Cb) - second, B(Cr) - third components.
    """

    def __init__(self, first: int = 0, second: int = 0, third: int = 0):
        if not (0 <= first <= 255):
            warnings.warn("Incorrect value. Must use value from range: 0 - 255. Will be used default value = 0")
            first = 0
        self.first = first

        if not (0 <= second <= 255):
            warnings.warn("Incorrect value. Must use value from range: 0 - 255. Will be used default value = 0")
            second = 0
        self.second = second

        if not (0 <= third <= 255):
            warnings.warn("Incorrect value. Must use value from range: 0 - 255. Will be used default value = 0")
            third = 0
        self.third = third


class WhiteVStripsParams:

    """
    Special configuration class for configure White V Strips pattern. Contains information about white stripes width
    and black stripes width.
    """

    def __init__(self, white_stripes_width: int = 1, black_stripes_width: int = 1):
        if not (1 <= white_stripes_width <= 1000):
            warnings.warn("Incorrect value. Must use value from range: 1 - 1000. Will be used default value = 1")
            white_stripes_width = 1
        self.white_stripes_width = white_stripes_width

        if not (0 <= black_stripes_width <= 1000):
            warnings.warn("Incorrect value. Must use value from range: 1 - 1000. Will be used default value = 1")
            black_stripes_width = 1
        self.black_stripes_width = black_stripes_width


class GradientStripsParams:

    """
    Special configuration class for configure Gradient Strips pattern. Contains information about color steps conut.
    """

    def __init__(self, color_step: int = 10000):
        if not (0 <= color_step <= 10000):
            warnings.warn("Incorrect value. Must use value from range: 1 - 10000. Will be used default value = 1")
            color_step = 1
        self.color_step = color_step


class MotionParams:

    """
    Special configuration class for configure Motion pattern. Contains information about frames conut.
    """

    def __init__(self, frames_count: int = 10000):
        if not (0 <= frames_count <= 10000):
            warnings.warn("Incorrect value. Must use value from range: 1 - 10000. Will be used default value = 1")
            frames_count = 1
        self.frames_count = frames_count


class SquareWindowParams:

    """
    Special configuration class for configure Square Window pattern. Contains information about white square size.
    """

    def __init__(self, white_square: int = 30):
        if not (0 <= white_square <= 100):
            warnings.warn("Incorrect value. Must use value from range: 0 - 100. Will be used default value = 30")
            white_square = 30
        self.white_square = white_square


class StepsScrollingParams:

    """
    Special configuration class for configure Scrolling (Steps type) pattern. Contains information about horizontally
    delta, vertically delta and frames count.
    """

    def __init__(self, horizontally: int = 0, vertically: int = 0, frames: int = 0):
        if not (-128 <= horizontally <= 127):
            warnings.warn("Incorrect value (horizontally). Must use value from range: (-)128 - 127. "
                          "For YCbCr 422 range: (-)128 - 126 \n"
                          "Will be used default value = 0")
            horizontally = 0
        if not (-128 <= vertically <= 127):
            warnings.warn("Incorrect value (vertically). Must use value from range: (-)128 - 127. "
                          "For YCbCr 420 range: (-)128 - 126 \n"
                          "Will be used default value = 0")
            vertically = 0
        if not (0 <= frames <= 255):
            warnings.warn("Incorrect value (frames). Must use value from range: 0 - 255. "
                          "Will be used default value = 0")
            frames = 0
        self.horizontally = (-1) * horizontally
        self.vertically = vertically
        self.frames = frames


class DistanceScrollingParams:
    """
    Support of DistanceScrolling will be added later.
    """
    def __init__(self):
        pass


PGPatternParams = TypeVar("PGPatternParams",
                          SolidColorParams,
                          WhiteVStripsParams,
                          GradientStripsParams,
                          MotionParams,
                          SquareWindowParams
                          )


PGScrollingParams = TypeVar("PGScrollingParams",
                            StepsScrollingParams,
                            DistanceScrollingParams)
