@tool
class_name CameraTraumaCauser
extends Marker3D

@export var continues_shake: bool = false
@export var shake_type := ShakingCamera.ShakeType.POSITIONAL
@export_exp_easing("attenuation") var distance_falloff: float = 1.0
@export_range(0.0, 10.0, 0.001, "or_greater", "suffix:m") var min_radius: float = 2.5
@export_range(0.0, 10.0, 0.001, "or_greater", "suffix:m") var max_radius: float = 10.0
@export_group("Inner(Min) Radius", "min_")
@export_range(0.0, 1.0, 0.001, "or_greater") var min_shake_intensity: float = 0.5
@export_range(0.0, 10.0, 0.001, "or_greater", "suffix:s") var min_shake_duration: float = 0.5
@export_group("Outer(Max) Radius", "max_")
@export_range(0.0, 1.0, 0.001, "or_greater") var max_shake_intensity: float = 0.5
@export_range(0.0, 10.0, 0.001, "or_greater", "suffix:s") var max_shake_duration: float = 0.5


#func _init() -> void:
	#if Engine.is_editor_hint():
		## Setup hint.
		#var sprite := Sprite3D.new()
		#sprite.billboard = BaseMaterial3D.BILLBOARD_ENABLED
		#sprite.shaded = false
		#sprite.texture = preload("res://src/general/shaking_camera.svg")
		#add_child(sprite)


func _process(_delta: float) -> void:
	if Engine.is_editor_hint():
		# For some reason, Godot doesn't like this when exporting the game...
		#var editor_selection: EditorSelection = EditorInterface.get_selection()
		#
		#if editor_selection.get_selected_nodes().has(self):
		DebugDraw3D.draw_sphere(global_position, min_radius, Color.RED)
		DebugDraw3D.draw_sphere(global_position, max_radius, Color.SKY_BLUE)
	elif continues_shake:
		cause_trauma()


func cause_trauma() -> void:
	var cameras: Array[ShakingCamera] = ShakingCamera.cameras

	for camera: ShakingCamera in cameras:
		var distance: float = Utils.node_distance(
				self,
				camera.origin if is_instance_valid(camera.origin) else camera
		)

		if distance > max_radius:
			continue

		var distance_ratio: float = remap(distance, min_radius, max_radius, 0.0, 1.0)
		distance_ratio = clampf(ease(distance_ratio, distance_falloff), 0.0, 1.0)

		var intensity: float = remap(distance_ratio, 0.0, 1.0, min_shake_intensity, max_shake_intensity)
		var duration: float = remap(distance_ratio, 0.0, 1.0, min_shake_duration, max_shake_duration)

		if continues_shake:
			camera.apply_constant_shake(intensity, shake_type)
		else:
			camera.shake(intensity, duration, shake_type)
