from UniTAP.common.color_info import ColorInfo


class DscParameters:
    """
    Class `DscParameters` describes all parameters necessary for formatting input image to DSC image.
    - Width of image `width`.
    - Height of image `height`.
    - Color format of image `color_format` type `ColorInfo.ColorFormat`.
    - BPC `bpc`.
    - BPP `bpp`.
    - Flag of is block prediction enabled `is_block_prediction_enabled`.
    - Horizontal slice number `horizontal_slice_number`.
    - Number of buffer bit depth `buffer_bit_depth`.
    - Vertical slice number `vertical_slice_number`.
    - Vertical slice size `vertical_slice_size`.
    - DSC major version `version_major`.
    - DSC minor version `version_minor`.
    """
    def __init__(self, width: int = 1920, height: int = 1080,
                 color_format: ColorInfo.ColorFormat = ColorInfo.ColorFormat.CF_RGB, bpc: int = 8, bpp: int = 128,
                 is_block_prediction_enabled: bool = False, horizontal_slice_number: int = 8, buffer_bit_depth: int = 8,
                 vertical_slice_number: int = 8, vertical_slice_size: int = 1, version_major: int = 1,
                 version_minor: int = 2):
        self.__width = width
        self.__height = height
        self.__color_format = color_format
        self.__bpc = bpc
        self.__bpp = bpp
        self.__is_block_prediction_enabled = is_block_prediction_enabled
        self.__horizontal_slice_number = horizontal_slice_number
        self.__buffer_bit_depth = buffer_bit_depth
        self.__vertical_slice_number = vertical_slice_number
        self.__vertical_slice_size = vertical_slice_size
        self.__version_major = version_major
        self.__version_minor = version_minor

    @property
    def width(self) -> int:
        return self.__width

    @width.setter
    def width(self, width: int = 1920):
        if width <= 0:
            raise ValueError(f"Incorrect width of image. Must be more, than 0. Current value: {width}")
        self.__width = width

    @property
    def height(self) -> int:
        return self.__height

    @height.setter
    def height(self, height: int = 1080):
        if height <= 0:
            raise ValueError(f"Incorrect height of image. Must be more, than 0. Current value: {height}")
        self.__height = height

    @property
    def color_format(self) -> ColorInfo.ColorFormat:
        return self.__color_format

    @color_format.setter
    def color_format(self, color_format: ColorInfo.ColorFormat.CF_RGB):
        self.__color_format = color_format

    @property
    def bpc(self) -> int:
        return self.__bpc

    @bpc.setter
    def bpc(self, bpc: int = 8):
        if bpc <= 5:
            raise ValueError(f"Incorrect bpc of image. Must be more, than 5. Current value: {bpc}")
        self.__bpc = bpc

    @property
    def bpp(self) -> int:
        return self.__bpp

    @bpp.setter
    def bpp(self, bpp: int = 10):
        if bpp <= 0:
            raise ValueError(f"Incorrect bpp of image. Must be more, than 0. Current value: {bpp}")
        self.__bpp = bpp

    @property
    def is_block_prediction_enabled(self) -> bool:
        return self.__is_block_prediction_enabled

    @width.setter
    def width(self, is_block_prediction_enabled: bool = False):
        self.__is_block_prediction_enabled = is_block_prediction_enabled

    @property
    def horizontal_slice_number(self) -> int:
        return self.__horizontal_slice_number

    @horizontal_slice_number.setter
    def horizontal_slice_number(self, horizontal_slice_number: int = 1920):
        if horizontal_slice_number <= 0:
            raise ValueError(f"Incorrect horizontal_slice_number of image. Must be more, than 0. "
                             f"Current value: {horizontal_slice_number}")
        self.__horizontal_slice_number = horizontal_slice_number

    @property
    def buffer_bit_depth(self) -> int:
        return self.__buffer_bit_depth

    @buffer_bit_depth.setter
    def buffer_bit_depth(self, buffer_bit_depth: int = 8):
        if buffer_bit_depth <= 0:
            raise ValueError(f"Incorrect buffer_bit_depth of image. Must be more, than 0. "
                             f"Current value: {buffer_bit_depth}")
        self.__buffer_bit_depth = buffer_bit_depth

    @property
    def vertical_slice_number(self) -> int:
        return self.__vertical_slice_number

    @vertical_slice_number.setter
    def vertical_slice_number(self, vertical_slice_number: int = 8):
        if vertical_slice_number <= 0:
            raise ValueError(f"Incorrect vertical_slice_number of image. Must be more, than 0. "
                             f"Current value: {vertical_slice_number}")
        self.__vertical_slice_number = vertical_slice_number

    @property
    def vertical_slice_size(self) -> int:
        return self.__vertical_slice_size

    @vertical_slice_size.setter
    def vertical_slice_size(self, vertical_slice_size: int = 1):
        if vertical_slice_size <= 0:
            raise ValueError(f"Incorrect vertical_slice_size of image. Must be more, than 0. "
                             f"Current value: {vertical_slice_size}")
        self.__vertical_slice_size = vertical_slice_size

    @property
    def version_major(self) -> int:
        return self.__version_major

    @version_major.setter
    def version_major(self, version_major: int = 1):
        if version_major <= 0:
            raise ValueError(f"Incorrect version_major of image. Must be more, than 0. Current value: {version_major}")
        self.__version_major = version_major

    @property
    def version_minor(self) -> int:
        return self.__version_minor

    @version_minor.setter
    def version_minor(self, version_minor: int = 2):
        if version_minor <= 0:
            raise ValueError(f"Incorrect version_minor of image. Must be more, than 0. Current value: {version_minor}")
        self.__version_minor = version_minor
