import bpy
from bpy.types import Panel
from pathlib import Path
from .prefs import get_addon_prefs
from .constant import RD_SCENE_NAME
# from .preferences import get_addon_prefs

# Node view panel
class GPEXP_PT_gp_node_ui(Panel):
    bl_space_type = "NODE_EDITOR"
    bl_region_type = "UI"
    # bl_category = "View"
    bl_category = "GP render"
    bl_label = "Gpencil Render Manager"

    def draw(self, context):
        prefs = get_addon_prefs()
        advanced = prefs.advanced
        layout = self.layout
        row = layout.row(align=True)
        row.operator('gp.render_scene_switch', icon='SCENE_DATA', text='Switch Scene')

        ## Check if there is another scene reference current scene in it's comp renderlayers
        ## If so, expose a button to go in (expensive check ?)
        node_scn = next((s for s in bpy.data.scenes
                      if s != context.scene and s.use_nodes
                      and next((n for n in s.node_tree.nodes if n.type == 'R_LAYERS' and n.scene == context.scene), None)
                      ),None)
        if node_scn:
            row.operator('gp.render_scene_switch', icon='NODETREE', text='Node Scene').scene = node_scn.name

        scn = context.scene

        ## Camera swapping
        row = layout.row()
        cam = scn.camera
        if cam:
            text = f'{cam.name} : {scn.render.resolution_x}x{scn.render.resolution_y}' # Cam:
        else:
            text = f'None' # Cam:

        # if cam and cam_name == 'draw_cam':
        #     cam_name = f'{cam.parent.name} > {cam_name}'
        row.operator("gp.swap_render_cams", text=text, icon='OUTLINER_OB_CAMERA')

        # Live checks
        if scn.render.resolution_percentage != 100:
            layout.label(text='Res Percentage not 100%', icon='ERROR')
            layout.prop(scn.render, 'resolution_percentage')

        exclude_count = len([vl for vl in scn.view_layers if not vl.use and vl.name not in {'View Layer', 'exclude'}])
        if exclude_count:
            # layout.label(text=f'{exclude_count} Excluded View Layers !')
            layout.operator('gp.enable_all_viewlayers', text=f'Reactivate {exclude_count} Excluded View Layers')


        if not scn.use_nodes or not scn.node_tree:
            return

        disabled_output = [n for n in scn.node_tree.nodes if n.type == 'OUTPUT_FILE' and n.mute]
        if disabled_output:
            output_ct = len([n for n in scn.node_tree.nodes if n.type == 'OUTPUT_FILE'])
            layout.label(text=f'{len(disabled_output)}/{output_ct} Output Muted', icon='INFO')

        layout.separator()

        layout.label(text='View layers:')
        ct = len([n for n in context.scene.node_tree.nodes if n.type == 'R_LAYERS' and n.select])

        # col = layout.column(align=True)
        # row=col.row(align=True)
        row=layout.row(align=True)

        row1 = row.row(align=True)
        row1.operator('gp.activate_only_selected_layers', text=f'Activate Only {ct} Layer Nodes')
        row1.enabled = ct > 0

        row2=row.row(align=True)
        row2.operator("wm.call_panel", text="", icon='RENDERLAYERS').name = "GPEXP_PT_viewlayers_ui"
        row2.operator("wm.call_panel", text="", icon='SCENE_DATA').name = "GPEXP_PT_viewlayers_multi_ui"
        # row2.operator("gp.viewlayer_popup", text="", icon='RENDERLAYERS') # Ops invoke hack
        # row2.operator("wm.call_menu", text="", icon='RENDERLAYERS').name = "GPEXP_MT_viewlayers_popup" # Bad menu

        if advanced:
            col = layout.column(align=True)
            txt = f'Merge {ct} Layer Nodes'
            col.operator('gp.merge_selected_viewlayer_nodes', icon='NODETREE', text=txt).disconnect = True
            col.operator('gp.merge_selected_viewlayer_nodes', icon='NODETREE', text='Merge (keep connect)').disconnect = False
            col.enabled = ct > 1

        layout.separator()
        col = layout.column()
        subcol = col.column()
        n = context.scene.node_tree.nodes.active
        if n:
            subcol.enabled = n and n.type == 'R_LAYERS' and not n.outputs[0].is_linked
        else:
            subcol.enabled = False

        subcol.operator('gp.reconnect_render_layer', icon='ANIM', text=f'Reconnect {ct} Layer Node')

        col.operator('gp.delete_render_layer', icon='TRACKING_CLEAR_FORWARDS', text=f'Delete {ct} Layer Node')

        layout.separator()

        layout.label(text='All Outputs:')
        row=layout.row()
        row.operator('gp.mute_toggle_output_nodes', icon='NODE_INSERT_ON', text='Mute').mute = True
        row.operator('gp.mute_toggle_output_nodes', icon='NODE_INSERT_OFF', text='Unmute').mute = False

        layout.separator()

        col=layout.column()
        col.label(text='Clean and updates:')


        col.separator()

        col.operator('gp.clean_compo_tree', icon='BRUSHES_ALL', text='Clean Nodes') # NODE_CORNER
        col.operator('gp.reset_render_settings', icon='SCENE', text='Reset All Scenes Render Settings')
        col.operator('gp.check_render_scene', icon='PRESET', text='Check For Problems')

        col.separator()

        ## (re)number exports
        ct = len([n for n in context.scene.node_tree.nodes if n.type == 'OUTPUT_FILE' and n.select])
        txt = f'Renumber {ct} Selected Outputs'
        subcol = col.column()
        subcol.enabled = bool(ct)
        
        row = subcol.row(align=True)
        row.operator('gp.number_outputs', icon='LINENUMBERS_ON', text=txt).mode = 'SELECTED'
        op = row.operator('gp.number_outputs', icon='X', text='')
        op.mode = 'SELECTED'
        op.clear = True

        ## Set / remove preview
        row=layout.row(align=True)
        row.operator('gp.merge_preview_ouput', icon='NODETREE', text='Set Preview')
        row.operator('gp.merge_preview_ouput', icon='X', text='').clear = True
        # subcol.operator('gp.normalize_outnames', icon='SYNTAX_OFF', text=f'Normalize Paths {ct} Selected Ouptut') # not ready
        # col.operator('gp.number_outputs', icon='LINENUMBERS_ON', text='Renumber all outputs').mode = 'ALL'

        if advanced:
            subcol.operator('gp.set_output_node_format', icon='OUTPUT', text='Copy Active Output Format')
            subcol.operator('gp.set_active_fileout_to_compout', icon='OUTPUT', text='Active Slot to Composite')

        col.operator('gp.connect_selected_to_file_out', icon='OUTPUT', text='Connect Selection To Ouput')

        layout.separator()

        col=layout.column()
        col.label(text='Delete Options:')
        if advanced:
            col.operator('gp.clear_render_tree', icon='X', text='Clear Framed Nodes')
        col.operator('gp.clear_render_tree', icon='X', text='Clear & Delete Render Scene').mode = "COMPLETE"

        layout.separator()
        layout.label(text='Scenes:')
        row = layout.row(align=True)
        row.operator('gp.split_to_scene', icon='DUPLICATE', text='Split Selection To Scene').mode = 'ALL'
        row.operator('gp.split_to_scene', text='Split Individually').mode = 'INDIVIDUAL'

        row = layout.row(align=True)
        row.operator('gp.set_crop_from_selection', icon='CON_OBJECTSOLVER', text='Autoset Crop')
        row.operator('gp.export_crop_coord_to_json', icon='FILE', text='Export json')

        layout.label(text='Render:')
        row = layout.row(align=True)
        row.operator('gp.render_selected_scenes', icon='RENDER_ANIMATION', text='Render Selected Scene')
        row.operator('gp.bg_render_script_selected_scenes', icon='TEXT', text='Gen Batch')
        # row.operator('gp.render_all_scenes', icon='RENDER_ANIMATION', text='Render All')

        if advanced:
            layout.separator()
            col = layout.column()
            col.label(text='Post-Render:')
            col.operator('gp.renumber_files_on_disk', icon='FILE', text='Renumber Files On Disk')

        layout.prop(context.scene.gp_render_settings, 'use_aa', text='Use Native AA Settings')
        layout.prop(prefs, 'advanced', text='Show Advanced Options')
        # layout.operator('gp.add_object_to_render', icon='RENDERLAYERS', text='Layer To Render').mode = 'ALL'
        # layout.operator('gp.add_object_to_render', icon='RENDERLAYERS', text='Layer To Render').mode = 'SELECTED'

        # layout.operator('gp.merge_layers', icon='X', text='Merge selected nodes')

