# Copyright (C) 2022 Thomas Hoppe (h0bB1T). All rights reserved.
#
# Unauthorized copying of this file via any medium is strictly prohibited.
# Proprietary and confidential.

import bpy
from typing import List, Tuple

from bpy.types import Panel, UILayout

from ..utils.dev import log_exception
from ..utils.io import decode_json
from ..properties import Properties
from ..operators.support_paint_command import UI_OT_support_paint_command


class NODE_PT_snw_side_panel_paint(Panel):
    bl_label = 'Paint Controls'
    bl_idname = 'NODE_PT_snw_side_panel_paint'
    bl_space_type = 'NODE_EDITOR'
    bl_region_type = 'UI'
    bl_category = 'Shader Node Wizard'

    @staticmethod
    def __get_node_info(tree: bpy.types.ShaderNodeTree) -> Tuple[str, str]:
        image, uv_map = None, None
        for n in tree.nodes:
            if n.bl_idname == 'ShaderNodeTexImage' and n.image:
                image = n.image.name
            elif n.bl_idname == 'ShaderNodeUVMap':
                uv_map = n.uv_map
            if image and uv_map:
                return (image, uv_map)

        return (None, None)


    @staticmethod
    def __get_paint_nodes(context: bpy.types.Context) -> List[Tuple[str, str]]:
        r = []
        if context.space_data.type == 'NODE_EDITOR' and \
            context.space_data.node_tree is not None  and \
            context.space_data.tree_type == 'ShaderNodeTree':

            tree = context.space_data.node_tree # type: bpy.types.ShaderNodeTree
            for n in tree.nodes:
                if n.bl_idname == 'ShaderNodeGroup':
                    try:
                        ni = decode_json(n.node_tree.snw_node_info)
                        if ni.get('type', '') == 'I':
                            image, uv_map = NODE_PT_snw_side_panel_paint.__get_node_info(n.node_tree)
                            if image and uv_map:
                                r.append((image, uv_map))
                    except Exception as e:
                        log_exception(e, context_msg="Failed to decode node info")
        
        return r


    @classmethod
    def poll(cls, context):
        return context.space_data.type == 'NODE_EDITOR' and \
            context.space_data.node_tree is not None  and \
            context.space_data.tree_type == 'ShaderNodeTree' and \
            NODE_PT_snw_side_panel_paint.__get_paint_nodes(context)


    def __paint_command(self, l: UILayout, text: str, icon: str, mode: str, image: str, uv_map: str):
        op = l.operator(UI_OT_support_paint_command.bl_idname, text=text, icon=icon)
        op.mode = mode
        op.image = image
        op.uv_map = uv_map


    def draw(self, context: bpy.types.Context):
        layout = self.layout
        props = Properties.get() # Properties

        c = layout.column(align=True)
        current = ''
        if context.mode == 'PAINT_TEXTURE':
            current = context.tool_settings.image_paint.canvas.name
        for p in sorted(NODE_PT_snw_side_panel_paint.__get_paint_nodes(context), key=lambda e: e[0]):
            self.__paint_command(
                c, 
                p[0], 
                'CHECKBOX_HLT' if current == p[0] else 'CHECKBOX_DEHLT', 
                'SET_IMAGE', 
                p[0], 
                p[1]
            )

        if context.mode == 'PAINT_TEXTURE':
            c.separator()
            self.__paint_command(c, 'Exit Painting', 'PANEL_CLOSE', 'EXIT', '', '')

