extends Control

var character_data = {
	'name': 'Default',
	'image': "res://addons/dialogic/Example Assets/portraits/df-3.png",
	'color': Color(0.973511, 1, 0.152344),
	'file': '',
	'mirror_portraits': false
}

var single_portrait_mode = false
var direction = 'left'
var debug = false
var fading_out = false

var current_state := {'character':'', 'portrait':'', 'position':'', 'mirrored':false}


func init(expression: String = '') -> void:
	set_portrait(expression)


func _ready():
	if debug:
		print('Character data loaded: ', character_data)
		print(rect_position, $TextureRect.rect_size)


func set_portrait(expression: String) -> void:
	current_state['portrait'] = expression
	if expression == "(Don't change)":
		return

	if expression == '':
		expression = 'Default'
	
	# Clearing old custom scenes
	for n in get_children():
		if 'DialogicCustomPortraitScene' in n.name:
			n.queue_free()

	var default
	for p in character_data['portraits']:
		if p['name'] == expression:
			if is_scene(p['path']):
				var custom_node = load(p['path'])
				var instance = custom_node.instance()
				instance.name = 'DialogicCustomPortraitScene'
				add_child(instance)
				
				$TextureRect.texture = ImageTexture.new()
				return
			else:
				if ResourceLoader.exists(p['path']):
					$TextureRect.texture = load(p['path'])
				else:
					$TextureRect.texture = ImageTexture.new()
				return
		# Saving what the default is to fallback to it.
		if p['name'] == 'Default':
			default = p['path']
	
	# Everything failed, go with the default one
	if ResourceLoader.exists(default):
		$TextureRect.texture = load(default)
	else:
		$TextureRect.texture = ImageTexture.new()


func set_mirror(value):
	current_state['mirrored'] = value
	if character_data["data"].has('mirror_portraits'):
		if character_data["data"]['mirror_portraits']:
			$TextureRect.flip_h = !value
		else:
			$TextureRect.flip_h = value
	else:
		$TextureRect.flip_h = value


func move_to_position(position_offset, time = 0.5):
	var positions = {
		'left': Vector2(-400, 0),
		'right': Vector2(+400, 0),
		'center': Vector2(0, 0),
		'center_right': Vector2(200, 0),
		'center_left': Vector2(-200, 0)}
	
	direction = position_offset
	modulate = Color(1,1,1,0)
	tween_modulate(modulate, Color(1,1,1, 1), time)
	rect_position = positions[position_offset]
	
	# Setting the scale of the portrait
	var custom_scale = Vector2(1, 1)
	if character_data.has('data'):
		if character_data['data'].has('scale'):
			custom_scale = Vector2(
				float(character_data['data']['scale']) / 100,
				float(character_data['data']['scale']) / 100
			)
			rect_scale = custom_scale
		if character_data['data'].has('offset_x'):
			rect_position += Vector2(
				character_data['data']['offset_x'],
				character_data['data']['offset_y']
			)
			
	if $TextureRect.get('texture'):
		rect_position -= Vector2(
			$TextureRect.texture.get_width() * 0.5,
			$TextureRect.texture.get_height()
		) * custom_scale
		
	fade_in()


# Tween stuff
func fade_in(time = 0.5):
	tween_modulate(modulate, Color(1,1,1, 1), time)
	
	if single_portrait_mode == false:
		var end_pos = Vector2(0, -40) # starting at center
		if direction == 'right':
			end_pos = Vector2(+40, 0)
		elif direction == 'left':
			end_pos = Vector2(-40, 0)
		else:
			rect_position += Vector2(0, 40)

		$TweenPosition.interpolate_property(
			self, "rect_position", rect_position, rect_position + end_pos, time,
			Tween.TRANS_LINEAR, Tween.EASE_IN_OUT
		)
		$TweenPosition.start()


func fade_out(time = 0.5):
	fading_out = true
	var end = modulate
	end.a = 0
	tween_modulate(modulate, end, time)
	$Tween.connect("tween_all_completed", self, "queue_free")


func focus():
	if not fading_out:
		tween_modulate(modulate, Color(1,1,1, 1))
		var _parent = get_parent()
		if _parent:
			# Make sure that this portrait is the last to be _draw -ed
			_parent.move_child(self, _parent.get_child_count())


func focusout():
	var alpha = 1
	if single_portrait_mode:
		alpha = 0
	if not fading_out:
		tween_modulate(modulate, Color(0.5,0.5,0.5, alpha))
		var _parent = get_parent()
		if _parent:
			# Render this portrait first
			_parent.move_child(self, 0)


func tween_modulate(from_value, to_value, time = 0.5):
	$Tween.interpolate_property(
		self, "modulate", from_value, to_value, time,
		Tween.TRANS_LINEAR, Tween.EASE_IN_OUT
	)
	$Tween.start()
	return $Tween


func is_scene(path) -> bool:
	if '.tscn' in path.to_lower():
		return true
	return false