class GPEXP_PT_gp_dopesheet_ui(Panel):
    bl_space_type = 'DOPESHEET_EDITOR'
    bl_region_type = 'UI'
    bl_category = "GP Render"
    # bl_parent_id='DOPESHEET_PT_gpencil_mode'
    bl_label = "Gpencil Render Manager"

    @classmethod
    def poll(cls, context):
        return context.object and context.object.type == 'GPENCIL'

    def draw(self, context):
        layout = self.layout
        settings = context.scene.gp_render_settings
        
        icon = 'DISCLOSURE_TRI_DOWN' if  settings.show_scene_setup else 'DISCLOSURE_TRI_RIGHT'
        col = layout.column()
        col.prop(settings, 'show_scene_setup', icon=icon, text='Scenes Setup', emboss=False )
        if settings.show_scene_setup:
            col.prop(settings, 'render_scene', icon='SCENE_DATA', placeholder=RD_SCENE_NAME)

            nodetree_placeholder = settings.render_scene or RD_SCENE_NAME
            col.prop(settings, 'node_scene', icon='NODETREE', placeholder=nodetree_placeholder)

        op = layout.operator('gp_export.render_auto_build')
        op.node_scene = settings.node_scene

        if context.object:
            layout.label(text=f'Object: {context.object.name}')
            if context.object.data.users > 1:
                row = layout.row()
                row.label(text=f'Multiple users ({context.object.data.users})', icon='ERROR')
                row.operator("wm.call_menu", text="", icon='QUESTION').name = "GPEXP_MT_multi_user_doc"
            if context.object.data.layers.active:
                layout.label(text=f'viewlayer: {context.object.data.layers.active.viewlayer_render}')
            else:
                layout.label(text=f'No active layer found')
                layout.label(text=f'(Active dopesheet layer not in active obj)')

        ## On layers
        col = layout.column()
        col.operator('gp.select_layer_in_comp', icon='RESTRICT_SELECT_OFF', text='Select Nodes')
        if context.object and context.object.type == 'GPENCIL':
            txt = f'{len([l for l in context.object.data.layers if l.select])} Layer(s) To Render'
        else:
            txt = 'Layer To Render'

        op = col.operator('gp.add_layer_to_render', icon='RENDERLAYERS', text=txt)
        op.node_scene = settings.node_scene


        # merge (only accessible if multiple layers selected)
        row = col.row()
        ct = len([l for l in context.object.data.layers if l.select])
        txt = f'Merge {ct} layers'
        # merge layers from dopesheet
        row.operator('gp.merge_viewlayers_to_active', text=txt, icon='SELECT_EXTEND').multi_object_merge = True
        ct = len([l for ob in context.selected_objects if ob.type == 'GPENCIL' for l in ob.data.layers if l.select])
        txt = f'Multi: {ct} layers'
        row.operator('gp.merge_viewlayers_to_active', text=txt, icon='SELECT_EXTEND').multi_object_merge = True
        row.enabled= ct > 1

        col.operator('gpexp.auto_merge_adjacent_prefix', icon='SELECT_EXTEND')
        row = col.row(align=True)
        row.operator('gp.remove_viewlayer_on_selected', text=f'Exclude {ct} layers', icon='X').remove_all_hidden = False
        row.operator('gp.remove_viewlayer_on_selected', text='', icon='HIDE_ON').remove_all_hidden = True

        ## all and objects
        layout.separator()

        col = layout.column()
        col.label(text='Whole Objects:')
        txt = f'{len([o for o in context.selected_objects if o.type == "GPENCIL" and o.select_get()])} Selected Object(s) To Render'
        
        op = col.operator('gp.add_object_to_render', icon='RENDERLAYERS', text=txt)
        op.mode='SELECTED'
        op.node_scene = settings.node_scene

        op = col.operator('gp.add_object_to_render', icon='RENDERLAYERS', text='All Visible GP To Render')
        op.mode='ALL'
        op.node_scene = settings.node_scene

        layout.separator()
        col = layout.column()
        col.label(text='Fixes:')
        row = col.row(align=True)
        row.operator('gp.auto_number_object', icon='OBJECT_DATAMODE', text='Renumber Objects')
        row.operator('gp.auto_number_object', icon='X', text='').delete = True
        col.operator('gp.lower_layers_name', icon='SYNTAX_OFF', text='Rename Lowercase')
        col.operator('gp.export_infos_for_compo', icon='FILE', text='Export Layers Infos') # Not really need, called in Check layers invoke

        row = layout.row(align=True)
        row.operator('gp.layers_state', icon='CHECKMARK', text='Check layers')
        row.operator('gp.restore_layers_state', icon='DECORATE_OVERRIDE', text='')

        col.operator('gp.check_masks', icon='MOD_MASK', text='Has Masks')

        # row = layout.row()
        layout.prop(bpy.context.preferences.edit, 'use_anim_channel_group_colors')

        layout.separator()
        
        # row.operator('gp.export_as_pdf', icon='RENDER_STILL', text='Render All to PDF Sequences')
        layout.label(text='Render All To Vector:')
        col= layout.column()
        row = col.row(align=True)
        row.operator('gp.export_as_pdf', icon='RENDER_STILL', text='PDF Sequences').export_type = 'pdf_sequence'
        row.operator('gp.export_as_pdf', icon='RENDER_STILL', text='PDF File').export_type = 'pdf'
        col.operator('gp.export_as_pdf', icon='RENDER_STILL', text='SWF File').export_type = 'swf'

        if bpy.app.version < (3,0,0):
            col.label(text='Not Blender 3.0.0+ !')

        ## Append GP Render workspace (usefull for user with disabled 'load_UI')
        if not bpy.data.workspaces.get('GP Render'):
            layout.operator('gp.set_gp_render_workspace')


