# SPDX-FileCopyrightText: 2017-2022 Blender Foundation
#
# SPDX-License-Identifier: GPL-2.0-or-later

import bpy
from bpy.types import Menu
from . import utils_core


class TextureMenu(Menu):
    bl_label = "Texture Options"
    bl_idname = "VIEW3D_MT_sv3_texture_menu"

    @classmethod
    def poll(self, context):
        return utils_core.get_mode() in (
                        'SCULPT',
                        'VERTEX_PAINT',
                        'TEXTURE_PAINT'
                        )

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

        if utils_core.get_mode() == 'SCULPT':
            self.sculpt(layout, context)

        elif utils_core.get_mode() == 'VERTEX_PAINT':
            self.vertpaint(layout, context)

        else:
            self.texpaint(layout, context)

    def sculpt(self, layout, context):
        has_brush = utils_core.get_brush_link(context, types="brush")
        tex_slot = has_brush.texture_slot if has_brush else None

        # Menus
        layout.row().menu(Textures.bl_idname)
        layout.row().menu(TextureMapMode.bl_idname)
        layout.row().separator()

        # Checkboxes
        if tex_slot:
            if tex_slot.map_mode != '3D':
                if tex_slot.map_mode in ('RANDOM', 'VIEW_PLANE', 'AREA_PLANE'):
                    layout.row().prop(tex_slot, "use_rake", toggle=True)
                    layout.row().prop(tex_slot, "use_random", toggle=True)

                # Sliders
                layout.row().prop(tex_slot, "angle",
                                  text=utils_core.PIW + "Angle", slider=True)

                if tex_slot.map_mode in ('RANDOM', 'VIEW_PLANE') and tex_slot.use_random:
                    layout.row().prop(tex_slot, "random_angle",
                                      text=utils_core.PIW + "Random Angle", slider=True)

                # Operator
                if tex_slot.map_mode == 'STENCIL':
                    if has_brush.texture and has_brush.texture.type == 'IMAGE':
                        layout.row().operator("brush.stencil_fit_image_aspect")

                    layout.row().operator("brush.stencil_reset_transform")

        else:
            layout.row().label(text="No Texture Slot available", icon="INFO")

    def vertpaint(self, layout, context):
        has_brush = utils_core.get_brush_link(context, types="brush")
        tex_slot = has_brush.texture_slot if has_brush else None

        # Menus
        layout.row().menu(Textures.bl_idname)
        layout.row().menu(TextureMapMode.bl_idname)

        # Checkboxes
        if tex_slot:
            if tex_slot.map_mode != '3D':
                if tex_slot.map_mode in ('RANDOM', 'VIEW_PLANE'):
                    layout.row().prop(tex_slot, "use_rake", toggle=True)
                    layout.row().prop(tex_slot, "use_random", toggle=True)

                # Sliders
                layout.row().prop(tex_slot, "angle",
                                  text=utils_core.PIW + "Angle", slider=True)

                if tex_slot.map_mode in ('RANDOM', 'VIEW_PLANE') and tex_slot.use_random:
                    layout.row().prop(tex_slot, "random_angle",
                                      text=utils_core.PIW + "Random Angle", slider=True)

                # Operator
                if tex_slot.map_mode == 'STENCIL':
                    if has_brush.texture and has_brush.texture.type == 'IMAGE':
                        layout.row().operator("brush.stencil_fit_image_aspect")

                    layout.row().operator("brush.stencil_reset_transform")

        else:
            layout.row().label(text="No Texture Slot available", icon="INFO")

    def texpaint(self, layout, context):
        has_brush = utils_core.get_brush_link(context, types="brush")
        tex_slot = has_brush.texture_slot if has_brush else None
        mask_tex_slot = has_brush.mask_texture_slot if has_brush else None

        # Texture Section
        layout.row().label(text="Texture", icon='TEXTURE')

        # Menus
        layout.row().menu(Textures.bl_idname)
        layout.row().menu(TextureMapMode.bl_idname)

        # Checkboxes
        if tex_slot:
            if tex_slot.map_mode != '3D':
                if tex_slot.map_mode in ('RANDOM', 'VIEW_PLANE'):
                    layout.row().prop(tex_slot, "use_rake", toggle=True)
                    layout.row().prop(tex_slot, "use_random", toggle=True)

                # Sliders
                layout.row().prop(tex_slot, "angle",
                                  text=utils_core.PIW + "Angle", slider=True)

                if tex_slot.map_mode in ('RANDOM', 'VIEW_PLANE') and tex_slot.use_random:
                    layout.row().prop(tex_slot, "random_angle",
                                      text=utils_core.PIW + "Random Angle", slider=True)

                # Operator
                if tex_slot.map_mode == 'STENCIL':
                    if has_brush.texture and has_brush.texture.type == 'IMAGE':
                        layout.row().operator("brush.stencil_fit_image_aspect")

                    layout.row().operator("brush.stencil_reset_transform")

        else:
            layout.row().label(text="No Texture Slot available", icon="INFO")

        layout.row().separator()

        # Texture Mask Section
        layout.row().label(text="Texture Mask", icon='MOD_MASK')

        # Menus
        layout.row().menu(MaskTextures.bl_idname)
        layout.row().menu(MaskMapMode.bl_idname)
        layout.row().menu(MaskPressureModeMenu.bl_idname)

        # Checkboxes
        if mask_tex_slot:
            if mask_tex_slot.mask_map_mode in ('RANDOM', 'VIEW_PLANE'):
                layout.row().prop(mask_tex_slot, "use_rake", toggle=True)
                layout.row().prop(mask_tex_slot, "use_random", toggle=True)

            # Sliders
            layout.row().prop(mask_tex_slot, "angle",
                              text=utils_core.PIW + "Angle", icon_value=5, slider=True)

            if mask_tex_slot.mask_map_mode in ('RANDOM', 'VIEW_PLANE') and mask_tex_slot.use_random:
                layout.row().prop(mask_tex_slot, "random_angle",
                           text=utils_core.PIW + "Random Angle", slider=True)

            # Operator
            if mask_tex_slot.mask_map_mode == 'STENCIL':
                if has_brush.mask_texture and has_brush.mask_texture.type == 'IMAGE':
                        layout.row().operator("brush.stencil_fit_image_aspect")

                prop = layout.row().operator("brush.stencil_reset_transform")
                prop.mask = True

        else:
            layout.row().label(text="Mask Texture not available", icon="INFO")


