# `say_random global_id list_id lenght`
#
# Displays the specified string as dialog spoken by the player. This command
# blocks further event execution until the dialog has finished being 'said'
# (either as displayed text or as audible speech from a file).
#
# Global variables can be substituted into the text by wrapping the global
# name in braces.
# e.g. say player "I have {coin_count} coins remaining".
#
# **Parameters**
#
# - *player*: Global ID of the `ESCPlayer` or `ESCItem` object that is active.
#	You can specify `current_player` in order to refer to the currently active
#	player, e.g. in cases where multiple players are playable such as in games
#	like Maniac Mansion or Day of the Tentacle.
# - *randomizer_list_id*: ID for the list of sentences.
# - *lenght*: lenght of the list.
#
# Example: `say_random player random_list 4`
#
# @ESC
extends ESCBaseCommand
class_name SayRandomCommand


const CURRENT_PLAYER_KEYWORD = "CURRENT_PLAYER"


var rng: RandomNumberGenerator 

# Constructor
func _init() -> void:
	rng = RandomNumberGenerator.new()


# Return the descriptor of the arguments of this command
func configure() -> ESCCommandArgumentDescriptor:
	return ESCCommandArgumentDescriptor.new(
		3,
		[TYPE_STRING, TYPE_STRING, TYPE_INT],
		[
			null,
			null,
			null
		],
		[
			true,
			false,
			false
		]
	)


# Validate whether the given arguments match the command descriptor
func validate(arguments: Array):
	if not .validate(arguments):
		return false

	if arguments[0].to_upper() != CURRENT_PLAYER_KEYWORD \
		and not escoria.object_manager.has(arguments[0]):
		escoria.logger.error(
			self,
			"[%s]: Invalid object: Object with global id %s not found."
					% [get_command_name(), arguments[0]]
		)
		return false

	return true


# Run the command
func run(command_params: Array) -> int:
	escoria.current_state = escoria.GAME_STATE.DIALOG
	var param_global_id = command_params[0]
	var param_list_id = command_params[1]
	var param_lenght = command_params[2]
	
	if !escoria.dialog_player:
		escoria.logger.error(
			self,
			"[%s]: No dialog player was registered and the say command was encountered."
					% get_command_name()
		)
		escoria.current_state = escoria.GAME_STATE.DEFAULT
		return ESCExecution.RC_ERROR

	if not escoria.main.current_scene.player:
		escoria.logger.warn(
			self,
			"[%s]: No player item in the current scene was registered and the say command was encountered."
					% get_command_name()
		)
		escoria.current_state = escoria.GAME_STATE.DEFAULT
		return ESCExecution.RC_CANCEL

	var text = param_list_id + "_" + String(rng.randi_range(0,param_lenght -1)) + ':" "'

	var speaking_character_global_id = escoria.main.current_scene.player.global_id \
		if param_global_id.to_upper() == CURRENT_PLAYER_KEYWORD \
		else param_global_id

	escoria.dialog_player.say(
		speaking_character_global_id,
		"",
		text
	)
	yield(escoria.dialog_player, "say_finished")
	escoria.current_state = escoria.GAME_STATE.DEFAULT

	var current_count_global_key = "%s_count" % [param_list_id]
	var current_count = escoria.globals_manager.get_global(current_count_global_key)
	if(current_count == null):
		current_count = 0
		
	escoria.globals_manager.set_global(current_count_global_key, current_count + 1)

	return ESCExecution.RC_OK


# Function called when the command is interrupted.
func interrupt():
	escoria.logger.debug(
		self,
		"[%s] interrupt() function not implemented." % get_command_name()
	)