# A tooltip displaying <verb> <item1> [<item2>]
tool
extends Node2D
class_name ESCRichTooltip


# Maximum width of the label
const MAX_WIDTH = 200

# Minimum height of the label
const MIN_HEIGHT = 30

# Maximum height of the label
const MAX_HEIGHT = 500

# Height of one line in the label
const ONE_LINE_HEIGHT = 16


# Color of the label
export(Color) var color setget set_color

# Vector2 defining the offset from the cursor
export(Vector2) var offset_from_cursor_action1 = Vector2(0,3)

export(Vector2) var offset_from_cursor_action2 = Vector2(0,-2)

# Activates debug mode. If enabled, shows the label with a white background.
export(bool) var debug_mode = false setget set_debug_mode

# Infinitive verb
var current_action: String

# Target item/hotspot
var current_target: String setget set_target

var current_target_object: Object = null setget set_target_object

# Preposition: on, with...
var current_prep: String = "with"

# Target 2 item/hotspot
var current_target2: String

var current_size: Vector2 = Vector2(0,0) setget _set_current_size

# True if tooltip is waiting for a click on second target (use x with y)
var waiting_for_target2 = false

# Node containing the debug white background
var debug_texturerect_node: TextureRect

# Indicates whether the current room is loaded and ready
var _room_is_ready: bool = false

# Tooltips are hidden
var hidden: bool = false

signal tooltip_size_updated

# Connect relevant functions
func _ready():
	if escoria.main.connect("room_ready", self, "_on_room_ready") != 0:
		escoria.logger.error(self, "Error connecting room_ready with _on_room_ready")

	if escoria.action_manager.connect("action_changed", self, "_on_action_selected") != 0:
		escoria.logger.error(self, "Error connecting action_changed with _on_action_selected")


# Set the color of the label
#
# ## Parameters
# - p_color: the color to set the label
func set_color(p_color: Color):
	color = p_color
	if _room_is_ready:
		update_tooltip_text()


# Enable/disable debug mode of the label. If enabled, the label is displayed
# with a white background.
#
# ## Parameters
# - p_debug_mode: if true, enable debug mode. False to disable
func set_debug_mode(p_debug_mode: bool):
	debug_mode = p_debug_mode
	if debug_mode:
		# Add a white TextureRect behind the RTL to see its actual size
		debug_texturerect_node = TextureRect.new()
		add_child(debug_texturerect_node)
		debug_texturerect_node.texture = load("res://addons/escoria-core/game/assets/images/white.png")
		debug_texturerect_node.expand = true
		debug_texturerect_node.stretch_mode = TextureRect.STRETCH_TILE
		#debug_texturerect_node.size_flags_horizontal = SIZE_EXPAND_FILL
		#debug_texturerect_node.size_flags_vertical = SIZE_EXPAND_FILL
		debug_texturerect_node.show_behind_parent = true
		debug_texturerect_node.anchor_right = 1.0
		debug_texturerect_node.anchor_bottom = 1.0
		debug_texturerect_node.mouse_filter = Control.MOUSE_FILTER_IGNORE
		move_child(debug_texturerect_node, 2)
	else:
		if debug_texturerect_node:
			remove_child(debug_texturerect_node)
			debug_texturerect_node.queue_free()

func set_target_object(target: Object, needs_second_target: bool = false) -> void:
	current_target_object = target
	waiting_for_target2 = needs_second_target
	if _room_is_ready:
		if(target == null):
			hide()
			return
		# show()
		update_tooltip_text()


# Set the first target of the label.
#
# ## Parameters
# - target: String the target to add to the label
# - needs_second_target: if true, the label will prepare for a second target
func set_target(target: String, needs_second_target: bool = false) -> void:
	current_target = target
	waiting_for_target2 = needs_second_target
	if _room_is_ready:
		if(target == ""):
			hide()
			return
		update_tooltip_text()
		# show()


# Set the second target of the label
#
# ## Parameters
# - target2: String the second target to add to the label
func set_target2(target2: String) -> void:
	current_target2 = target2
	if _room_is_ready:
		if(target2 == ""):
			hide()
			return
		update_tooltip_text()
		# show()


