import bpy
from .. import utils
from ..utils import create_grab_constraint
from ..cAPI import SimulationAPI
class HI_PHY_OT_GrabConstraintGrab(bpy.types.Operator):
    bl_idname = "hi_phy.grab_constraint_grab"
    bl_label = "Hi Phy Grab Constraint Grab"
    bl_options = {'REGISTER', 'UNDO_GROUPED'}

    grab_constraint: bpy.props.StringProperty(name="Grab Constraint")

    def execute(self, context):
        # When grabing we are going to create a series of point constraints parented under the grab constraint
        depsgraph = bpy.context.evaluated_depsgraph_get()
        grab_constraint_obj = bpy.data.objects[self.grab_constraint].evaluated_get(depsgraph)
        if (not grab_constraint_obj.hi_phy.is_active or
            grab_constraint_obj.hi_phy.object_type != "CONSTRAINT" or
            grab_constraint_obj.hi_phy.constraint_type != SimulationAPI.ConstraintType.GrabConstraint):
            self.report({"ERROR"}, self.grab_constraint.name + " is not a HiPhy grab constraint")
            return {'CANCELLED'}
        constraint_objects = []
        if (grab_constraint_obj.hi_phy.grab_constraint_apply_to_all):
            for obj in bpy.context.scene.objects:
                # we will not try to grab soft colliders
                if utils.isSimulationObject(obj) and obj.hi_phy.object_type != "SOFT_COLLIDER":
                    constraint_objects.append((obj, 1.0))
        else:
            for o in grab_constraint_obj.hi_phy.grab_constraint_object_list:
                constraint_objects.append((o.obj, o.weight))
        for obj, weight in constraint_objects:
            if (not create_grab_constraint.create(grab_constraint_obj, obj.evaluated_get(depsgraph), weight, "hi_phy_" + self.grab_constraint + "_grab_" + obj.name, self)):
                return {'CANCELLED'}
        return {'FINISHED'}
 
class HI_PHY_OT_GrabConstraintRelease(bpy.types.Operator):
    bl_idname = "hi_phy.grab_constraint_release"
    bl_label = "Hi Phy Grab Constraint Release"
    bl_options = {'REGISTER', 'UNDO_GROUPED'}

    grab_constraint: bpy.props.StringProperty(name="Grab Constraint")

    def execute(self, context):
        grab_constraint_obj = bpy.data.objects[self.grab_constraint]
        if not create_grab_constraint.release(grab_constraint_obj, self):
            return {'CANCELLED'}            
        return {'FINISHED'}

__CLASSES__ = [
    HI_PHY_OT_GrabConstraintGrab,
    HI_PHY_OT_GrabConstraintRelease,
]

def register():
    for class_ in __CLASSES__:
        bpy.utils.register_class(class_)

def unregister():
    for class_ in reversed(__CLASSES__):
        bpy.utils.unregister_class(class_)