class GPEXP_MT_multi_user_doc(bpy.types.Menu):
    bl_label = "Case of multiuser objects"

    def draw(self, context):
        layout = self.layout
        # call another menu
        #layout.operator("wm.call_menu", text="Unwrap").name = "VIEW3D_MT_uv_map"
        #**Behavior from context mode**
        col = layout.column()
        col.label(text='Multi user data will be rendered all together on last generated viewlayers.', icon='INFO')
        col.label(text='Make them single user if needed to render separately.')
        # col.label(text='Select objects > call search pop-up (F3) > "Make single user" > tick "object data" > ok')
        col.label(text='Procedure:')

        col.label(text='- select concerned objects')
        col.label(text='- call search pop-up (F3)')
        col.label(text='- search "Make single user"')
        col.label(text='- tick only "object data"')


def viewlayer_layout(layout, scn):
    for vl in scn.view_layers:
        row = layout.row()
        row.prop(vl, 'use', text=vl.name, icon='RESTRICT_RENDER_OFF' if vl.use else 'RESTRICT_RENDER_ON', emboss=False, toggle=0)
        # row.prop(vl, 'use', text=vl.name, icon='RESTRICT_RENDER_OFF', emboss=False)

## Can only toggle one with a menu
# class GPEXP_MT_viewlayers_popup(bpy.types.Menu):
#     bl_label = "View Layers"
#     def draw(self, context):
#         layout = self.layout
#         viewlayer_layout(layout, context)