# Update the tooltip text.
# * If waiting for target item: get text from action*_target_texts dictionaries using current_tool as key
# * If item is in inventory: use action3_text and action4_text variables
# * Else: use action1_text and action2_text variables
func update_tooltip_text():
	if(current_target_object == null):
		return

	var item_in_inventory = escoria.inventory_manager.inventory_has(current_target_object.global_id)
	var waiting_for_target_item = escoria.action_manager.action_state == ESCActionManager.ACTION_INPUT_STATE.AWAITING_TARGET_ITEM

	var action1_text = get_action_target_text(current_target_object.action3_target_texts) if waiting_for_target_item else current_target_object.action3_text if item_in_inventory else current_target_object.action1_text
	var action2_text = get_action_target_text(current_target_object.action4_target_texts) if waiting_for_target_item else current_target_object.action4_text if item_in_inventory else current_target_object.action2_text
		
	$tooltip1/label.text = action1_text
	$tooltip1.visible = !hidden and action1_text != "";

	$tooltip2/label.text = action2_text
	$tooltip2.visible = !hidden and action2_text != "";
	

func get_action_target_text(action_target_texts: Dictionary):
	var action_target_text = action_target_texts.get(escoria.action_manager.current_tool.global_id)
	return action_target_text if action_target_text else ""

# Update the tooltip size according to the text.
func update_size():
	if not get_tree():
		# We're not in the tree anymore. Return
		return
	current_size = $tooltip1/label.get_font("normal_font").get_string_size(current_target)

func get_tooltip1_size():
	if not get_tree():
		# We're not in the tree anymore. Return
		return 
	return Vector2(150,20);
	# escoria.logger.info(self, "get_string_size: " + String($tooltip1/label.get_font("normal_font").get_string_size(current_target)))
	#return $tooltip1/label.get_font("normal_font").get_string_size(current_target)

func get_tooltip2_size():
	if not get_tree():
		# We're not in the tree anymore. Return
		return
	return Vector2(150,20);
	#return $tooltip2/label.get_font("normal_font").get_string_size(current_target)

# Calculate the offset of the label depending on its position.
#
# ## Parameters
# - position: the position to test
#
# **Return**
# The calculated offset
func _offset(position: Vector2) -> Vector2:
	#var center_offset_x = current_size.x / 2
	#var offset_y = 5

	#position.x -= center_offset_x
	#position.y += offset_y

	return position


# Return the tooltip distance to top edge.
#
# ## Parameters
# - position: the position to test
#
# **Return**
# The distance to the edge.
func tooltip_distance_to_edge_top(position: Vector2):
	return position.y


# Return the tooltip distance to bottom edge.
#
# ## Parameters
# - position: the position to test
#
# **Return**
# The distance to the edge.
func tooltip_distance_to_edge_bottom(position: Vector2):
	return escoria.game_size.y - position.y


# Return the tooltip distance to left edge.
#
# ## Parameters
# - position: the position to test
#
# **Return**
# The distance to the edge.
func tooltip_distance_to_edge_left(position: Vector2):
	return position.x


# Return the tooltip distance to right edge.
#
# ## Parameters
# - position: the position to test
#
# **Return**
# The distance to the edge.
func tooltip_distance_to_edge_right(position: Vector2):
	return escoria.game_size.x - position.x

func show():
	escoria.logger.info(self, "show")
	hidden = false
	update_tooltip_text()
	# if _room_is_ready:
	# 	$tooltip1.visible = true;
	# 	$tooltip2.visible = true;
	#$icon.visible = true;
	#$label.visible = true;
	#$background.visible = true;

func hide():
	if _room_is_ready:
		$tooltip1.visible = false;
		$tooltip2.visible = false;
	#$icon.visible = false;
	#$label.visible = false;
	#$background.visible = false;

func setHidden():
	hidden = true
	hide()

# Clear the tooltip targets texts
func clear():
	waiting_for_target2 = false
	set_target("")
	set_target2("")

func _set_current_size(size: Vector2):
	current_size = size
	
# Called when the room is loaded to setup the label.
func _on_room_ready():
	escoria.main.current_scene.game.tooltip_node = self
	_room_is_ready = true


# Called when an action is selected in Escoria
func _on_action_selected() -> void:
	current_action = escoria.action_manager.current_action

	if _room_is_ready:
		update_tooltip_text()
		hide()
