class_name PlayableCharacter
extends CharacterBase

var last_dpad: Array[Vector2] = [Vector2.ZERO,Vector2.ZERO]

# Node components
@onready var hitbox = $Hitbox
@onready var attack_hitbox = $Attackbox
@onready var attack_hitbox_collider = $Attackbox/Collider
@onready var hitbox_collider = $Attackbox/Collider

var can_move = true
var in_cutscene = false

var interactable_object: Node = null
var interactable_object_cutscene: Cutscene = null

signal interacted_with_object(object: Node, interaction: Cutscene)

func _unhandled_input(event): 
	if event.is_action_pressed("melee") and can_move and not in_cutscene:
		if interactable_object != null and interactable_object_cutscene != null:
			interacted_with_object.emit(interactable_object, interactable_object_cutscene)
		else:
			var animation_rng = randf_range(0, 1)
			anim_tree.set("parameters/melee/blend_position", animation_rng)
			anim_tree.set("parameters/conditions/melee", true)
			can_move = false
			velocity = Vector2.ZERO
			attacked.emit()

func _physics_process(delta):
	if in_cutscene:
		anim_tree.set("parameters/conditions/is_moving", false)
		anim_tree.set("parameters/conditions/melee", false)
	else:
		get_input()
	super._physics_process(delta)
	
func set_animation_direction(direction: Vector2):
	anim_tree.set("parameters/idle/blend_position", direction)
	anim_tree.set("parameters/walk/blend_position", direction)
	anim_tree.set("parameters/melee/0/blend_position", direction)
	anim_tree.set("parameters/melee/1/blend_position", direction)
	anim_tree.set("parameters/melee/2/blend_position", direction)
	anim_tree.set("parameters/hurt/blend_position", direction)
	anim_tree.set("parameters/cut_walk/blend_position", direction)
	
func xor(a:bool, b:bool):
	return a != b

func get_input():
	var vertical = Input.get_axis("up", "down")
	var horizontal = Input.get_axis("left", "right")
	var input_direction = Vector2(horizontal, vertical)
	var input_angle = rad_to_deg(atan2(vertical,horizontal))
	
	var test = xor(abs(input_direction.dot(Vector2.RIGHT)) > 0.5, abs(input_direction.dot(Vector2.UP)) > 0.5)
	
	# Keep lateral directions when moving diagonally
	# if the player moves in one direction and then diagonally
	# (i.e. first left then up-left)
	if test or input_direction == Vector2.ZERO:
		last_dpad[1] = last_dpad[0]
		last_dpad[0] = input_direction
	if last_dpad[0] == Vector2.ZERO and input_direction != Vector2.ZERO:
		last_dpad[0] = input_direction
	
	if not can_move:
		input_direction = Vector2.ZERO
		last_dpad[0] = Vector2.ZERO
		last_dpad[1] = Vector2.ZERO	
	else:
		velocity = input_direction * speed

	if input_direction == Vector2.ZERO:
		anim_tree.set("parameters/conditions/is_moving", false)
	else:
		anim_tree.set("parameters/conditions/is_moving", true)
		set_animation_direction(last_dpad[0])


func _on_attackbox_area_entered(area: Area2D):
	var attack_vector: Vector2 = anim_tree.get("parameters/melee/0/blend_position")
	attack_did_hit.emit(area, 15, attack_vector)

func _on_enemy_attack_did_hit(other, power, attack_direction):
	if other.get_parent().get_instance_id() == get_instance_id() :
		attack_hitbox_collider.set_deferred("disabled", true)
		health = health - power
		can_move = false
		if health <= 0:
			if Globals.nsfw and has_nsfw_animations:
				anim_playback.travel("nsfw_defeated_start")
			else:
				anim_playback.travel("defeated")
			defeated.emit()
			velocity = Vector2.ZERO
		else:
			var facing_direction = attack_direction * -1.0
			set_animation_direction(facing_direction)
			var knockback_direction = attack_direction.rotated(deg_to_rad(randf_range(-1, 1) * KNOCKBACK_RANDOMNESS))
			velocity = KNOCKBACK_POWER * knockback_direction.normalized()
			anim_playback.travel("hurt")
			anim_tree.set("parameters/conditions/melee", false)
		got_hurt.emit(health)

func _on_animation_tree_animation_finished(anim_name):
	if anim_name.contains("hurt") or anim_name.contains("kick") or anim_name.contains("punch"):
		can_move = true
		anim_tree.set("parameters/conditions/melee", false)
	if anim_name.contains("kick") or anim_name.contains("punch"):
		attack_hitbox_collider.set_deferred("disabled", true)
