# gpl: authors Carlos Padial, Turi Scandurra

import bpy
import os
from bpy.types import (
        Operator,
        Panel,
        )
from bpy.props import IntProperty
import subprocess
from . import functions


proxy_qualities = [
        ("1", "25%", ""), ("2", "50%", ""),
        ("3", "75%", ""), ("4", "100%", ""),
        ("5", "none", "")
        ]


# Functions
def setup_proxy(context, strip, size):
    preferences = context.preferences
    prefs = preferences.addons[__package__].preferences

    # set up proxy settings
    strip.use_proxy = True

    if prefs.use_bi_custom_directory:
        strip.use_proxy_custom_directory = True
        filename = strip.filepath.rpartition("/")[2].rpartition(".")[0]
        strip.proxy.directory = bpy.path.relpath(prefs.proxy_dir + filename)
    else:
        strip.use_proxy_custom_directory = False

    if strip.use_proxy_custom_file is True:
        strip.use_proxy_custom_file = False

    strip.proxy.quality = prefs.quality
    strip.proxy.timecode = prefs.timecode

    if size == 5:
        strip.use_proxy = False
        strip.proxy.build_25 = False
        strip.proxy.build_50 = False
        strip.proxy.build_75 = False
        strip.proxy.build_100 = False

    else:
        proxysuffix = proxy_qualities[size - 1][1].split("%")[0]

        if (proxysuffix == "25"):
            strip.proxy.build_25 = True
        if (proxysuffix == "50"):
            strip.proxy.build_50 = True
        if (proxysuffix == "75"):
            strip.proxy.build_75 = True
        if (proxysuffix == "100"):
            strip.proxy.build_100 = True

    return {"FINISHED"}


def create_proxy(context, strip, size, res):
    # calculate proxy resolution
    div = 4 / size
    newres = (int(int(res[0]) / div), int(int(res[1]) / div))

    preferences = context.preferences
    proxy_dir = preferences.addons[__package__].preferences.proxy_dir
    scripts = preferences.addons[__package__].preferences.proxy_scripts
    ffmpeg_command = preferences.addons[__package__].preferences.ffmpeg_command

    functions.create_folder(proxy_dir)

    if scripts:
        commands = []

    # get filename
    if strip.type == "MOVIE":
        filename = bpy.path.abspath(strip.filepath)
        proxysuffix = proxy_qualities[size - 1][1].split("%")[0]
        proxy_dir = bpy.path.abspath(proxy_dir)
        newfilename = os.path.join(proxy_dir, filename.rpartition("/")[2])
        fileoutput = newfilename.rpartition(".")[0] + "-" + proxysuffix + ".avi"

        # default value for ffmpeg_command = "fmpeg -i {} -vcodec mjpeg -qv 1 -s {}x{} -y {}"

        command = ffmpeg_command.format(filename, newres[0], newres[1], fileoutput)
        print(command)

        if scripts:
            commands.append(command)
        else:
            # check for existing file
            if not os.path.isfile(fileoutput):
                subprocess.call(command, shell=True)
            else:
                print("File already exists")

        # set up proxy settings
        strip.use_proxy = True
        try:
            strip.use_proxy_custom_file = True
            strip.proxy.filepath = bpy.path.relpath(fileoutput)
        except:
            pass

        if (proxysuffix == "25"):
            strip.proxy.build_25 = True
        if (proxysuffix == "50"):
            strip.proxy.build_50 = True
        if (proxysuffix == "75"):
            strip.proxy.build_75 = True
        if (proxysuffix == "100"):
            strip.proxy.build_100 = True

    if scripts:
        return commands
    else:
        return None


def create_proxy_scripts(scripts_dir, commands, strip_name=None):

    functions.create_folder(bpy.path.abspath(scripts_dir))
    for i in commands:
        # print(i)
        filename = "{}/proxy_script_{}.sh".format(scripts_dir, strip_name)
        text_file = open(bpy.path.abspath(filename), "w")
        # print(filename)
        text_file.write(i)
        text_file.close()


# classes
class CreateProxyOperator(Operator):
    bl_idname = "sequencer.create_proxy_operator"
    bl_label = "Create Proxy"
    bl_description = ("Use ffmpeg to create a proxy from video\n"
                      "and setup proxies for selected strip")
    bl_options = {'REGISTER', 'UNDO'}

    size: IntProperty(
            name="Proxy Size",
            default=1
            )

    @classmethod
    def poll(self, context):
        strip = functions.act_strip(context)
        scn = context.scene
        if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
            return strip.type in ('MOVIE')
        else:
            return False

    def execute(self, context):
        preferences = context.preferences
        proxy_scripts_path = preferences.addons[__package__].preferences.proxy_scripts_path

        for strip in context.selected_editable_sequences:
            # get resolution from active strip
            try:
                bpy.ops.sequencerextra.read_exif()
            except:
                pass

            sce = context.scene
            try:
                res = sce['metadata'][0]['Composite:ImageSize'].split("x")
            except:
                res = (sce.render.resolution_x, sce.render.resolution_y)

            commands = create_proxy(context, strip, self.size, res)

            if commands is None:
                # Update scene
                context.scene.update()
                newstrip = context.scene.sequence_editor.active_strip

                # deselect all other strips
                for i in context.selected_editable_sequences:
                    if i.name != newstrip.name:
                        i.select = False

                # Update scene
                context.scene.update()
            else:
                create_proxy_scripts(proxy_scripts_path, commands, strip.name)

        return {'FINISHED'}


