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

from typing import List
import bpy, traceback

from bpy.types import Operator, UILayout
from bpy.props import StringProperty, BoolProperty

from ..preferences import PreferencesPanel
from ..registries.asset_registry import AssetEntry
from ..utils.blender import set_active_object
from ..utils.asset_loader import load_collection, load_object


class ASSET_OT_import_3d_object(Operator):
    """
    Import collection or object.
    """
    bl_idname = 'awp.import_3d_object'
    bl_label = ''
    bl_description = ''
    bl_options = {'REGISTER', 'UNDO'}


    is_collection: BoolProperty() # type: ignore
    do_link: BoolProperty() # type: ignore
    filename: StringProperty() # type: ignore
    asset: StringProperty() # type: ignore
    desc: StringProperty() # type: ignore


    @classmethod
    def description(cls, context, properties):
        return f'{"Link" if properties.do_link else "Append"} {properties.asset} from Library and place it in Scene'


    def execute(self, context: bpy.types.Context):
        try:
            obj = load_collection(
                self.filename, 
                self.asset, 
                self.do_link, 
                True,
                PreferencesPanel.get().import_relative_paths
            ) if self.is_collection else load_object(
                self.filename, 
                self.asset, 
                self.do_link, 
                True,
                PreferencesPanel.get().import_relative_paths
            )

            if not self.is_collection:
                # In case of objects, add to scene/current
                bpy.context.scene.collection.objects.link(obj)

                # In link mode, we have to first create a library override.
                obj.select_set(True)

            # obj is either the imported object or the collection instance.
            # Following code is identical.

            # Deselect all other objects.
            [ o.select_set(o == obj) for o in bpy.context.selectable_objects ]

            # Make this the active object.
            set_active_object(obj)

            # Start placer.
            bpy.ops.awp.object_placer(
                'INVOKE_DEFAULT',
                placemode='place', 
                quick=True, 
                create_copy=False, 
                linked_copy=True, 
                auto_parent=False
            )

            return {'FINISHED'}
        except Exception as ex:
            print(traceback.format_exc())
            self.report({'ERROR'}, f'Asset loading failed, see Console ({ex})')
            return {'FINISHED'}


    def invoke(self, context, event):
        #x, y = event.mouse_x, event.mouse_y
        #bpy.context.window.cursor_warp(10, 10)
        #move_back = lambda: bpy.context.window.cursor_warp(x, y)
        #bpy.app.timers.register(move_back, first_interval=0.001)
        
        return self.execute(context)


    @staticmethod
    def create_ui(l: UILayout, asset: AssetEntry, link: bool, is_collection: bool):
        op = l.operator(
            ASSET_OT_import_3d_object.bl_idname, 
            #text='Link' if link else 'Append', 
            icon='DECORATE_LIBRARY_OVERRIDE' if link else 'ADD'
        ) # type: ASSET_OT_import_3d_object
        op.is_collection = is_collection
        op.do_link = link        
        op.filename = asset.blend
        op.asset = asset.name
        op.desc = asset.description
