[gd_scene load_steps=8 format=3 uid="uid://df5fuj4vjr11p"]

[ext_resource type="Script" path="res://addons/MetroidvaniaSystem/Database/MapViewer.gd" id="1_s16ok"]
[ext_resource type="Script" path="res://addons/MetroidvaniaSystem/Database/MapOverlay.gd" id="2_pgyha"]
[ext_resource type="Script" path="res://addons/MetroidvaniaSystem/Scripts/EditorIconButton.gd" id="2_tjngl"]

[sub_resource type="ButtonGroup" id="ButtonGroup_lmh17"]

[sub_resource type="GDScript" id="GDScript_fjyy3"]
resource_name = "Settings"
script/source = "@tool
extends Button

var plugin: EditorPlugin

func _enter_tree() -> void:
	if owner:
		plugin = owner.plugin

func _ready() -> void:
	if not plugin:
		return
	
	_pressed()
	
	await get_tree().process_frame
	for data in MetSys.settings.collectible_list:
		var collectible := add_collectible()
		collectible.set_data(data)

func _pressed() -> void:
	for button in button_group.get_buttons():
		button.exit()
	
	%Settings.show()

func exit():
	%Settings.hide()

func add_collectible() -> Control:
	var collectible := preload(\"res://addons/MetroidvaniaSystem/Nodes/CollectibleElement.tscn\").instantiate()
	%CollectibleList.add_child(collectible)
	collectible.save_request.connect(save_collectible_list)
	return collectible

func save_collectible_list():
	var list: Array[Dictionary]
	for collectible in %CollectibleList.get_children():
		if not collectible.is_queued_for_deletion():
			list.append(collectible.get_data())
	MetSys.settings.collectible_list = list
	ResourceSaver.save(MetSys.settings)
"

[sub_resource type="GDScript" id="GDScript_dicqo"]
resource_name = "Finder"
script/source = "@tool
extends Button

@onready var scan_progress: ProgressBar = %ScanProgress
@onready var show_on_map: CheckButton = %ShowOnMap
@onready var summary: VBoxContainer = %Summary

var thread: Thread
var found_elements: Array[Dictionary]

func _ready() -> void:
	scan_progress.hide()
	show_on_map.hide()
	exit()

func _pressed() -> void:
	for button in button_group.get_buttons():
		button.exit()
	
	%Finder.show()

func exit():
	%Finder.hide()

func start_scan() -> void:
	summary.hide()
	%ScanButton.disabled = true
	
	var collectible_list: Array[Dictionary]
	for item in %CollectibleList.get_children():
		collectible_list.append(item.get_data2())
	
	found_elements.clear()
	for item in summary.get_children():
		item.free()
	
	thread = Thread.new()
	thread.start(scan_maps.bind(collectible_list))
	set_process(true)

func _process(delta: float) -> void:
	if not thread:
		set_process(false)
		return
	
	if thread.is_alive():
		return
	
	thread.wait_to_finish()
	thread = null
	
	scan_progress.hide()
	show_on_map.show()
	summary.show()
	%ScanButton.disabled = false
	
	for item in %CollectibleList.get_children():
		var data: Dictionary = item.get_data2()
		var count := 0
		var count_label := setup_header(data)
		
		for found in found_elements:
			if found.element != data.element:
				continue
			
			count += 1
			setup_found(found)
		
		count_label.text = str(count)
		summary.add_child(HSeparator.new())

func scan_maps(element_list: Array[Dictionary]):
	Thread.set_thread_safety_checks_enabled(false)
	
	var maps: Array[String]
	var folders: Array[String]
	folders.append(MetSys.settings.map_root_folder)
	
	while not folders.is_empty():
		var folder := folders.pop_back()
		folders.append_array(Array(DirAccess.get_directories_at(folder)).map(func(subfolder: String) -> String: return folder.path_join(subfolder)))
		maps.append_array(Array(DirAccess.get_files_at(folder)).map(func(file: String) -> String: return folder.path_join(file)))
	
	scan_progress.max_value = maps.size()
	scan_progress.value = 0
	scan_progress.show()
	show_on_map.hide()
	
	for map in maps:
		var lines := FileAccess.open(map, FileAccess.READ).get_as_text().split(\"\\n\")
		
		var current_element: Dictionary
		for line in lines:
			if not current_element.is_empty():
				if line.begins_with(\"[\"):
					found_elements.append(current_element)
					current_element = {}
				elif line.begins_with(\"position =\"):
					current_element.position = str_to_var(line.get_slice(\"=\", 1))
				else:
					continue
			
			for element in element_list:
				if line.begins_with(\"[node name=\\\"%s\" % element.element):
					current_element = element.duplicate()
					current_element.map = map
					break
		
		if not current_element.is_empty():
			found_elements.append(current_element)
		
		scan_progress.value += 1

func complete_element(element: Dictionary):
	var found := preload(\"res://addons/MetroidvaniaSystem/Nodes/CollectibleFoundItem.tscn\").instantiate()
	found.set_element(element)
	found.hovered.connect(owner._on_item_hover.bind(found))
	summary.add_child.call_deferred(found)

func setup_header(data: Dictionary) -> Label:
	var hbox := HBoxContainer.new()
	summary.add_child(hbox)
	
	var tex := TextureRect.new()
	hbox.add_child(tex)
	tex.texture = data.get(\"icon\")
	
	var label := Label.new()
	hbox.add_child(label)
	label.text = data.element
	
	label = Label.new()
	hbox.add_child(label)
	
	return label

func setup_found(data: Dictionary):
	var label := Label.new()
	summary.add_child(label)
	label.mouse_filter = Control.MOUSE_FILTER_PASS
	label.set_meta(&\"data\", data)
	
	data.map = data.map.trim_prefix(MetSys.settings.map_root_folder)
	
	var room := MetSys.map_data.get_cells_assigned_to(data.map)
	if \"position\" in data and not room.is_empty():
		var top_left := Vector2i.MAX
		for coords in room:
			top_left.x = mini(coords.x, top_left.x)
			top_left.y = mini(coords.y, top_left.y)
		
		var pos := top_left + Vector2i(data.position / MetSys.settings.in_game_cell_size)
		data.coords = Vector3i(pos.x, pos.y, room[0].z)
		label.text = \"%s %s\" % [data.map, data.coords]
	else:
		label.text = \"%s\" % data.map
	
	label.mouse_entered.connect(owner._on_item_hover.bind(label))

func toggle_display_on_map(toggled_on: bool) -> void:
	if toggled_on:
		owner.extra_draw = draw_collectibles_on_map
	else:
		owner.extra_draw = Callable()
	owner.map_overlay.queue_redraw()

func draw_collectibles_on_map(canvas_item: CanvasItem):
	for element in found_elements:
		var icon: Texture2D = element.icon
		var target_size := icon.get_size() * (minf(MetSys.CELL_SIZE.x, MetSys.CELL_SIZE.y) / minf(icon.get_width(), icon.get_height()) * 0.9)
		
		if \"coords\" in element:
			var coords: Vector3i = element.coords
			if coords.z != owner.current_layer:
				continue
			
			var pos := Vector2(coords.x + owner.map_offset.x, coords.y + owner.map_offset.y) * MetSys.CELL_SIZE
			canvas_item.draw_texture_rect(icon, Rect2(pos + MetSys.CELL_SIZE * 0.5 - target_size * 0.5, target_size), false)
		else:
			for coords in MetSys.map_data.get_cells_assigned_to(element.map):
				if coords.z != owner.current_layer:
					break
				
				var pos := Vector2(coords.x + owner.map_offset.x, coords.y + owner.map_offset.y) * MetSys.CELL_SIZE
				canvas_item.draw_texture_rect(icon, Rect2(pos + MetSys.CELL_SIZE * 0.5 - target_size * 0.5, target_size), false)
				break
	
"

[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_qbvjg"]
content_margin_left = 4.0
content_margin_right = 4.0
bg_color = Color(0, 0, 0, 0.501961)

[node name="MapViewer" type="HBoxContainer"]
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_s16ok")
metadata/_edit_lock_ = true

[node name="Panel" type="PanelContainer" parent="."]
custom_minimum_size = Vector2(200, 0)
layout_mode = 2
size_flags_horizontal = 0

[node name="ScrollContainer" type="ScrollContainer" parent="Panel"]
layout_mode = 2

[node name="VBoxContainer" type="VBoxContainer" parent="Panel/ScrollContainer"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3

[node name="Layer" type="VBoxContainer" parent="Panel/ScrollContainer/VBoxContainer"]
layout_mode = 2
mouse_filter = 2

[node name="Label" type="Label" parent="Panel/ScrollContainer/VBoxContainer/Layer"]
layout_mode = 2
text = "当前层"
horizontal_alignment = 1

[node name="CurrentLayer" type="SpinBox" parent="Panel/ScrollContainer/VBoxContainer/Layer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 4

[node name="RecenterButton" type="Button" parent="Panel/ScrollContainer/VBoxContainer/Layer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 4
text = "重置视角"

[node name="CheckButton" type="CheckButton" parent="Panel/ScrollContainer/VBoxContainer/Layer"]
layout_mode = 2
size_flags_horizontal = 4
text = "预览映射"

[node name="HSeparator" type="HSeparator" parent="Panel/ScrollContainer/VBoxContainer"]
layout_mode = 2

[node name="Modes" type="VBoxContainer" parent="Panel/ScrollContainer/VBoxContainer"]
layout_mode = 2

[node name="Settings" type="Button" parent="Panel/ScrollContainer/VBoxContainer/Modes"]
layout_mode = 2
toggle_mode = true
button_pressed = true
button_group = SubResource("ButtonGroup_lmh17")
text = "收集品设置"
script = SubResource("GDScript_fjyy3")

[node name="Finder" type="Button" parent="Panel/ScrollContainer/VBoxContainer/Modes"]
layout_mode = 2
toggle_mode = true
button_group = SubResource("ButtonGroup_lmh17")
text = "收集品查找"
script = SubResource("GDScript_dicqo")

[node name="HSeparator2" type="HSeparator" parent="Panel/ScrollContainer/VBoxContainer"]
layout_mode = 2

[node name="EditControls" type="VBoxContainer" parent="Panel/ScrollContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3

[node name="Settings" type="VBoxContainer" parent="Panel/ScrollContainer/VBoxContainer/EditControls"]
unique_name_in_owner = true
visible = false
layout_mode = 2
size_flags_vertical = 3

[node name="ScrollContainer" type="ScrollContainer" parent="Panel/ScrollContainer/VBoxContainer/EditControls/Settings"]
layout_mode = 2
size_flags_vertical = 3
vertical_scroll_mode = 2

[node name="CollectibleList" type="VBoxContainer" parent="Panel/ScrollContainer/VBoxContainer/EditControls/Settings/ScrollContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3

[node name="Button" type="Button" parent="Panel/ScrollContainer/VBoxContainer/EditControls/Settings"]
layout_mode = 2
icon_alignment = 1
script = ExtResource("2_tjngl")
icon_name = "Add"

[node name="Finder" type="VBoxContainer" parent="Panel/ScrollContainer/VBoxContainer/EditControls"]
unique_name_in_owner = true
visible = false
layout_mode = 2
size_flags_vertical = 3

[node name="ScanButton" type="Button" parent="Panel/ScrollContainer/VBoxContainer/EditControls/Finder"]
unique_name_in_owner = true
layout_mode = 2
text = "Scan Maps"

[node name="ScanProgress" type="ProgressBar" parent="Panel/ScrollContainer/VBoxContainer/EditControls/Finder"]
unique_name_in_owner = true
visible = false
layout_mode = 2

[node name="ShowOnMap" type="CheckButton" parent="Panel/ScrollContainer/VBoxContainer/EditControls/Finder"]
unique_name_in_owner = true
visible = false
layout_mode = 2
text = "Display on Map"

[node name="ScrollContainer" type="ScrollContainer" parent="Panel/ScrollContainer/VBoxContainer/EditControls/Finder"]
layout_mode = 2
size_flags_vertical = 3
horizontal_scroll_mode = 3
vertical_scroll_mode = 2

[node name="Summary" type="VBoxContainer" parent="Panel/ScrollContainer/VBoxContainer/EditControls/Finder/ScrollContainer"]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 0

[node name="MapOverlay" type="Control" parent="."]
clip_contents = true
layout_mode = 2
size_flags_horizontal = 3
script = ExtResource("2_pgyha")

[node name="ColorRect" type="ColorRect" parent="MapOverlay"]
modulate = Color(0, 0, 0, 0.12549)
show_behind_parent = true
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
mouse_filter = 2

[node name="Map" type="Control" parent="MapOverlay"]
unique_name_in_owner = true
show_behind_parent = true
anchors_preset = 0
size_flags_horizontal = 3
mouse_filter = 2

[node name="StatusLabel" type="Label" parent="MapOverlay"]
unique_name_in_owner = true
layout_mode = 0
offset_right = 1.0
offset_bottom = 23.0
theme_override_styles/normal = SubResource("StyleBoxFlat_qbvjg")
vertical_alignment = 1

[connection signal="toggled" from="Panel/ScrollContainer/VBoxContainer/Layer/CheckButton" to="." method="toggle_mapped"]
[connection signal="pressed" from="Panel/ScrollContainer/VBoxContainer/EditControls/Settings/Button" to="Panel/ScrollContainer/VBoxContainer/Modes/Settings" method="add_collectible"]
[connection signal="pressed" from="Panel/ScrollContainer/VBoxContainer/EditControls/Finder/ScanButton" to="Panel/ScrollContainer/VBoxContainer/Modes/Finder" method="start_scan"]
[connection signal="toggled" from="Panel/ScrollContainer/VBoxContainer/EditControls/Finder/ShowOnMap" to="Panel/ScrollContainer/VBoxContainer/Modes/Finder" method="toggle_display_on_map"]
