import os

from enum import IntEnum
from .color_info import ColorInfo
from .data_info import DataInfo
from .timestamp import Timestamp
from PIL import Image


class ImageFileFormat(IntEnum):
    """
    Describe all supported image file formats for saving `VideoFrame`:
    - BIN.
    - PPM.
    - BMP.
    - DSC.
    """
    IFF_BIN = 0
    IFF_PPM = 1
    IFF_BMP = 2
    IFF_DSC = 3


class VideoFrame:

    """
    Class `VideoFrame` contains base information about video frame:
    - Height (int).
    - Width (int).
    - Data (bytearray).
    - Color info (object of `ColorInfo`).
    - Data info (object of `DataInfo`).
    - Timestamp (object of `Timestamp`).
    """

    def __init__(self):
        self.width = 0
        self.height = 0
        self.data = bytearray()
        self.color_info = ColorInfo()
        self.data_info = DataInfo()
        self.timestamp = Timestamp(0)
        self._compressed = False

    def __str__(self):
        return f"Resolution: {self.width}x{self.height}\n" \
               f"Data length: {len(self.data)}\n" \
               f"Color Info:\n{self.color_info}\n" \
               f"Data Info:\n{self.data_info}\n" \
               f"Timestamp:\n{self.timestamp}\n"

    def is_compressed(self) -> bool:
        return self._compressed


def get_vf_from_image(path: str, width: int, height: int) -> VideoFrame:
    """

    Function allows getting prepared object of `VideoFrame` from external (custom) image.

    Args:
        path (str) - full path to image.
        width (int) - width of image.
        height (int) - height of image.

    """
    if not os.path.exists(path):
        raise FileNotFoundError(f"Image: {path} is missing!")

    image = Image.open(path)

    if width < image.size[0] and height < image.size[1]:
        image = image.crop((0, 0, width, height))

    size = image.size

    if size == [0, 0]:
        raise ValueError("Invalid image size.")

    convert_image = image.convert('RGB').resize(size=(width, height), resample=Image.Resampling.LANCZOS)

    video_frame = VideoFrame()
    video_frame.data = bytearray(convert_image.tobytes())
    video_frame.width = width
    video_frame.height = height
    video_frame.color_info.bpc = 8
    video_frame.color_info.color_format = ColorInfo.ColorFormat.CF_RGB
    video_frame.color_info.colorimetry = ColorInfo.Colorimetry.CM_sRGB
    # video_frame.color_info.dynamic_range = ColorInfo.DynamicRange.DR_VESA
    video_frame.data_info.packing = DataInfo.Packing.P_PACKED
    video_frame.data_info.component_order = DataInfo.ComponentOrder.CO_RGB
    video_frame.data_info.alignment = DataInfo.Alignment.A_LSB

    return video_frame
