@tool
extends Function
class_name Movable

signal on_move(position: Vector3, rotation: Vector3)
signal on_moved()

@export var restricted: bool = false
@export var restrict_movement: Callable
@export var lock_rotation: bool = false
var hit_node := Node3D.new()

func _on_grab_down(event: EventPointer):
	if restricted && event.target != get_parent():
		return

	event.initiator.node.add_child(hit_node)
	hit_node.global_transform = get_parent().global_transform

func _on_grab_move(_event: EventPointer):
	if hit_node.get_parent() == null:
		return
	
	if restrict_movement:
		get_parent().global_position = restrict_movement.call(hit_node.global_position)
	else:
		get_parent().global_position = hit_node.global_position

	if !lock_rotation:
		get_parent().global_basis = hit_node.global_basis
		on_move.emit(get_parent().global_position, get_parent().global_rotation)
	else:
		on_move.emit(get_parent().global_position, Vector3(0, 0, 0))

func _on_grab_up(event: EventPointer):
	event.initiator.node.remove_child(hit_node)
	on_moved.emit()

func _get_configuration_warnings() -> PackedStringArray:
	var warnings := PackedStringArray()

	if get_parent() is StaticBody3D == false:
		warnings.append("Movable requires a StaticBody3D as parent.")
	

	return warnings
