extends Node

signal finished_compilation

const EXCLUDED_DIRECTORIES: Array[String] = [
	"res://addons",
	"res://.godot",
	"res://localization",
]

#const SIMUTANEOUS_SCENES: int = 5

@onready var progress_bar: ProgressBar = %ProgressBar
@onready var canvas_layer: CanvasLayer = $CanvasLayer


func precompile_shaders() -> void:
	var files: PackedStringArray = find_scenes_in_file_path("res://")
	var index: int = 0
	
	while index < files.size():
		#print("Compilation Progress: ", index, "/", files.size() - 1)
		
		var file: String = files[index]
		index += 1
		
		if scene_file_path == file or get_tree().current_scene.scene_file_path == file:
			continue
		
		await compile_scene(file)
		
		progress_bar.value = index / float(files.size())
	
	finished_compilation.emit()


func compile_scene(scene_path: String) -> void:
	var scene: PackedScene = load(scene_path)
	
	if not scene.can_instantiate():
		return
	
	var node: Node = scene.instantiate()
	
	node.set_script(null)
	
	for child: Node in Utils.get_all_children(node):
		child.set_script(null)
		
		# WARNING: Any children of these fmod nodes are also deleted.
		# if (
		# 		child is FmodBankLoader
		# 		or child is FmodEventEmitter2D
		# 		or child is FmodEventEmitter3D
		# 		or child is FmodListener2D
		# 		or child is FmodListener3D
		# ):
		# 	child.free()
		
		if (
				child is GPUParticles2D
				or child is GPUParticles3D
				or child is CPUParticles2D
				or child is CPUParticles3D
		):
			child.set_emitting(true)
		#child.set_process(false)
		#child.set_process_internal(false)
		#child.set_physics_process_internal(false)
	
	add_child(node)
	await get_tree().create_timer(0.2, false).timeout
	node.queue_free()


func find_scenes_in_file_path(path: String, find_recursive: bool = true) -> PackedStringArray:
	var files: PackedStringArray = []
	path = str(path, "/" if not path.ends_with("/") else "")
	
	for file: String in DirAccess.get_files_at(path):
		if file.get_extension().contains("scn"):
			#print("Path: '%s' Filename: '%s'" %[path, file])
			files.append(str(path, file))
	
	if find_recursive:
		for folder: String in DirAccess.get_directories_at(path):
			var excluded_path: String = str(path, folder)
			
			if EXCLUDED_DIRECTORIES.has(excluded_path):
				continue
			
			files.append_array(find_scenes_in_file_path(excluded_path))
	
	return files
