extends Control
@export var MouseOverlay: Node
@onready var Cam = get_viewport().get_camera_3d()


# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	if !OS.is_debug_build():
		self.queue_free()


class Line:
	var Start:Vector3
	var End:Vector3
	var LineColor:Color
	var time


	func _init(Start:Vector3, End:Vector3, LineColor, time):
		self.Start = Start
		self.End = End
		self.LineColor = LineColor
		self.time = time

var Lines = []
var RemovedLine = false


func _process(delta):
	for i in range(len(Lines)):
		Lines[i].time -= delta

	if (len(Lines) > 0 || RemovedLine):
		queue_redraw() #Calls _draw
		RemovedLine = false


func _draw():

	for i in range(len(Lines)):
		if Lines[i].Start.length() == 0:return
		var ScreenPointStart = Cam.unproject_position(Lines[i].Start)
		var ScreenPointEnd = Cam.unproject_position(Lines[i].End)

		#Dont draw line if either start or end is considered behind the camera
		#this causes the line to not be drawn sometimes but avoids a bug where the
		#line is drawn incorrectly
		if (Cam.is_position_behind(Lines[i].Start) ||
			Cam.is_position_behind(Lines[i].End)):
			continue

		draw_line(ScreenPointStart, ScreenPointEnd, Lines[i].LineColor)

	#Remove lines that have timed out
	var i = Lines.size() - 1
	while (i >= 0):
		if (Lines[i].time < 0.0):
			Lines.remove_at(i)
			RemovedLine = true

		i -= 1


## start point, end point, color, time (optional)
func DrawLine(Start, End, time = 0.0, LineColor = Color(1.0, 0.0, 0.0, 1.0)):
	Lines.append(Line.new(Start, End, LineColor, time))


## start point, velocity (direction and magnitude), color, time (optional)
func DrawRay(Start, Ray, time = 0.0, LineColor = Color(1.0, 0.0, 0.0, 1.0)):
	Lines.append(Line.new(Start, Start + Ray, LineColor, time))


## start point, half extents (float), color, time (optional)
func DrawCube(Center, HalfExtents, time = 0.0, LineColor = Color(1.0, 0.0, 0.0, 1.0)):
	#Start at the 'top left'
	var LinePointStart = Center
	LinePointStart.x -= HalfExtents
	LinePointStart.y += HalfExtents
	LinePointStart.z -= HalfExtents

	#Draw top square
	var LinePointEnd = LinePointStart + Vector3(0, 0, HalfExtents * 2.0)
	DrawLine(LinePointStart, LinePointEnd, LineColor, time);
	LinePointStart = LinePointEnd
	LinePointEnd = LinePointStart + Vector3(HalfExtents * 2.0, 0, 0)
	DrawLine(LinePointStart, LinePointEnd, LineColor, time);
	LinePointStart = LinePointEnd
	LinePointEnd = LinePointStart + Vector3(0, 0, -HalfExtents * 2.0)
	DrawLine(LinePointStart, LinePointEnd, LineColor, time);
	LinePointStart = LinePointEnd
	LinePointEnd = LinePointStart + Vector3(-HalfExtents * 2.0, 0, 0)
	DrawLine(LinePointStart, LinePointEnd, LineColor, time);

	#Draw bottom square
	LinePointStart = LinePointEnd + Vector3(0, -HalfExtents * 2.0, 0)
	LinePointEnd = LinePointStart + Vector3(0, 0, HalfExtents * 2.0)
	DrawLine(LinePointStart, LinePointEnd, LineColor, time);
	LinePointStart = LinePointEnd
	LinePointEnd = LinePointStart + Vector3(HalfExtents * 2.0, 0, 0)
	DrawLine(LinePointStart, LinePointEnd, LineColor, time);
	LinePointStart = LinePointEnd
	LinePointEnd = LinePointStart + Vector3(0, 0, -HalfExtents * 2.0)
	DrawLine(LinePointStart, LinePointEnd, LineColor, time);
	LinePointStart = LinePointEnd
	LinePointEnd = LinePointStart + Vector3(-HalfExtents * 2.0, 0, 0)
	DrawLine(LinePointStart, LinePointEnd, LineColor, time);

	#Draw vertical lines
	LinePointStart = LinePointEnd
	DrawRay(LinePointStart, Vector3(0, HalfExtents * 2.0, 0), LineColor, time)
	LinePointStart += Vector3(0, 0, HalfExtents * 2.0)
	DrawRay(LinePointStart, Vector3(0, HalfExtents * 2.0, 0), LineColor, time)
	LinePointStart += Vector3(HalfExtents * 2.0, 0, 0)
	DrawRay(LinePointStart, Vector3(0, HalfExtents * 2.0, 0), LineColor, time)
	LinePointStart += Vector3(0, 0, -HalfExtents * 2.0)
	DrawRay(LinePointStart, Vector3(0, HalfExtents * 2.0, 0), LineColor, time)
