extends Node

class SaveData:
	var id: int
	var type: String
	var parent: String
	var scene_file_path: String

	var position: Vector3
	var rotation_degrees

#Connections
	var place_id: int
	var room_ids: Array
	var tile_ids: Array
	
	var door_to_tile: Dictionary

#Tile data
	var grid_pos: Vector3i
	var face_dict: Array
	var construction_mode: int

func _init():
	ObjectSerializer.register_scripts({
	"SaveData": SaveData,
	"Tile": Tile,
	"Room": Room,
	"Wall": Wall,
	"Door": Door,
})

func _on_save_button_pressed() -> void:
	var save_nodes = get_tree().get_nodes_in_group("SaveObjects")
	var save_file = FileAccess.open("user://savegame.save", FileAccess.WRITE)
	for node in save_nodes:

		if not node.has_method("save"):
			print("no method")
			continue
		
		var node_data = node.save()
		var save_data = SaveData.new()
		for i in node_data:
			save_data.set(i, node_data[i])
		
		var serialized_save_data = BinarySerializer.serialize_var(save_data)
		
		var byte_data = var_to_bytes(serialized_save_data)
		
		save_file.store_var(byte_data)
		
	pass # Replace with function body.

func _on_load_button_pressed():
	
	if not FileAccess.file_exists("user://savegame.save"):
		print("no save to load")
		return
	
	var save_nodes = get_tree().get_nodes_in_group("SaveObjects")
	for i in save_nodes:
		if i:
			i.free()
	
	var save_file = FileAccess.open("user://savegame.save", FileAccess.READ)
	
	var place_id_dict: Dictionary = {}
	var room_id_dict: Dictionary = {}
	var tile_id_dict: Dictionary = {}
	
	var load_place_to_room: Dictionary = {}
	var load_place_to_tile: Dictionary = {}
	var load_room_to_tile: Dictionary = {}
	var load_room_to_door: Dictionary = {}
	var load_tile_to_door: Array = []
	
	while save_file.get_position() < save_file.get_length():
		
		var next_load_bytes = save_file.get_var()
		var next_load = bytes_to_var(next_load_bytes)
		var load_object = load(next_load["scene_file_path"]).instantiate()
		var id = next_load["id"]
		
		match next_load["type"]:
			"Place":
				place_id_dict[id] = load_object.get_instance_id()
				load_place_to_room[load_object] = []
				load_place_to_tile[load_object] = {}
				
				for j in next_load.keys():
					load_object.set(j, next_load[j])
				get_node(next_load["parent"]).add_child(load_object)
				
			"Room":
				room_id_dict[id] = load_object.get_instance_id()
				load_room_to_tile[load_object] = []
				load_room_to_door[load_object] = []
				
				for j in next_load.keys():
					if j == "place_id":
						var new_place_id = place_id_dict[next_load[j]]
						var place = instance_from_id(new_place_id)
						load_place_to_room[place].append(load_object)
						load_object.set(j, new_place_id)
					else:
						load_object.set(j, next_load[j])
				instance_from_id(load_object["place_id"]).get_node("RoomContainer").add_child(load_object)
				
			"Tile":
				tile_id_dict[id] = load_object.get_instance_id()
				
				for j in next_load.keys():
					if j == "place_id":
						var new_place_id = place_id_dict[next_load[j]]
						var place = instance_from_id(new_place_id)
						load_place_to_tile[place].merge({next_load["grid_pos"]: load_object})
						load_object.set(j, new_place_id)
					elif j == "main_room":
						var new_room_id = room_id_dict[j]
						var room = instance_from_id(new_room_id)
						load_room_to_tile[room].append(load_object)
						load_object["lookup_tile_to_room"] = room
					elif j == "face_dict":
						if next_load[j]:
							var temp_new_dict: Dictionary
							for k in next_load[j]:
								temp_new_dict[k] = null
							load_object[j] = temp_new_dict.duplicate()
					
					else:
						load_object.set(j, next_load[j])
				instance_from_id(load_object["place_id"]).get_node("TileContainer").add_child(load_object)
			
			"Door":
				for j in next_load.keys():
					if j == "place_id":
						var new_place_id = place_id_dict[next_load[j]]
						load_object.set(j, new_place_id)
					elif j == "room_ids":
						for k in next_load["room_ids"]:
							var new_room_id = room_id_dict[k]
							var room = instance_from_id(new_room_id)
							load_room_to_door[room].append(load_object)
							load_object["lookup_door_to_room"].append(room)
					elif j == "door_to_tile":
						var tile_dict = next_load["door_to_tile"]
						for k in tile_dict.keys():
							var new_tile_id = tile_id_dict[tile_dict[k]]
							var tile = instance_from_id(new_tile_id)
							
							load_tile_to_door.append({tile: {k: load_object}})

							load_object["lookup_door_to_tile"].merge({k: tile})
					else:
						load_object.set(j, next_load[j])
				instance_from_id(load_object["place_id"]).get_node("ObjectContainer").add_child(load_object)

			_:
				for j in next_load.keys():
					load_object.set(j, next_load[j])
				get_node(next_load["parent"]).add_child(load_object)
		
	for i in load_place_to_room.keys():
		i.lookup_place_to_room = load_place_to_room[i]
	
	for i in load_place_to_tile.keys():
		i.lookup_place_to_tile.merge(load_place_to_tile[i])

	for i in load_room_to_tile.keys():
		i.room_to_tile = load_room_to_tile[i]
	
	for i in load_room_to_door.keys():
		i.room_to_door = load_room_to_door[i]
		
	for i in load_tile_to_door:
		for j in i.keys():
			for k in i[j].keys():
				var one = i[j]
				var two = one[k]
				j.face_dict[k] = two
