import bpy
from bpy.types import Operator
from bpy.props import (BoolProperty, StringProperty)

from vse_toolbox.sequencer_utils import (get_strips, rename_strips, set_channels,
    get_channel_index, new_text_strip)
                                         
from vse_toolbox.bl_utils import get_scene_settings


class VSETB_OT_rename(Operator):
    bl_idname = "vse_toolbox.strips_rename"
    bl_label = "Rename Strips"
    bl_description = "Rename Strips"
    bl_options = {"REGISTER", "UNDO"}

    #template : StringProperty(name="Strip Name", default="")
    #increment : IntProperty(name="Increment", default=0)
    channel_name : StringProperty(name="Channel Name", default="")
    selected_only : BoolProperty(name="Selected Only", default=False)
    #start_number : IntProperty(name="Start Number", default=0, min=0)
    #by_sequence : BoolProperty(
    #    name="Reset By Sequence",
    #    description="Reset Start Number for each sequence",
    #    default=False
    #)

    @classmethod
    def poll(cls, context):
        settings = get_scene_settings()
        return settings.active_project

    def invoke(self, context, event):
        scn = context.scene
        settings = get_scene_settings()
        
        return context.window_manager.invoke_props_dialog(self)

    def draw(self, context):
        layout = self.layout
        scn = context.scene
        settings = get_scene_settings()
        project = settings.active_project

        col = layout.column()
        col.use_property_split = True
        col.use_property_decorate = False

        if self.channel_name == 'Shots':
            col.prop(project, 'shot_template', text='Shot Name')
            col.prop(project, 'shot_start_number', text='Start Number')
            col.prop(project, 'shot_increment', text='Increment')
            col.prop(project, 'reset_by_sequence')
        elif self.channel_name == 'Sequences':
            col.prop(project, 'sequence_template' ,text='Sequence Name')
            col.prop(project, 'sequence_start_number', text='Start Number')
            col.prop(project, 'sequence_increment', text='Increment')

        col.prop(self, 'selected_only')

    def execute(self, context):
        scn = context.scene
        settings = get_scene_settings()
        project = settings.active_project

        strips = get_strips(channel=self.channel_name, selected_only=self.selected_only)
        if self.channel_name == 'Shots':
            rename_strips(strips, 
                template=project.shot_template,
                increment=project.shot_increment, start_number=project.shot_start_number,
                by_sequence=project.reset_by_sequence
            )

        if self.channel_name == 'Sequences':            
            rename_strips(strips,
                template=project.sequence_template,
                increment=project.sequence_increment, start_number=project.sequence_start_number
            )     

        return {"FINISHED"}


class VSETB_OT_show_waveform(Operator):
    bl_idname = "vse_toolbox.show_waveform"
    bl_label = "Show Waveform"
    bl_description = "Show Waveform of all audio strips"
    bl_options = {"REGISTER", "UNDO"}

    enabled : BoolProperty(default=True)

    @classmethod
    def poll(cls, context):
        return True

    def execute(self, context):
        scn = context.scene   

        for strip in get_strips(channel='Audio'):
            strip.show_waveform = self.enabled
        
        return {"FINISHED"}


class VSETB_OT_set_sequencer(Operator):
    bl_idname = "vse_toolbox.set_sequencer"
    bl_label = "Set Sequencer"
    bl_description = "Set resolution, frame end and channel names"
    bl_options = {"REGISTER", "UNDO"}

    @classmethod
    def poll(cls, context):
        return True

    def execute(self, context):
        scn = context.scene   

        set_channels()
        movies = get_strips(channel='Movie')
        movie = None
        if movies:
            movie = movies[0]
            movie.transform.scale_x = movie.transform.scale_y = 1
            elem = movie.strip_elem_from_frame(scn.frame_current)
            scn.render.resolution_x = elem.orig_width
            scn.render.resolution_y = elem.orig_height
        else:
            self.report({'INFO'}, f'Cannot set Resolution. No Movie Found.')
        
        scn.view_settings.view_transform = 'Standard'
        scn.render.image_settings.file_format = 'FFMPEG'
        scn.render.ffmpeg.gopsize = 5
        scn.render.ffmpeg.constant_rate_factor = 'HIGH'
        scn.render.ffmpeg.format = 'QUICKTIME'
        scn.render.ffmpeg.audio_codec = 'AAC'
        scn.render.ffmpeg.audio_codec = 'MP3'
        scn.render.ffmpeg.audio_mixrate = 44100
        scn.render.ffmpeg.audio_bitrate = 128

        shots = get_strips(channel='Shots')
        if shots:
            scn.frame_end = shots[-1].frame_final_end -1
        elif movie:
            scn.frame_end = movie.frame_final_end -1
        
        return {"FINISHED"}


class VSETB_OT_set_stamps(Operator):
    bl_idname = "vse_toolbox.set_stamps"
    bl_label = "Set Stamps"
    bl_description = "Set Stamps on Video"
    bl_options = {"REGISTER", "UNDO"}

    def execute(self, context):
        scn = context.scene
        settings = get_scene_settings()
        #strip_settings = get_strip_settings()
        channel_index = get_channel_index('Stamps')

        for strip in get_strips('Stamps'):
            if strip.type == 'META':
                scn.sequence_editor.sequences.remove(strip)

        bpy.ops.sequencer.select_all(action='DESELECT')

        height = scn.render.resolution_y
        width = scn.render.resolution_x
        ratio = (height / 1080)
        margin = 0.01
        box_margin = 0.005
        font_size = int(24*ratio)

        crop_x = int(width * 0.4)
        crop_max_y = int(height - font_size*2)
        #crop_min_y =  int(scn.render.resolution_y * 0.01)

        stamp_params = dict(start=scn.frame_start, end=scn.frame_end,
            font_size=font_size, y=margin, box_margin=box_margin, select=True, box_color=(0, 0, 0, 0.5))

        # Project Name
        project_strip_stamp = new_text_strip('project_name_stamp', channel=1, **stamp_params,
            text=settings.active_project.name, x=0.01, align_x='LEFT', align_y='BOTTOM')

        project_strip_stamp.crop.max_x = crop_x * 2
        project_strip_stamp.crop.max_y = crop_max_y

        # Shot Name
        shot_strip_stamp = new_text_strip('shot_name_stamp', channel=2, **stamp_params,
            text='{active_shot_name}',  align_y='BOTTOM')

        shot_strip_stamp.crop.min_x = crop_x
        shot_strip_stamp.crop.max_x = crop_x
        shot_strip_stamp.crop.max_y = crop_max_y

        # Frame Range
        frame_strip_stamp = new_text_strip('frame_range_stamp', channel=3, **stamp_params,
            text='{active_shot_frame} / {active_shot_duration}', x=0.99, align_x='RIGHT', align_y='BOTTOM')

        frame_strip_stamp.crop.min_x = crop_x *2
        frame_strip_stamp.crop.max_y = crop_max_y

        bpy.ops.sequencer.meta_make()
        stamps_strip = context.active_sequence_strip
        stamps_strip.name = 'Stamps'
        stamps_strip.channel = channel_index

        #stamps_strip = scn.sequence_editor.sequences.new_meta('Stamps', scn.frame_start, scn.frame_end)
        #stamps_strip.channel = get_channel_index('Stamps')
        scn.frame_set(scn.frame_current)  # For update stamps

        return {"FINISHED"}
    

classes = (
    VSETB_OT_rename,
    VSETB_OT_set_sequencer,
    VSETB_OT_set_stamps,
    VSETB_OT_show_waveform,
)

def register(): 
    for cls in classes:
        bpy.utils.register_class(cls)

def unregister():
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)