# SPDX-FileCopyrightText: 2019-2023 Blender Foundation
#
# SPDX-License-Identifier: GPL-2.0-or-later

import bpy

from .functions import *
from .operators import *
from .preferences import *

# -----------------------------------------------------------------------------
# menu classes

class VIEW3D_MT_materialutilities_assign_material(bpy.types.Menu):
    """Menu for choosing which material should be assigned to current selection"""
    # The menu is filled programmatically with available materials

    bl_idname = "VIEW3D_MT_materialutilities_assign_material"
    bl_label = "Assign Material"

    def draw(self, context):
        layout = self.layout
        layout.operator_context = 'INVOKE_REGION_WIN'
        edit_mode = False

        materials = bpy.data.materials.items()

        bl_id = VIEW3D_OT_materialutilities_assign_material_object.bl_idname
        obj = context.object
        mu_prefs = materialutilities_get_preferences(context)

        if (not obj is None) and obj.mode == 'EDIT':
            bl_id = VIEW3D_OT_materialutilities_assign_material_edit.bl_idname
            edit_mode = True

        if len(materials) > mu_prefs.search_show_limit:
            op = layout.operator(bl_id,
                            text = 'Search',
                            icon = 'VIEWZOOM')
            op.material_name = ""
            op.new_material = False
            op.show_dialog = True
            if not edit_mode:
                op.override_type = mu_prefs.override_type

        op = layout.operator(bl_id,
                text = "Add New Material",
                icon = 'ADD')
        op.material_name = mu_new_material_name(mu_prefs.new_material_name)
        op.new_material = True
        op.show_dialog = True
        if not edit_mode:
            op.override_type = mu_prefs.override_type

        layout.separator()

        for material_name, material in materials:
            op = layout.operator(bl_id,
                    text = material_name,
                    icon_value = material.preview.icon_id)
            op.material_name = material_name
            op.new_material = False
            op.show_dialog = False
            if not edit_mode:
                op.override_type = mu_prefs.override_type


class VIEW3D_MT_materialutilities_clean_slots(bpy.types.Menu):
    """Menu for cleaning up the material slots"""

    bl_idname = "VIEW3D_MT_materialutilities_clean_slots"
    bl_label = "Clean Slots"

    def draw(self, context):
        layout = self.layout

        layout.label
        layout.operator(VIEW3D_OT_materialutilities_clean_material_slots.bl_idname,
                        text = "Clean Material Slots",
                        icon = 'X')
        layout.separator()
        layout.operator(VIEW3D_OT_materialutilities_remove_material_slot.bl_idname,
                        text = "Remove Active Material Slot",
                        icon = 'REMOVE')
        layout.operator(VIEW3D_OT_materialutilities_remove_all_material_slots.bl_idname,
                        text = "Remove All Material Slots",
                        icon = 'CANCEL')


class VIEW3D_MT_materialutilities_select_by_material(bpy.types.Menu):
    """Menu for choosing which material should be used for selection"""
    # The menu is filled programmatically with available materials

    bl_idname = "VIEW3D_MT_materialutilities_select_by_material"
    bl_label = "Select by Material"

    def draw(self, context):
        layout = self.layout

        bl_id = VIEW3D_OT_materialutilities_select_by_material_name.bl_idname
        obj = context.object
        mu_prefs = materialutilities_get_preferences(context)

        layout.label

        if obj is None or obj.mode == 'OBJECT':
            materials = bpy.data.materials.items()

            if len(materials) > mu_prefs.search_show_limit:
                layout.operator(bl_id,
                                text = 'Search',
                                icon = 'VIEWZOOM'
                                ).show_dialog = True

                layout.separator()

            #show all used materials in entire blend file
            for material_name, material in materials:
                # There's no point in showing materials with 0 users
                #  (It will still show materials with fake user though)
                if material.users > 0:
                    op = layout.operator(bl_id,
                                    text = material_name,
                                    icon_value = material.preview.icon_id
                                    )
                    op.material_name = material_name
                    op.show_dialog = False

        elif obj.mode == 'EDIT':
            objects = context.selected_editable_objects
            materials_added = []

            for obj in objects:
                #show only the materials on this object
                material_slots = obj.material_slots
                for material_slot in material_slots:
                    material = material_slot.material

                    # Don't add a material that's already in the menu
                    if material.name in materials_added:
                        continue

                    op = layout.operator(bl_id,
                                    text = material.name,
                                    icon_value = material.preview.icon_id
                                    )
                    op.material_name = material.name
                    op.show_dialog = False

                    materials_added.append(material.name)

