import warnings
from enum import IntEnum
from typing import TypeVar


class VideoPattern(IntEnum):
    """
    Class `VideoPattern` contains all possible variants of patterns which can be set in the function `set_pattern`.
    """
    Disabled = 0
    ColorBars = 1
    Chessboard = 2
    SolidColor = 3
    SolidWhite = 4
    SolidRed = 5
    SolidGreen = 6
    SolidBlue = 7
    WhiteVStrips = 8
    GradientRGBStripes = 9
    ColorRamp = 10
    ColorSquares = 11
    MotionPattern = 12
    SquareWindow = 15


class PGDynamicRange(IntEnum):
    """
    Class `PGDynamicRange` contains all possible variants of Dynamic Range.
    """
    VESA = 0x00
    CTA = 0x01


class PGStandard(IntEnum):
    """
    Class `PGStandard` contains all possible variants of Standard.
    """
    CVT = 0x01
    DMT = 0x02
    CTA = 0x03


class PGVideoMode(IntEnum):
    """
    Class `PGVideoMode` contains all possible variants of Video mode.
    """
    CTA = 0x00
    RB1 = 0x01
    RB2 = 0x02
    RB3 = 0x03


class PGAspectRatio(IntEnum):
    """
    Class `PGVideoMode` contains all possible variants of Aspect ratio.
    """
    NoData = 0x00
    Ratio4x3 = 0x01
    Ratio16x9 = 0x02


class PGColorInfo(IntEnum):
    """
    Class `PGColorInfo` contains all possible variants of Color info.
    """
    Unknown = -1
    RGB = 0
    YCbCr444 = 1
    YCbCr422 = 2
    YCbCr420 = 3
    Y_only = 4
    RAW = 5


class PGColorimetry(IntEnum):
    """
    Class `PGColorimetry` contains all possible variants of Colorimetry.
    """
    Unknown = 0
    ITU601 = 0
    ITU709 = 1


class PGColorDepth(IntEnum):
    """
    Class `PGColorDepth` contains all possible variants of Color Depth.
    """
    Unknown = -1
    BPC6 = 0
    BPC8 = 1
    BPC10 = 2
    BPC12 = 3
    BPC16 = 4
    BPC7 = 5
    BPC14 = 6


class PGAdaptiveSyncPatternType(IntEnum):
    """
    Class `PGAdaptiveSyncPatternType` contains all possible variants of Adaptive Sync Pattern.
    """
    AS_None = 0
    AS_Constant = 1
    AS_Square = 2
    AS_Zigzag = 3
    AS_Fixed = 4


class ConstantASParams:
    """
    Special configuration class for configure Adaptive-Sync. Contains information about blank lines count.
    """
    def __init__(self, lines: int = 0):
        if lines < 0:
            warnings.warn("Incorrect blank lines count. Must use more then 0. "
                          "Will be used default value = 0")
            lines = 0
        self.lines = lines


class SquareASParams:

    """
    Special configuration class for configure Adaptive-Sync. Contains information about blank lines minimum and maximum
    count and period frames count.
    """

    def __init__(self, min_lanes: int = 0, max_lanes: int = 1000, period_frames: int = 10):
        if min_lanes < 0:
            warnings.warn("Incorrect blank lines min count. Must use more then 0. "
                          "Will be used default value = 0")
            min_lanes = 0
        if max_lanes < 0:
            warnings.warn("Incorrect blank lines max count. Must use more then 0. "
                          "Will be used default value = 1000")
            max_lanes = 1000
        if period_frames < 0:
            warnings.warn("Incorrect period frames count. Must use more then 0. "
                          "Will be used default value = 10")
            period_frames = 10
        self.min_lanes = min_lanes
        self.max_lanes = max_lanes
        self.period_frames = period_frames


class ZigzagASParams:

    """
    Special configuration class for configure Adaptive-Sync. Contains information about blank lines minimum and maximum
    count, increase and decrease lanes count.
    """

    def __init__(self, min_lanes: int = 0, max_lanes: int = 1000, increase_lines: int = 100, decrease_lines: int = 100):
        if min_lanes < 0:
            warnings.warn("Incorrect blank lines min count. Must use more then 0. "
                          "Will be used default value = 0")
            min_lanes = 0
        if max_lanes < 0:
            warnings.warn("Incorrect blank lines max count. Must use more then 0. "
                          "Will be used default value = 1000")
            max_lanes = 1000
        if increase_lines < 0:
            warnings.warn("Incorrect increase lines count. Must use more then 0. "
                          "Will be used default value = 100")
            increase_lines = 100
        if decrease_lines < 0:
            warnings.warn("Incorrect decrease lines count. Must use more then 0. "
                          "Will be used default value = 100")
            decrease_lines = 100
        self.min_lanes = min_lanes
        self.max_lanes = max_lanes
        self.increase_lines = increase_lines
        self.decrease_lines = decrease_lines


class FixedASParams:

    """
    Special configuration class for configure Adaptive-Sync. Contains information about refresh rate count, increase
    and decrease lanes count.
    """

    def __init__(self, refresh_rate: int = 60, divide_by_1_001: bool = False, increase_lines: int = 100,
                 decrease_lines: int = 100):
        if refresh_rate < 0:
            warnings.warn("Incorrect refresh rate count. Must use more then 0. "
                          "Will be used default value = 60")
            refresh_rate = 60
        if increase_lines < 0:
            warnings.warn("Incorrect increase lines count. Must use more then 0. "
                          "Will be used default value = 100")
            increase_lines = 100
        if decrease_lines < 0:
            warnings.warn("Incorrect decrease lines count. Must use more then 0. "
                          "Will be used default value = 100")
            decrease_lines = 100
        self.refresh_rate = refresh_rate
        self.divide_by_1_001 = int(divide_by_1_001)
        self.increase_lines = increase_lines
        self.decrease_lines = decrease_lines


ASParams = TypeVar("ASParams",
                   ConstantASParams,
                   SquareASParams,
                   ZigzagASParams,
                   FixedASParams,
                   )
