@tool
class_name LevelLoader
extends Marker3D

signal level_loaded
signal level_unloaded

@export_file("*.tscn", "*.scn") var scene_path: String
@export var load_threaded: bool = true
@export_tool_button("Load Level", "Slot") var editor_load: Callable = load_level
@export_tool_button("Unload Level", "Clear") var editor_unload: Callable = unload_level

var level: Node


func load_level() -> void:
	if is_instance_valid(level):
		if level.scene_file_path == scene_path:
			push_warning("Level already loaded")
			return

		unload_level()

	var scene: PackedScene

	if load_threaded:
		scene = await _load_level_threaded()
	else:
		scene = load(scene_path)

	assert(is_instance_valid(scene), "Scene is not valid.")

	level = scene.instantiate()
	add_child(level)

	level_loaded.emit()


func unload_level() -> void:
	if is_instance_valid(level):
		level.queue_free()

	# Remove children that have no owner. Usually happens when duplicating the node (in the editor).
	for child: Node in get_children():
		if child.owner == null:
			child.queue_free()

	level_unloaded.emit()


func _load_level_threaded() -> PackedScene:
	var interactive_loader := InteractiveLoader.new()
	add_child(interactive_loader)

	return await interactive_loader.load_threaded(scene_path)