class Textures(Menu):
    bl_label = "Brush Texture"
    bl_idname = "VIEW3D_MT_sv3_texture_list"

    def init(self):
        if utils_core.get_mode() == 'SCULPT':
            datapath = "tool_settings.sculpt.brush.texture"

        elif utils_core.get_mode() == 'VERTEX_PAINT':
            datapath = "tool_settings.vertex_paint.brush.texture"

        elif utils_core.get_mode() == 'TEXTURE_PAINT':
            datapath = "tool_settings.image_paint.brush.texture"

        else:
            datapath = ""

        return datapath

    def draw(self, context):
        datapath = self.init()
        has_brush = utils_core.get_brush_link(context, types="brush")
        current_texture = eval("bpy.context.{}".format(datapath)) if \
                          has_brush else None
        layout = self.layout

        # get the current texture's name
        if current_texture:
            current_texture = current_texture.name

        layout.row().label(text="Brush Texture")
        layout.row().separator()

        # add an item to set the texture to None
        utils_core.menuprop(layout.row(), "None", "None",
                 datapath, icon='RADIOBUT_OFF', disable=True,
                 disable_icon='RADIOBUT_ON',
                 custom_disable_exp=(None, current_texture),
                 path=True)

        # add the menu items
        for item in bpy.data.textures:
            utils_core.menuprop(layout.row(), item.name,
                     'bpy.data.textures["%s"]' % item.name,
                     datapath, icon='RADIOBUT_OFF',
                     disable=True,
                     disable_icon='RADIOBUT_ON',
                     custom_disable_exp=(item.name, current_texture),
                     path=True)


class TextureMapMode(Menu):
    bl_label = "Brush Mapping"
    bl_idname = "VIEW3D_MT_sv3_texture_map_mode"

    def draw(self, context):
        layout = self.layout
        has_brush = utils_core.get_brush_link(context, types="brush")

        layout.row().label(text="Brush Mapping")
        layout.row().separator()

        if has_brush:
            if utils_core.get_mode() == 'SCULPT':
                path = "tool_settings.sculpt.brush.texture_slot.map_mode"

                # add the menu items
                for item in has_brush. \
                  texture_slot.bl_rna.properties['map_mode'].enum_items:
                    utils_core.menuprop(
                            layout.row(), item.name, item.identifier, path,
                            icon='RADIOBUT_OFF',
                            disable=True,
                            disable_icon='RADIOBUT_ON'
                            )
            elif utils_core.get_mode() == 'VERTEX_PAINT':
                path = "tool_settings.vertex_paint.brush.texture_slot.map_mode"

                # add the menu items
                for item in has_brush. \
                  texture_slot.bl_rna.properties['map_mode'].enum_items:
                    utils_core.menuprop(
                            layout.row(), item.name, item.identifier, path,
                            icon='RADIOBUT_OFF',
                            disable=True,
                            disable_icon='RADIOBUT_ON'
                            )
            else:
                path = "tool_settings.image_paint.brush.texture_slot.map_mode"

                # add the menu items
                for item in has_brush. \
                  texture_slot.bl_rna.properties['map_mode'].enum_items:
                    utils_core.menuprop(
                            layout.row(), item.name, item.identifier, path,
                            icon='RADIOBUT_OFF',
                            disable=True,
                            disable_icon='RADIOBUT_ON'
                            )
        else:
            layout.row().label(text="No brushes available", icon="INFO")