class GPEXP_PT_viewlayers_ui(Panel):
    bl_space_type = "NODE_EDITOR"
    bl_region_type = "UI"
    bl_label = "View Layers"

    def draw(self, context):
        layout = self.layout
        layout.label(text=f'{context.scene.name} :: View layers')
        col = layout.column(align=True)
        viewlayer_layout(col, context.scene)

class GPEXP_PT_viewlayers_multi_ui(Panel):
    bl_space_type = "NODE_EDITOR"
    bl_region_type = "UI"
    bl_label = "Multi View Layers"

    def draw(self, context):
        layout = self.layout
        layout.label(text=f'{len(bpy.data.scenes)} scenes :: View layers')
        for s in bpy.data.scenes:
            col = layout.column()
            col.label(text=f'{s.name}::')
            viewlayer_layout(col, s)
            layout.separator()

class GPEXP_OT_viewlayer_popup_invoke(bpy.types.Operator):
    bl_idname = "gp.viewlayer_popup"
    bl_label = "Viewlayer Popup"
    bl_description = "Pop up menu for toggling viewlayers"
    bl_options = {"REGISTER",}

    def invoke(self, context, event):
        return context.window_manager.invoke_props_dialog(self)

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

    def execute(self, context):
        return {"FINISHED"}


## not registered for now (better to place render menu in GP dopesheet)
def manager_ui(self, context):
    '''appended to DATA_PT_gpencil_layers'''

    layout = self.layout

    ## On layers
    if context.object and context.object.type == 'GPENCIL':
        txt = f'{len([l for l in context.object.data.layers if l.select])} Layer(s) To Render'
    else:
        txt = 'Layer To Render'
    layout.operator('gp.add_layer_to_render', icon='RENDERLAYERS', text=txt)

    ## On objects
    # txt = 'Selected Object To Render'
    # if context.scene.name != RD_SCENE_NAME:
    txt = f'{len([o for o in context.selected_objects if o.type == "GPENCIL" and o.select_get()])} Selected Object(s) To Render'
    layout.operator('gp.add_object_to_render', icon='RENDERLAYERS', text=txt).mode='SELECTED'

    layout.operator('gp.add_object_to_render', icon='RENDERLAYERS', text='All GP at once').mode='ALL'


# ## function to append in a menu
# def palette_manager_menu(self, context):
#     """Palette menu to append in existing menu"""
#     # GPENCIL_MT_material_context_menu
#     layout = self.layout
#     # {'EDIT_GPENCIL', 'PAINT_GPENCIL','SCULPT_GPENCIL','WEIGHT_GPENCIL', 'VERTEX_GPENCIL'}
#     layout.separator()
#     prefs = get_addon_prefs()

#     layout.operator("", text='do stuff from material submenu', icon='MATERIAL')

#-# REGISTER

classes=(
GPEXP_PT_viewlayers_ui,
GPEXP_PT_viewlayers_multi_ui,
GPEXP_OT_viewlayer_popup_invoke,
GPEXP_MT_multi_user_doc,
GPEXP_PT_gp_node_ui,
GPEXP_PT_gp_dopesheet_ui,
)

def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    # bpy.types.DATA_PT_gpencil_layers.prepend(manager_ui)

def unregister():
    # bpy.types.DATA_PT_gpencil_layers.remove(manager_ui)
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)