extends Node

var marker_list = []
var label_count = 10
var labels = []
var max_dist = 4
var current_marker
var cam

func node_added(node):
	if node.name.begins_with("marker_"):
		if !node in marker_list:
			marker_list.push_back(node)
func node_removed(node):
	marker_list.erase(node)

var state = 0
func _ready():
	get_tree().connect("node_added", self, "node_added")
	get_tree().connect("node_removed", self, "node_removed")
	var root = get_tree().get_root()
	var queue = [root]
	while queue.size() > 0:
		var item = queue.pop_front()
		if item.name.begins_with("marker_"):
			marker_list.push_back(item)
		for e in item.get_children():
			queue.push_back(e)

func see_through_marker(m):
	if !m.has_meta("marker_data"):
		return false
	var md = m.get_meta("marker_data")
	if md.has("see_through") && md.see_through == true:
		return true
	return false

func _process(delta):
	if state == 0:
		var root = get_tree().get_root()
		for _e in range(label_count):
			var tl = Label.new()
			root.add_child(tl)
			tl.hide()
			labels.push_back(tl)
		state = 1
	if state == 1:
		var cam = get_viewport().get_camera()
		if !cam.has_meta("player"):
			return
		var player = cam.get_meta("player")
		assert(player)
		var size = get_viewport().size
		var center = size/2
		var visible_markers = []
		var wstate = cam.get_world().direct_space_state
		for e in marker_list:
			var cam_pos = cam.global_transform.origin
			var player_pos = player.global_transform.origin
			var marker_pos = e.global_transform.origin
			if player_pos.distance_squared_to(marker_pos) < max_dist * max_dist:
				var lpos = cam.global_transform.xform_inv(marker_pos)
				if lpos.z < 0:
					if see_through_marker(e) && e.visible:
						visible_markers.push_back(e)
					elif e.visible:
						var xlist = [player]
						if e.has_meta("marker_data"):
							var md = e.get_meta("marker_data")
							if !md.has("obj"):
								e.hide()
							else:
								if md.obj is PhysicsBody:
									xlist.push_back(md.obj)
						else:
							e.hide()
						
						var result = wstate.intersect_ray(cam_pos, marker_pos, xlist)
						if !result.has("collider") || !result.collider:
							visible_markers.push_back(e)

		var free_labels = []
		var process_markers = visible_markers.duplicate()
		for e in labels:
			var l: Label = e
			if l.has_meta("marker"):
#				var n = l.get_meta("marker")
#				if n in visible_markers:
#					process_markers.erase(n)
#				else:
					l.remove_meta("marker")
					free_labels.push_back(l)
					l.hide()
			else:
				free_labels.push_back(l)
				l.hide()
		if free_labels.size() == 0:
			state = 2
			return
		for e in process_markers:
			if free_labels.size() == 0:
				break
			var pos = cam.unproject_position(e.global_transform.origin)
			var l = free_labels.pop_front()
			var t = InputMap.get_action_list("activate")[0].as_text() + ": "
			if e.name.ends_with("_door"):
				t += "Open"
			elif e.name.ends_with("_container"):
				t += "Access"
			elif e.name.ends_with("_pickup"):
				t += "Pick up"
			elif e.name.ends_with("_vehicleseat") || e.name.ends_with("_seat"):
				t += "Sit"
			elif e.name.ends_with("_exit"):
				t += "Exit"
			elif e.name.ends_with("_talk"):
				t += "Talk"
			elif e.name.ends_with("_action"):
				t += "Action"
			elif e.name.ends_with("_grab"):
				t += "Grab"
			elif e.name.ends_with("_take"):
				t += "Take"
			elif e.name.ends_with("_sacrifice"):
				t += "Sacrifice"
			l.set_meta("marker", e)
			l.text = t
			l.add_color_override("font_color", Color(0.6,0.6,1,1))
			l.rect_position = pos - l.rect_size / 2.0
			l.show()
		var current = null
		var cur_d = INF
		for l in labels:
			if l.visible:
				var d = l.rect_position.distance_squared_to(center)
				if !current:
					cur_d = d
					current = l
				else:
					if cur_d > d:
						current = l
						cur_d = d
		if current:
			current.add_color_override("font_color", Color(0.9,0.9,1,1))
			current_marker = current.get_meta("marker")
		else:
			current_marker = null

		state = 2

	if state == 2:
		state = 1
#	var player = get_viewport().get_camera().get_meta("player")
#	if !controls.is_gui && !player.has_meta("group_behavior") && !player.has_meta("")
#	if Input.is_action_just_pressed("activate"):
#		var marker = current_marker
#		if marker && marker.has_meta("marker_data"):
#			var md = marker.get_meta("marker_data")
#			print("marker_data: ", md)
#			if md.has("obj"):
#				print("obj: ", md.obj.name)
#			if md.has("obj") && md.has("method"):
#				print("activate ", md.obj.name, " ", md.method)
#				md.obj.call_deferred(md.method, md)
func activate_marker():
		print("Activate marker")
		var marker = current_marker
		if marker && marker.has_meta("marker_data"):
			var md = marker.get_meta("marker_data")
			print("marker_data: ", md)
			if md.has("obj"):
				print("obj: ", md.obj.name)
			if md.has("obj") && md.has("method"):
				print("activate ", md.obj.name, " ", md.method)
				md.obj.call_deferred(md.method, md)

func init_markers(obj, marker_info):
	var queue = [obj]
	while queue.size() > 0:
		var item = queue.pop_front()
		if item.name.begins_with("marker_"):
			if marker_info.has(item.name):
				marker_info[item.name].marker_obj = item
		for e in item.get_children():
			queue.push_back(e)
	queue = [obj]
	while queue.size() > 0:
		var item = queue.pop_front()
		if item.name.begins_with("marker_"):
			var marker_data = {}
			marker_data.obj = obj
			if marker_info.has(item.name):
				var o = marker_info[item.name]
				for k in o.keys():
					marker_data[k] = o[k]
				if o.has("see_through") && o.see_through:
					item.hide()
			item.set_meta("marker_data", marker_data)
		for e in item.get_children():
			queue.push_back(e)
func init_marker(m, obj, data):
	assert(m)
	assert(obj)
	assert(data)
	var marker_data = {}
	marker_data.obj = m
	for e in data.keys():
		marker_data[e] = data[e]
		if data.has("see_through") && data.see_through:
			obj.hide()
	obj.set_meta("marker_data", marker_data)
	if !obj in marker_list:
		marker_list.push_back(obj)
