extends Panel

var config_path = "res://config/animation/frames_config.json"

@export var scan_path = "res://asset/art/characters/"

@onready var config_edit := %ConfigEdit
@onready var save_btn := %SaveButton
@onready var exec_btn := %ExecButton
@onready var frames_display_grid := %FramesDisplayGrid

# 0.png
# 12.png
# 11.png.import
# 31 - 副本.png.import
var regex = RegEx.create_from_string("^.*(\\d+)\\.png$")
# {
# 	"dirs": {},
# 	"mapping": {},
# }
var original_config: JSON

var displayer = preload("res://config/animation/frames_display_card.tscn")


func _update_display():
	config_edit.set_text(JSON.stringify(original_config.data, " "))


func _ready() -> void:
	# remove cache and reload config
	original_config = ResourceLoader.load(
		config_path, "JSON", ResourceLoader.CacheMode.CACHE_MODE_IGNORE
	)
	original_config.resource_path = config_path
	_validate_json()
	# scan files
	_scan()
	_display_cards()
	ResourceSaver.save(original_config)
	ResourceUtils.remove_editor_cache("frames_config")
	_update_display()


func _validate_json():
	# first_frame_mapping
	if !original_config.data.has("first_frame_mapping"):
		original_config.data["first_frame_mapping"] = {}
	# mirror_mapping
	if !original_config.data.has("mirror_mapping"):
		original_config.data["mirror_mapping"] = {}
	if !original_config.data.has("dirs"):
		original_config.data["dirs"] = {}
	if !original_config.data.has("mapping"):
		original_config.data["mapping"] = {}
	if !original_config.data.has("frames_per_second"):
		original_config.data["frames_per_second"] = {}


func _scan():
	var dir = DirAccess.open(scan_path)
	if !dir:
		printerr("Failed to open directory:", scan_path)
		return
	var dirs = {}
	for sub_dir in dir.get_directories():
		var sub_path = scan_path + sub_dir
		var frames = _scan_subdir_frames(sub_path)
		if frames.size() > 0:
			print("Found frames in:", sub_dir)
			# Add to the config
			var ids = frames.keys()
			ids.sort_custom(func(a, b): return int(a) < int(b))
			dirs[sub_dir] = {
				"path": sub_path,
				"frames": frames,
				"ids": ids,
			}
		else:
			print("No frames found in:", sub_dir)
	original_config.data["dirs"] = dirs


func _scan_subdir_frames(path: String) -> Dictionary:
	var subdir = DirAccess.open(path)
	if !subdir:
		printerr("Failed to open subdir:", path)
		return {}
	var frames := {}
	# print(path, subdir.get_files())
	for file in subdir.get_files():
		var regex_match := regex.search(file) as RegExMatch
		# print('file:', file,' regex:', regex_match)
		if regex_match:
			var frame_id = int(regex_match.get_string(1))
			frames[str(frame_id)] = path + "/" + file
	return frames


func _display_cards():
	# clear frames_display_grid
	for child in frames_display_grid.get_children():
		child.queue_free()
	# add cards
	var mapping = {}
	var frames_per_second = {}
	var mirror_mapping = {}
	var first_frame_mapping = {}
	for frames_name in original_config.data.dirs.keys():
		var card = displayer.instantiate()
		card.frames_config = original_config
		card.frame_dir_name = frames_name
		#mapping[frames_name] = original_config.data['mapping'][frames_name]
		#frames_per_second[frames_name] = original_config.data['frames_per_second'][frames_name]
		if original_config.data["mapping"].has(frames_name):
			mapping[frames_name] = original_config.data["mapping"][frames_name]
		else:
			mapping[frames_name] = frames_name
		# frames_per_second
		if original_config.data["frames_per_second"].has(frames_name):
			frames_per_second[frames_name] = original_config.data["frames_per_second"][frames_name]
		else:
			frames_per_second[frames_name] = 6
		# mirror_mapping
		if original_config.data["mirror_mapping"].has(frames_name):
			mirror_mapping[frames_name] = original_config.data["mirror_mapping"][frames_name]
		else:
			mirror_mapping[frames_name] = ""
		# first_frame_mapping
		if original_config.data["first_frame_mapping"].has(frames_name):
			first_frame_mapping[frames_name] = (
				original_config.data["first_frame_mapping"][frames_name]
			)
		else:
			first_frame_mapping[frames_name] = ""
		card.mapping_name = mapping[frames_name]
		card.frames_per_sec = frames_per_second[frames_name]
		card.mirror_mapping = mirror_mapping[frames_name]
		card.first_frame_mapping = first_frame_mapping[frames_name]
		frames_display_grid.add_child(card)
	original_config.data.mapping = mapping
	original_config.data.frames_per_second = frames_per_second
	original_config.data.mirror_mapping = mirror_mapping
	original_config.data.first_frame_mapping = first_frame_mapping
