# a vector field manipulator that can be picked up and radius resized by the
# holding controller's joystick.
# needs a VisualAttractorSphere child node to work.
@tool
class_name Manipulator
extends XRToolsPickable

var held_controller: XRController3D = null
	
var attractor: GPUParticlesAttractorSphere3D 

const MIN_SCALE = 0.5
const MAX_SCALE = 10
const SCALE_SPEED = 1.0

# Add support for is_xr_class on XRTools classes
# I'm not sure why this is needed exactly, but you'll
# annoying get console errors without it.
func is_xr_class(name : String) -> bool:
	return name == "XRToolsPickable"

func _ready() -> void:
	super()
	picked_up.connect(_on_pickable_object_picked_up)
	dropped.connect(_on_pickable_object_dropped)
	highlight_updated.connect(_on_highlight_updated)

	if Engine.is_editor_hint():
		return

	attractor = $VisualAttractorSphere

	# Make the material unique so each manipulator can have its own color
	var visual = $Visual
	if visual and visual.get_surface_override_material_count() > 0:
		var material = visual.get_surface_override_material(0).duplicate()
		visual.set_surface_override_material(0, material)

func _process(delta: float) -> void:
	if Engine.is_editor_hint():
		return

	if held_controller:
		var joystick_y = held_controller.get_vector2("primary").y
		if abs(joystick_y) > 0.1:
			var new_radius = attractor.radius + (joystick_y * SCALE_SPEED * delta)
			attractor.radius = clamp(new_radius, MIN_SCALE, MAX_SCALE)

func _on_pickable_object_picked_up(pickable: XRToolsPickable) -> void:
	held_controller = pickable.get_picked_up_by_controller()

func _on_pickable_object_dropped(_pickable: XRToolsPickable) -> void:
	held_controller = null

func _on_highlight_updated(_pickable: XRToolsPickable, enable: bool) -> void:
	var visual = $Visual
	if visual and visual.get_surface_override_material_count() > 0:
		if enable:
			visual.get_surface_override_material(0).emission_energy_multiplier = 1.0
		else:
			visual.get_surface_override_material(0).emission_energy_multiplier = 0.20
