"""
Our awesome editor module in which we
have all the classes that interact with
it and make it possible.

An editor includes a single timeline,
built by tracks, in which we place media
elements and we are able to apply effects
to them.

Here is a brief explanation about the
hierarchy:

- The editor has a timeline.
- The timeline has audio and video tracks
(that can handle when we play or not the
audio and video).
- The tracks have parts, that are virtual
items to simplify the way we combine 
tracks. Those parts include media 
instances. The tracks have priorities
ones against the others.
- The media instances have a time range
in which they must be played within the
track (within the timeline). Those media
instances have the start and end time
range for the media source and can apply
effects to the frames.
- The media sources are just the way we
obtain the frames for the specific media
items (read a file, constant color, etc.).
"""
from yta_editor.tracks.items.transition.transition_node_registry import register_transition_processor_nodes


def main():
    from yta_editor.tests import video_modified_stored

    video_modified_stored()


if __name__ == '__main__':
    pass
    # main()

# TODO: This should be somewhere else I think...
# Things I need to execute before launching the system
print('Launching things we need before...')
# TODO: Pass the 'render_context'
# register_transition_processor_nodes()






# TODO: Move this
from yta_editor_common.context import RenderContext
from yta_video_opengl.context.provider import OpenGLContextProvider
from yta_editor.timeline import Timeline
from yta_video_pyav.settings import Settings
from typing import Union
from quicktions import Fraction


class YTAEditor:
    """
    Class to work with our awesome editor.

    TODO: Each 'YTAEditor' should have its own
    `moderngl.Context` I think, so we need to
    change it and make it not singleton.
    """

    def __init__(
        self,
        number_of_tracks: int = 2,
        output_size: tuple[int, int] = Settings.DEFAULT_VIDEO_SIZE.value, # (1920, 1080) before
        fps: Union[int, float, Fraction] = Settings.DEFAULT_VIDEO_FPS.value, # 60.0 before
        # TODO: I don't like this name
        audio_fps: Union[int, Fraction] = Settings.DEFAULT_AUDIO_FPS.value, # 44_100 before # 48_000.0 for aac
        # TODO: Where does this come from (?)
        audio_samples_per_frame: int = Settings.DEFAULT_AUDIO_SAMPLES_PER_FRAME.value, # 1_024 before
        video_codec: str = Settings.DEFAULT_VIDEO_CODEC.value, # h264 before
        video_pixel_format: str = Settings.DEFAULT_PIXEL_FORMAT.value, # yuv420p before
        audio_codec: str = Settings.DEFAULT_AUDIO_CODEC.value, # aac before
        audio_layout: str  = Settings.DEFAULT_AUDIO_LAYOUT.value, # stereo before
        audio_format: str = Settings.DEFAULT_AUDIO_FORMAT.value # fltp before
    ):
        # Validate the parameters and/or set default
        output_size = (
            Settings.DEFAULT_VIDEO_SIZE.value
            if output_size is None else
            output_size
        )

        fps = (
            Settings.DEFAULT_VIDEO_FPS.value
            if fps is None else
            fps
        )

        audio_fps = (
            Settings.DEFAULT_AUDIO_FPS.value
            if audio_fps is None else
            audio_fps
        )

        # TODO: These values below should go in the RenderContext
        audio_samples_per_frame = (
            # 48_000 is not working well, why?
            Settings.DEFAULT_AUDIO_SAMPLES_PER_FRAME.value
            if audio_samples_per_frame is None else
            audio_samples_per_frame
        )

        video_codec = (
            Settings.DEFAULT_VIDEO_CODEC.value
            if video_codec is None else
            video_codec
        )

        video_pixel_format = (
            Settings.DEFAULT_PIXEL_FORMAT.value
            if video_pixel_format is None else
            video_pixel_format
        )

        audio_codec = (
            Settings.DEFAULT_AUDIO_CODEC.value
            if audio_codec is None else
            audio_codec
        )

        audio_layout = (
            Settings.DEFAULT_AUDIO_LAYOUT.value
            if audio_layout is None else
            audio_layout
        )

        audio_format = (
            Settings.DEFAULT_AUDIO_FORMAT.value
            if audio_format is None else
            audio_format
        )

        # Generate a unique context for this YTAEditor instance
        opengl_context = OpenGLContextProvider().context

        # Generate a unique render context for this timeline
        self.render_context = RenderContext(
            opengl_context = opengl_context,
            size = output_size,
            fps = fps,
            audio_fps = audio_fps,
            # TODO: By now I'm forcing this
            do_use_gpu = True
        )

        # TODO: The Timeline should receive the `render_context`
        # instead of these parameters
        self.timeline: Timeline = Timeline(
            render_context = self.render_context,
            number_of_tracks = number_of_tracks,
            # output_size = output_size,
            # fps = fps,
            # audio_fps = audio_fps,
            # TODO: I think all this below should be also in the RenderContext
            audio_samples_per_frame = audio_samples_per_frame,
            video_codec = video_codec,
            video_pixel_format = video_pixel_format,
            audio_codec = audio_codec,
            audio_layout = audio_layout,
            audio_format = audio_format
        )

        # Register transition nodes
        register_transition_processor_nodes(
            render_context = self.render_context
        )
