from yta_editor_frame.frame.resource.abstract import FrameResourceABC
from yta_editor_frame.frame.resource.types import FrameResourceType
from yta_programming.decorators.requires_dependency import requires_dependency
from yta_validation.parameter import ParameterValidator


class AvVideoFrameResource(
    FrameResourceABC
):
    """
    A frame resource based on a pyav VideoFrame.

    The `.frame` attribute is an `av.VideoFrame`.
    """

    @property
    def width(
        self
    ) -> int:
        return self.frame.width
    
    @property
    def height(
        self
    ) -> int:
        return self.frame.height
    
    @property
    def format(
        self
    ) -> str:
        return str(self.frame.format.name)
    
    @property
    def type(
        self
    ) -> FrameResourceType:
        return FrameResourceType.CPU_AV_VIDEOFRAME

    def __init__(
        self,
        frame: 'av.VideoFrame',
        render_context: 'RenderContext'
    ):
        ParameterValidator.validate_mandatory_instance_of('frame', frame, 'VideoFrame')

        super().__init__(
            frame = frame,
            render_context = render_context
        )

    def release(
        self
    ):
        pass

    @requires_dependency('av', 'yta_editor_frame', 'av')
    def copy(
        self
    ) -> 'AvVideoFrameResource':
        """
        Get a copy of this frame resource.
        """
        import av

        arr = self.frame.to_ndarray()
        arr_copy = arr.copy()
        # TODO: Why do we force the 'format' (?)
        copy = av.VideoFrame.from_ndarray(arr_copy, format = 'rgb24')

        return AvVideoFrameResource(
            frame = copy,
            render_context = self.render_context
        )