import bpy
from .utils_debug import getLogPrefix, getTimestamp

def markDeletable(obj, deletable):
    if hasattr(obj, "NEEDLE_deletable"):
        obj.NEEDLE_deletable = deletable
    else:
        obj["NEEDLE_deletable"] = deletable

def deleteObjectsRecursive(objects):
    for obj in objects:
        deleteObject(obj, True)
    pass

def deleteObject(obj, recursive: bool = False):
    if hasattr(obj, "NEEDLE_deletable"):
        if obj.NEEDLE_deletable == False:
            return
    if recursive:
        if hasattr(obj, "node_tree"):
            node_tree = obj.node_tree
            for node in node_tree.nodes:
                deleteObject(node, recursive=True)
        if hasattr(obj, "texture_slots"):
            texture_slots = obj.texture_slots
            for texture_slot in texture_slots:
                deleteObject(texture_slot, recursive=True)
        if hasattr(obj, "texture"):
            texture = obj.texture
            deleteObject(texture, recursive=True)
        if hasattr(obj, "image"):
            image = obj.image
            deleteObject(image, recursive=True)
        if hasattr(obj, "materials"):
            materials = obj.materials
            for material in materials:
                deleteObject(material, recursive=True)
        if hasattr(obj, "data"):
            data = obj.data
            deleteObject(data, recursive=True)
    try:
        if hasattr(obj, "name"):
            print(getLogPrefix() + "Deleting object: " + obj.name, getattr(obj, "type", "unknown type"))
        if isinstance(obj, bpy.types.Object):
            bpy.data.objects.remove(obj, do_unlink=True)
        elif isinstance(obj, bpy.types.Mesh):
            bpy.data.meshes.remove(obj, do_unlink=True)
        elif isinstance(obj, bpy.types.Material):
            bpy.data.materials.remove(obj, do_unlink=True)
        elif isinstance(obj, bpy.types.Texture):
            bpy.data.textures.remove(obj, do_unlink=True)
        elif isinstance(obj, bpy.types.Image):
            bpy.data.images.remove(obj, do_unlink=True)
        elif isinstance(obj, bpy.types.ImageTexture):
            bpy.data.textures.remove(obj, do_unlink=True)
    except Exception as e:
        print("Error removing object:\n", e)


def createQuad(material: bpy.types.Material | None):
    prev_active = bpy.context.active_object
    bpy.ops.mesh.primitive_plane_add(location=(0, 0, 0))
    quad = bpy.context.active_object
    # restore previous selection
    bpy.context.view_layer.objects.active = prev_active
    if material is not None:
        assignMaterial(material, quad)
    return quad

def assignMaterial(material : bpy.types.Material, blender_object : bpy.types.Object):
    if blender_object is not None:
        if blender_object.data.materials:
            # assign to 1st material slot
            blender_object.data.materials[0] = material
        else:
            # no slots
            blender_object.data.materials.append(material)




def linkMeshData(objects:list) -> bool:
    '''
    Links the mesh data of all objects to the first object in the list.
    '''
    if len(objects) < 2:
        print("Need at least 2 objects to link mesh data")
        return False
    
    mesh = None
    for i in range(0, len(objects)):
        obj = objects[i]
        if not hasattr(obj, "data"):
            print("Object \"" + obj.name + "\" has no data (is it not a mesh?)")
            continue
        if not obj.type == "MESH":
            print("Object \"" + obj.name + "\" is not a mesh")
            continue
        if mesh is None:
            mesh = obj.data
            continue
        active_material = obj.active_material
        obj.material_slots[0].link = "OBJECT"
        obj.material_slots[0].material = active_material
        obj.data = mesh
    return mesh is not None