class VIEW3D_MT_materialutilities_specials(bpy.types.Menu):
    """Spcials menu for Material Utilities"""

    bl_idname = "VIEW3D_MT_materialutilities_specials"
    bl_label = "Specials"

    def draw(self, context):
        mu_prefs = materialutilities_get_preferences(context)
        layout = self.layout

        #layout.operator(VIEW3D_OT_materialutilities_set_new_material_name.bl_idname, icon = "SETTINGS")

        #layout.separator()

        layout.operator(MATERIAL_OT_materialutilities_merge_base_names.bl_idname,
                        text = "Merge Base Names",
                        icon = "GREASEPENCIL")

        layout.operator(MATERIAL_OT_materialutilities_join_objects.bl_idname,
                        text = "Join by material",
                        icon = "OBJECT_DATAMODE")

        layout.separator()

        op = layout.operator(MATERIAL_OT_materialutilities_auto_smooth_angle.bl_idname,
                        text = "Set Auto Smooth",
                        icon = "SHADING_SOLID")
        op.affect = mu_prefs.set_smooth_affect
        op.angle = mu_prefs.auto_smooth_angle

class VIEW3D_MT_materialutilities_main(bpy.types.Menu):
    """Main menu for Material Utilities"""

    bl_idname = "VIEW3D_MT_materialutilities_main"
    bl_label = "Material Utilities"

    def draw(self, context):
        obj = context.object
        mu_prefs = materialutilities_get_preferences(context)

        layout = self.layout
        layout.operator_context = 'INVOKE_REGION_WIN'

        layout.menu(VIEW3D_MT_materialutilities_assign_material.bl_idname,
                     icon = 'ADD')
        layout.menu(VIEW3D_MT_materialutilities_select_by_material.bl_idname,
                     icon = 'VIEWZOOM')
        layout.separator()

        layout.operator(VIEW3D_OT_materialutilities_copy_material_to_others.bl_idname,
                         text = 'Copy Materials to Selected',
                         icon = 'COPY_ID')

        layout.separator()

        layout.menu(VIEW3D_MT_materialutilities_clean_slots.bl_idname,
                    icon = 'NODE_MATERIAL')

        layout.separator()
        layout.operator(VIEW3D_OT_materialutilities_replace_material.bl_idname,
                        text = 'Replace Material',
                        icon = 'OVERLAY')

        op = layout.operator(VIEW3D_OT_materialutilities_fake_user_set.bl_idname,
                       text = 'Set Fake User',
                       icon = 'FAKE_USER_OFF')
        op.fake_user = mu_prefs.fake_user
        op.affect = mu_prefs.fake_user_affect

        op = layout.operator(VIEW3D_OT_materialutilities_change_material_link.bl_idname,
                       text = 'Change Material Link',
                       icon = 'LINKED')
        op.link_to = mu_prefs.link_to
        op.affect = mu_prefs.link_to_affect
        layout.separator()

        layout.menu(VIEW3D_MT_materialutilities_specials.bl_idname,
                        icon = 'SOLO_ON')



def materialutilities_specials_menu(self, contxt):
    self.layout.separator()
    self.layout.menu(VIEW3D_MT_materialutilities_main.bl_idname)


def materialutilities_menu_move(self, context):
    layout = self.layout
    layout.operator_context = 'INVOKE_REGION_WIN'

    layout.operator(MATERIAL_OT_materialutilities_material_slot_move.bl_idname,
                    icon = 'TRIA_UP_BAR',
                    text = 'Move Slot to the Top').movement = 'TOP'
    layout.operator(MATERIAL_OT_materialutilities_material_slot_move.bl_idname,
                    icon = 'TRIA_DOWN_BAR',
                    text = 'Move Slot to the Bottom').movement = 'BOTTOM'
    layout.separator()

def materialutilities_menu_functions(self, context):
    layout = self.layout
    layout.operator_context = 'INVOKE_REGION_WIN'

    layout.separator()

    layout.menu(VIEW3D_MT_materialutilities_assign_material.bl_idname,
                 icon = 'ADD')
    layout.menu(VIEW3D_MT_materialutilities_select_by_material.bl_idname,
                 icon = 'VIEWZOOM')
    layout.separator()

    layout.separator()

    layout.menu(VIEW3D_MT_materialutilities_clean_slots.bl_idname,
                icon = 'NODE_MATERIAL')

    layout.separator()
    layout.operator(VIEW3D_OT_materialutilities_replace_material.bl_idname,
                    text = 'Replace Material',
                    icon = 'OVERLAY')

    layout.operator(VIEW3D_OT_materialutilities_fake_user_set.bl_idname,
                   text = 'Set Fake User',
                   icon = 'FAKE_USER_OFF')

    layout.operator(VIEW3D_OT_materialutilities_change_material_link.bl_idname,
                   text = 'Change Material Link',
                   icon = 'LINKED')
    layout.separator()

    layout.menu(VIEW3D_MT_materialutilities_specials.bl_idname,
                    icon = 'SOLO_ON')
