@tool
class_name XRToolsHoldButton
extends Node3D


signal pressed


# Enable our button
@export var enabled : bool = false: set = set_enabled

@export var activate_action : String = "trigger_click"
@export var activate_action_desktop : String = "ui_accept"

# Countdown
@export var hold_time : float = 2.0

# Color our our visualisation
@export var color : Color = Color(1.0, 1.0, 1.0, 1.0): set = set_color

# Size
@export var size : Vector2 = Vector2(1.0, 1.0): set = set_size


var time_held = 0.0
var material : ShaderMaterial
var xr_start_node : XRToolsStartXR


# Add support for is_xr_class on XRTools classes
func is_xr_class(name : String) -> bool:
	return name == "XRToolsHoldButton"


# Called when the node enters the scene tree for the first time.
func _ready():
	material = $Visualise.get_surface_override_material(0)
	xr_start_node = XRTools.find_xr_child(
	XRTools.find_xr_ancestor(self,
	"*Staging",
	"XRToolsStaging"),"StartXR","Node")

	if !Engine.is_editor_hint():
		_set_time_held(0.0)

	_update_size()
	_update_color()
	_update_enabled()


func _process(delta):
	if Engine.is_editor_hint():
		return

	var button_pressed = false

	# we check all trackers
	var controllers = XRServer.get_trackers(XRServer.TRACKER_CONTROLLER)
	for name in controllers:
		var tracker : XRPositionalTracker = controllers[name]
		if tracker.get_input(activate_action):
			button_pressed = true


	if !xr_start_node.is_xr_active():
		if Input.is_action_pressed("ui_accept") or Input.is_action_pressed(activate_action_desktop):
			button_pressed = true



	if button_pressed:
		_set_time_held(time_held + delta)
		if time_held > hold_time:
			# done, disable this
			set_enabled(false)
			emit_signal("pressed")
	else:
		_set_time_held(max(0.0, time_held - delta))


func set_enabled(p_enabled: bool):
	enabled = p_enabled
	_update_enabled()


func _update_enabled():
	if is_inside_tree() and !Engine.is_editor_hint():
		_set_time_held(0.0)
		set_process(enabled)


func _set_time_held(p_time_held):
	time_held = p_time_held
	if material:
		$Visualise.visible = time_held > 0.0
		material.set_shader_parameter("value", time_held/hold_time)


func set_size(p_size: Vector2):
	size = p_size
	_update_size()


func _update_size():
	if material: # Note, material won't be set until after we setup our scene
		var mesh : QuadMesh = $Visualise.mesh
		if mesh.size != size:
			mesh.size = size

			# updating the size will unset our material, so reset it
			$Visualise.set_surface_override_material(0, material)


func set_color(p_color: Color):
	color = p_color
	_update_color()


func _update_color():
	if material:
		material.set_shader_parameter("albedo", color)