extends Node2D

class_name LevelsManager

const tmp_level_scene_path = "user://tmp/"

const init_level_scene_path = "res://src/levels/"

const group_name = "serializable"

# 当前楼层
export var level : int = 1 setget set_level
# 全局数据
var global : Dictionary = {}

signal level_changed(level)

func _ready():
	var dir = Directory.new()
	FileUtils.remove_dir(tmp_level_scene_path)
	dir.make_dir(tmp_level_scene_path)

# 获取当前楼层实例
func get_current_level_instance() -> LevelInstance:
	return get_child(0) as LevelInstance

# 设置楼层
func set_level(next_level:int):
	#保存数据
	save_screenshot()
	save_instance_to_local()
	save_data_to_local()
	load_data(next_level)

func load_data(next_level:int):
	#加载数据
	var next_scene = load_scene_from_local(next_level) as LevelInstance
	add_child(next_scene)
	get_current_level_instance().free()
	$"/root/Main".on_level_changed(next_level)
	load_data_from_local(next_level)
	#设置数据
	level = next_level

# 保存当前楼层的屏幕截图
func save_screenshot():
	var image = get_viewport().get_texture().get_data()
	image.flip_y()
	var save_error = image.save_png("%s%s.png" % [tmp_level_scene_path,level])
	if save_error != OK:
		print("保存截图失败:"+save_error)
	
# 设置楼层和位置
func set_level_and_position(next_level:int,position:Vector2):
	set_level(next_level)
	var player = get_current_level_instance().get_player()
	player.position = position
	
# 保存当前场景到本地文件
func save_instance_to_local():
	var scene = PackedScene.new()
	var result = scene.pack(get_current_level_instance())
	if result == OK:
		var error = ResourceSaver.save("%s%s.tscn" % [tmp_level_scene_path,level], scene)
		if error != OK:
			push_error("保存场景失败")

# 从本地加载场景文件
func load_scene_from_local(next_level:int) -> LevelInstance:
	var path = "%s%s.tscn" % [tmp_level_scene_path,next_level]
	var scene = null
	if FileUtils.file_exist(path):
		scene = load(path).instance()
	else:
		var init_path = "%sLevel%s.tscn" % [init_level_scene_path,next_level]
		scene = load(init_path).instance()
	scene.name = "Level%s" % next_level
	return scene as LevelInstance

# 保存游戏数据
func save_data_to_local():
	var data = {}
	for node in get_tree().get_nodes_in_group(group_name):
		node.save_data(data,global)
	var file = File.new()
	var file_error = file.open("%s%s.data" % [tmp_level_scene_path,level],File.WRITE)
	if file_error != OK:
		print("保存游戏数据失败:",file_error)
		return
	file.store_var(data,true)
	file.close()
	
# 还原游戏数据
func load_data_from_local(next_level:int):
	var file = File.new()
	var file_error = file.open("%s%s.data" % [tmp_level_scene_path,next_level],File.READ)
	var data = null
	if file_error == OK:
		 data = file.get_var(true)
	else:
		data = {}
	for node in get_tree().get_nodes_in_group(group_name):
		node.load_data(data,global)

# 持久化数据
func save_persistent(index:int)->void:
	#保存当前场景
	save_instance_to_local()
	save_data_to_local()
	#保存当前楼层
	var file = File.new()
	var dir = Directory.new()
	var dest_dir = "user://%s/" % index
	dir.make_dir(dest_dir)
	file.open(dest_dir + "level.data",File.WRITE)
	file.store_string(to_json({
		"level":self.level,
		"global":self.global
	}))
	file.close()
	#迁移数据到持久化目录
	if dir.open(tmp_level_scene_path) == OK:
		dir.list_dir_begin()
		var file_name = dir.get_next()
		while file_name != "":
			if dir.current_is_dir():
				print("Found directory: " + file_name)
			else:
				var copy_result = dir.copy(tmp_level_scene_path + file_name,dest_dir + file_name)
				if copy_result != OK:
					print("保存存档失败",copy_result)
			file_name = dir.get_next()
	else:
		print("An error occurred when trying to access the path.")

# 加载持久化数据
func load_persistent(index:int)->void:
	var file = File.new()
	var dir = Directory.new()
	var dest_dir = "user://%s/" % index
	dir.remove(tmp_level_scene_path)
	dir.make_dir(tmp_level_scene_path)
	#迁移持久化目录到临时目录
	if dir.open(dest_dir) == OK:
		dir.list_dir_begin()
		var file_name = dir.get_next()
		while file_name != "":
			if dir.current_is_dir():
				print("Found directory: " + file_name)
			else:
				if file_name != "level.data":
					var copy_result = dir.copy(dest_dir + file_name,tmp_level_scene_path + file_name)
					if copy_result != OK:
						print("读取存档失败",copy_result)
			file_name = dir.get_next()
	else:
		print("An error occurred when trying to access the path.")
	#读取楼层
	file.open(dest_dir + "level.data",File.READ)
	var data = JSON.parse(file.get_as_text()).result
	var level = data.level
	self.global = data.global
	file.close()
	load_data(level)