class MaskTextures(Menu):
    bl_label = "Mask Texture"
    bl_idname = "VIEW3D_MT_sv3_mask_texture_list"

    def draw(self, context):
        layout = self.layout
        datapath = "tool_settings.image_paint.brush.mask_texture"
        has_brush = utils_core.get_brush_link(context, types="brush")
        current_texture = eval("bpy.context.{}".format(datapath)) if \
                          has_brush else None

        layout.row().label(text="Mask Texture")
        layout.row().separator()

        if has_brush:
            # get the current texture's name
            if current_texture:
                current_texture = current_texture.name

            # add an item to set the texture to None
            utils_core.menuprop(
                    layout.row(), "None", "None",
                    datapath, icon='RADIOBUT_OFF', disable=True,
                    disable_icon='RADIOBUT_ON',
                    custom_disable_exp=(None, current_texture),
                    path=True
                    )

            # add the menu items
            for item in bpy.data.textures:
                utils_core.menuprop(
                        layout.row(), item.name, 'bpy.data.textures["%s"]' % item.name,
                        datapath, icon='RADIOBUT_OFF', disable=True,
                        disable_icon='RADIOBUT_ON',
                        custom_disable_exp=(item.name, current_texture),
                        path=True
                        )
        else:
            layout.row().label(text="No brushes available", icon="INFO")


class MaskMapMode(Menu):
    bl_label = "Mask Mapping"
    bl_idname = "VIEW3D_MT_sv3_mask_map_mode"

    def draw(self, context):
        layout = self.layout
        path = "tool_settings.image_paint.brush.mask_texture_slot.mask_map_mode"
        has_brush = utils_core.get_brush_link(context, types="brush")

        layout.row().label(text="Mask Mapping")
        layout.row().separator()
        if has_brush:
            items = has_brush. \
                    mask_texture_slot.bl_rna.properties['mask_map_mode'].enum_items
            # add the menu items
            for item in items:
                utils_core.menuprop(
                        layout.row(), item.name, item.identifier, path,
                        icon='RADIOBUT_OFF',
                        disable=True,
                        disable_icon='RADIOBUT_ON'
                        )
        else:
            layout.row().label(text="No brushes available", icon="INFO")


class TextureAngleSource(Menu):
    bl_label = "Texture Angle Source"
    bl_idname = "VIEW3D_MT_sv3_texture_angle_source"

    def draw(self, context):
        layout = self.layout
        has_brush = utils_core.get_brush_link(context, types="brush")

        if has_brush:
            if utils_core.get_mode() == 'SCULPT':
                items = has_brush. \
                        bl_rna.properties['texture_angle_source_random'].enum_items
                path = "tool_settings.sculpt.brush.texture_angle_source_random"

            elif utils_core.get_mode() == 'VERTEX_PAINT':
                items = has_brush. \
                        bl_rna.properties['texture_angle_source_random'].enum_items
                path = "tool_settings.vertex_paint.brush.texture_angle_source_random"

            else:
                items = has_brush. \
                        bl_rna.properties['texture_angle_source_random'].enum_items
                path = "tool_settings.image_paint.brush.texture_angle_source_random"

            # add the menu items
            for item in items:
                utils_core.menuprop(
                        layout.row(), item[0], item[1], path,
                        icon='RADIOBUT_OFF',
                        disable=True,
                        disable_icon='RADIOBUT_ON'
                        )
        else:
            layout.row().label(text="No brushes available", icon="INFO")

class MaskPressureModeMenu(Menu):
    bl_label = "Mask Pressure Mode"
    bl_idname = "VIEW3D_MT_sv3_mask_pressure_mode_menu"

    def draw(self, context):
        layout = self.layout
        path = "tool_settings.image_paint.brush.use_pressure_masking"

        layout.row().label(text="Mask Pressure Mode")
        layout.row().separator()

        # add the menu items
        for item in context.tool_settings.image_paint.brush. \
          bl_rna.properties['use_pressure_masking'].enum_items:
            utils_core.menuprop(
                    layout.row(), item.name, item.identifier, path,
                    icon='RADIOBUT_OFF',
                    disable=True,
                    disable_icon='RADIOBUT_ON'
                    )


classes = (
    TextureMenu,
    Textures,
    TextureMapMode,
    MaskTextures,
    MaskMapMode,
    TextureAngleSource,
    MaskPressureModeMenu
    )

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

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