class CreateBIProxyOperator(Operator):
    bl_idname = "sequencer.create_bi_proxy_operator"
    bl_label = "Create proxy with Blender Internal"
    bl_description = "Use BI system to create a proxy"
    bl_options = {'REGISTER', 'UNDO'}

    size: IntProperty(
            name="Proxy Size",
            default=1
            )

    @classmethod
    def poll(self, context):
        strip = functions.act_strip(context)
        scn = context.scene
        if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
            return strip.type in ('MOVIE')
        else:
            return False

    def execute(self, context):
        try:
            strips = functions.get_selected_strips(context)

            for strip in strips:
                # deselect all other strips
                for i in strips:
                    i.select = False
                # select current strip
                strip.select = True
                if strip.type == "MOVIE":
                    setup_proxy(context, strip, self.size)
        except Exception as e:
            functions.error_handlers(
                        self,
                        "sequencer.create_bi_proxy_operator", e,
                        "Create proxy with blender internal"
                        )
            return {"CANCELLED"}

        # select all strips again
        for strip in strips:
            try:
                strip.select = True
            except ReferenceError:
                pass
        bpy.ops.sequencer.reload()

        return {'FINISHED'}


class CreateProxyToolPanel(Panel):
    bl_label = "Proxy Tools"
    bl_idname = "OBJECT_PT_ProxyTool"
    bl_space_type = 'SEQUENCE_EDITOR'
    bl_region_type = 'UI'

    @classmethod
    def poll(self, context):
        if context.space_data.view_type in {'SEQUENCER',
                                            'SEQUENCER_PREVIEW'}:
            strip = functions.act_strip(context)
            scn = context.scene
            preferences = context.preferences
            prefs = preferences.addons[__package__].preferences
            if scn and scn.sequence_editor and scn.sequence_editor.active_strip:
                if prefs.use_proxy_tools:
                    return strip.type in ('MOVIE')
        else:
            return False

    def draw_header(self, context):
        layout = self.layout
        layout.label(text="", icon="AUTO")

    def draw(self, context):

        preferences = context.preferences
        prefs = preferences.addons[__package__].preferences

        layout = self.layout
        layout.prop(prefs, "use_internal_proxy", text="Use BI proxy builder")

        strip = functions.act_strip(context)

        if prefs.use_internal_proxy:
            layout = self.layout
            row = layout.row(align=True)
            row.prop(prefs, "use_bi_custom_directory")

            if prefs.use_bi_custom_directory:
                row.prop(prefs, "proxy_dir", text="")
                filename = strip.filepath.rpartition("/")[2].rpartition(".")[0]
                layout.label(text="sample dir: //" + bpy.path.abspath(prefs.proxy_dir + filename))

            layout = self.layout
            col = layout.column()
            col.label(text="Build JPEG quality")
            col.prop(prefs, "quality")

            if strip.type == 'MOVIE':
                col = layout.column()
                col.label(text="Use timecode index:")

                col.prop(prefs, "timecode")

            layout = self.layout
            layout.label(text="Setup and create BI proxy:")
            row = layout.row(align=True)

            for i in range(4):
                proxysuffix = proxy_qualities[i][1]
                row.operator("sequencer.create_bi_proxy_operator",
                             text=proxysuffix).size = i + 1

            layout = self.layout
            layout.operator("sequencer.create_bi_proxy_operator",
                            text="Clear proxy sizes").size = 5

        else:
            layout = self.layout
            layout.prop(prefs, "proxy_dir", text="Path for proxies")

            layout = self.layout
            layout.label(text="Create and import proxy from clip:")
            row = layout.row(align=True)

            layout = self.layout
            layout.prop(prefs, "ffmpeg_command", text="command")

            layout.label(text="{} = filename, with, height, fileoutput")
            label = prefs.ffmpeg_command.format("filename", "with", "height", "fileoutput")
            layout.label(label)

            for i in range(4):
                proxysuffix = proxy_qualities[i][1]
                row.operator("sequencer.create_proxy_operator",
                             text=proxysuffix).size = i + 1

            layout = self.layout
            layout.prop(prefs, "proxy_scripts")

            if prefs.proxy_scripts:
                layout = self.layout
                layout.prop(prefs, "proxy_scripts_path", text="Path for scripts")

        layout = self.layout
        box = layout.box()
        box.prop(context.space_data, "proxy_render_size")
        box.operator("sequencer.rebuild_proxy", text="Rebuild Proxies and TC")
