# ##### BEGIN GPL LICENSE BLOCK #####
#
#  Copyright (C) 2022 VFX Grace - All Rights Reserved
#
#  This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <https://www.gnu.org/licenses/>.
#
# ##### END GPL LICENSE BLOCK #####

import bpy
from bpy.types import Panel, UIList, UILayout, Menu
from bl_ui.properties_particle import particle_get_settings
from .operators import (PARTICLE_OT_AddModifier, PARTICLE_OT_CopyModifier,
                        PARTICLE_OT_RemoveModifier, PARTICLE_OT_MoveModifier,
                        PARTICLE_OT_AssignVertexGroup, PARTICLE_OT_MakeCurveSingle,
                        PARTICLE_OT_VertexGroupOperation)
from .props import MODIFIER_TYPES


class PARTICLE_UL_child_modifiers(UIList):
    def draw_item(self, context, layout: UILayout, data, item, icon, active_data, active_propname, index):
        row = layout.row()
        row.prop(item, "name", text="", emboss=False, icon_value=UILayout.enum_item_icon(item, "type", item.type))
        row.prop(item, "enabled", icon='CHECKBOX_HLT' if item.enabled else 'CHECKBOX_DEHLT',
                 icon_only=True, emboss=False)


class PARTICLE_MT_child_modifiers_context_menu(Menu):
    bl_label = "Child Modifiers Menu"

    def draw(self, context):
        layout = self.layout
        layout.operator(PARTICLE_OT_CopyModifier.bl_idname, icon='DUPLICATE')
        layout.operator(PARTICLE_OT_MakeCurveSingle.bl_idname)


class PARTICLE_PT_child_modifer(Panel):
    bl_label = "Modifier"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "particle"
    bl_parent_id = "PARTICLE_PT_children"
    bl_options = {'DEFAULT_CLOSED'}

    @classmethod
    def poll(cls, context):
        part = particle_get_settings(context)
        return part and part.child_type != 'NONE'

    def draw_header(self, context):
        part = particle_get_settings(context)
        self.layout.prop(part.child_modifier, "use_child_modifier", text="")

    def draw(self, context):
        layout = self.layout
        part = particle_get_settings(context)
        child_modifier = part.child_modifier
        layout.enabled = child_modifier.use_child_modifier

        row = layout.row()
        rows = 3
        if child_modifier.modifiers:
            rows = 5
        row.template_list("PARTICLE_UL_child_modifiers", "", child_modifier, "modifiers", child_modifier,
                          "active_index", rows=rows, sort_lock=True)

        col = row.column(align=True)
        col.operator_menu_enum(PARTICLE_OT_AddModifier.bl_idname, "type", text="", icon='ADD')
        col.operator(PARTICLE_OT_RemoveModifier.bl_idname, icon='REMOVE', text="")
        col.separator()
        col.menu("PARTICLE_MT_child_modifiers_context_menu", icon='DOWNARROW_HLT', text="")
        if child_modifier.modifiers:
            col.separator()
            col.operator(PARTICLE_OT_MoveModifier.bl_idname, icon='TRIA_UP', text="").direction = 'UP'
            col.operator(PARTICLE_OT_MoveModifier.bl_idname, icon='TRIA_DOWN', text="").direction = 'DOWN'

            assert 0 <= child_modifier.active_index < len(child_modifier.modifiers)

            mod = child_modifier.modifiers[child_modifier.active_index]
            if mod.type in MODIFIER_TYPES:
                layout.use_property_split = True

                # Common props
                col = layout.column(align=True)
                row = col.row(align=True)
                row.prop(mod, "influence")
                influence_mask = mod.influence_mask
                if influence_mask.vertex_group:
                    sub_row = col.row(align=True)
                    sub_row.prop_search(influence_mask, "vertex_group", context.object, "vertex_groups", text="└─")
                    sub_row.prop_enum(mod, "mask_invert_flag", 'INFLUENCE', text="", icon="ARROW_LEFTRIGHT")
                else:
                    props = row.operator(PARTICLE_OT_AssignVertexGroup.bl_idname, text="", icon="GROUP_VERTEX")
                    props.prop_path = influence_mask.path_from_id()
                row.prop(influence_mask, "use_texture", text="", icon='TEXTURE_DATA')
                if influence_mask.use_texture:
                    obj = context.object
                    if obj and obj.type == 'MESH' and obj.data.uv_layers.active is None:
                        row = col.row()
                        row.alignment = 'CENTER'
                        row.label(text="UV Map Needed", icon='ERROR')
                    else:
                        sub_row = col.row(align=True)
                        sub_row.prop(influence_mask, "texture", text="└─")
                        prop_path = influence_mask.path_from_id()
                        if influence_mask.texture:
                            sub_row.prop_enum(mod, "tex_invert_flag", 'INFLUENCE', text="", icon="ARROW_LEFTRIGHT")
                            sub_row.operator("particle.edit_texture", text="", icon='OPTIONS').prop_path = prop_path
                            if influence_mask.texture.type == 'IMAGE':
                                props = sub_row.operator("particle.edit_texture", text="", icon='TPAINT_HLT')
                                props.prop_path = prop_path
                                props.edit_image = True
                        else:
                            sub_row.operator("particle.add_texture", text="", icon='ADD').prop_path = prop_path

                col.prop(mod, "seed")
                MODIFIER_TYPES[mod.type].draw_influence_threshold(mod, col)

                MODIFIER_TYPES[mod.type].draw(mod, context, layout)


def draw_vertex_group_operation(self, context):
    if context.object and context.object.vertex_groups:
        row = self.layout.row(align=True)
        row.operator(PARTICLE_OT_VertexGroupOperation.bl_idname, text="Rename Vertex Group").option = 0
        row.operator(PARTICLE_OT_VertexGroupOperation.bl_idname, text="Remove Vertex Group").option = 1


classes = [PARTICLE_UL_child_modifiers, PARTICLE_MT_child_modifiers_context_menu, PARTICLE_PT_child_modifer]


def register():
    from bpy.utils import register_class
    for cls in classes:
        register_class(cls)
    bpy.types.DATA_PT_vertex_groups.append(draw_vertex_group_operation)


def unregister():
    from bpy.utils import unregister_class
    bpy.types.DATA_PT_vertex_groups.remove(draw_vertex_group_operation)
    for cls in reversed(classes):
        unregister_class(cls)
