extends Node


# Declare member variables here. Examples:
# var a = 2
# var b = "text"


# Called when the node enters the scene tree for the first time.
var freeze_dist = 20.0
func _ready():
	pass # Replace with function body.


# Called every frame. 'delta' is the elapsed time since the previous frame.
func freeze_character(c):
	var pos = c.transform
	var sp = Spatial.new()
	var pp = c.get_parent()
	var character_data = {}
	var stats = {}
	if c.has_meta("character_data"):
		character_data = c.get_meta("character_data")
	if c.has_meta("stats"):
		stats = c.get_meta("stats")
	pp.add_child(sp)
	sp.transform = pos
	sp.add_to_group("frozen")
	sp.set_meta("character_data", character_data)
	var animtree: AnimationTree = c.get_meta("animation_tree")
	assert(animtree)
	var animation_node = animtree["parameters/state/playback"].get_current_node()
	sp.set_meta("animation_node", animation_node)
#	sp.set_meta("animation_tree", str(c.get_path_to(animtree)))
	sp.set_meta("stats", stats)
	if characters.get_crowd():
		characters.get_crowd().remove_agent(c)
	c.queue_free()

func prepare_save_data() -> bool:
	if  !freeze_all():
		return false
	scenario.save_data.characters = []
	for c in get_tree().get_nodes_in_group("frozen"):
		var n = {}
		n.character_data = c.get_meta("character_data")
		n.stats = c.get_meta("stats")
		n.animation_node = c.get_meta("animation_node")
		n.xform = var2str(c.global_transform)
		scenario.save_data.characters.push_back(n)
	return true
func get_player():
	var c = get_viewport().get_camera()
	if !c:
		return null
	if !c.has_meta("player"):
		return null
	var player = c.get_meta("player")
	if !player:
		return null
	return player

func unfreeze_character(c):
	var data = c.get_meta("character_data")
	var stats = c.get_meta("stats")
	print("HAIR: ", data.hair, " ", data.hair_mat)
	var nc = characters.replace_character(c, data.sex, data.modules, data.face, data.hair, data.hair_mat)
	nc.set_meta("stats", stats)
	var animtree: AnimationTree = nc.get_meta("animation_tree")
	assert(animtree)
	var animation_node = c.get_meta("animation_node")
	animtree["parameters/state/playback"].start(animation_node)
	animtree["parameters/state/playback"].travel(animation_node)
	nc.set_meta("saved_anim_state", animation_node)
var state = 0
var delay = 0.0
func freeze_all() -> bool:
	var player = get_player()
	var ok = true
	for c in get_tree().get_nodes_in_group("character"):
		if c == player:
			continue
		elif c.name.begins_with("npc_spawn"):
			c.queue_free()
			continue
		elif c.name == "npc" && !c.has_meta("animation_tree"):
			print("bad ", c.name, " ", c.get_meta_list())
			for e in c.get_meta_list():
				print("bad", c.get_meta(e))
			c.queue_free()
			continue
		assert(c.has_meta("animation_tree"))
		if c.has_meta("animation_tree"):
			freeze_character(c)
		else:
			ok = false
	assert(ok)
	return ok
func _process(delta):
	return
	var cam = get_viewport().get_camera()
	var player = get_player()
	if !player:
		return
	var cpos = cam.global_transform.origin
	match state:
		0:
			characters.set_process(false)
			for c in get_tree().get_nodes_in_group("character"):
				if c == player:
					continue
				var p = c.global_transform.origin
				if p.distance_squared_to(cpos) > freeze_dist * freeze_dist:
					if c.has_meta("animation_tree"):
						freeze_character(c)
			characters.set_process(true)
			state = 1
			delay = 1.0
#			print("spawned: ", get_tree().get_nodes_in_group("character").size())
#			print("frozen: ", get_tree().get_nodes_in_group("frozen").size())
		1:
			characters.set_process(false)
			for c in get_tree().get_nodes_in_group("frozen"):
				var p = c.global_transform.origin
				if p.distance_squared_to(cpos) < 0.25 * freeze_dist * freeze_dist:
					print("unfreeze")
					unfreeze_character(c)
			characters.set_process(true)
			if delay > 0.0:
				delay -= delta
			else:
				state = 0
