tool
extends KinematicBody2D
class_name Enemy

signal died
signal got_damage


export var num_of_hits := 3
export var walking_speed := 20.0
export var attack_cool_down := .1
export var patroler = true
export var idle_interval := .5
export var idle_time := .2
export var dont_fall_patrol = true
export var gravity = 500.0

var _velocity := Vector2.ZERO
var _is_idle := false
var _is_alive := true
var _triggerd := false
var _damage_enabled := true
var _player_ref:Player = null;
var _genesis_position:Vector2;

func _get_configuration_warning() -> String:
	var warnings = PoolStringArray()
	var children = get_children()
	var warning_sections := {
		"animation_player": true,
		"collision_shape": true,
		"sprite": true,
		"raycast_left": dont_fall_patrol,
		"raycast_right": dont_fall_patrol,
		"area_2d": true
	}
	for child in children:
		if child.name == 'CollisionShape2D': warning_sections.collision_shape = false;
		elif child.name == 'Sprite': warning_sections.sprite = false;
		elif child.name == 'Area2D': warning_sections.area_2d = false;
		elif child.name == 'RayCastLeft': warning_sections.raycast_left = false;
		elif child.name == 'RayCastRight': warning_sections.raycast_right = false;
		elif child.name == 'AnimationPlayer':
			warning_sections.animation_player = not (
				 $AnimationPlayer.has_animation("walk") and
				 $AnimationPlayer.has_animation("die") and
				 $AnimationPlayer.has_animation("idle") and
				 $AnimationPlayer.has_animation("hit")
				)
		
	if warning_sections.collision_shape:
		warnings.append(name + " Needs to have a CollisionShape2D Child")
	if warning_sections.area_2d:
		warnings.append(name + " Needs to have an Area2D Child")
	if warning_sections.raycast_left:
		warnings.append(name + " With dont-fall mode Needs to have a RayCastLeft Child")
	if warning_sections.raycast_right:
		warnings.append(name + " With dont-fall mode Needs to have a RayCastRight Child")
	if warning_sections.sprite:
		warnings.append(name + " Needs to have aa Sprite Child")
	if warning_sections.animation_player:
		warnings.append(name + " Needs to have an AnimationPlayer Child witt 'walk', 'idle', 'die', 'hit' animations")
	return warnings.join('\n')

func _ready() -> void:
	add_to_group("Enemies")
	_genesis_position = position

func _physics_process(delta: float) -> void:
	if Engine.editor_hint: return
	if not _is_alive: return
	if not _damage_enabled:
		_velocity.y += gravity * delta
		_velocity = move_and_slide(_velocity, Vector2.UP)
		return
	if not _is_idle and not _triggerd:
		if patroler:
			if is_on_wall():
				$Sprite.scale = Vector2($Sprite.scale.x * -1, 1)
			elif dont_fall_patrol and is_on_floor():
				var pit_direction = _get_pit_direction()
				if not pit_direction == 0:
					$Sprite.scale = Vector2(pit_direction * -1, 1) 
		$AnimationPlayer.play("walk")
		_velocity.y += gravity * delta
		_velocity.x = $Sprite.scale.x * walking_speed 
		_velocity = move_and_slide(_velocity, Vector2.UP)
	pass

func take_damage(from_direction:int, damage: int = 1)->void:
	num_of_hits -= 1
	if num_of_hits <= 0:
		_is_alive = false
		_damage_enabled = false
		$AnimationPlayer.play("die")
	else:
		_damage_enabled = false
		$AnimationPlayer.play("hit")
		$Sprite.scale = Vector2(from_direction * -1, 1) 
		_velocity.x = 100 * from_direction
		_velocity.y = -50

func on_animation_hit_ended():
	_damage_enabled = true

func _get_pit_direction()->int:
	if not $RayCastLeft.is_colliding():
		return -1
	elif not $RayCastRight.is_colliding():
		return 1
	return 0

func _alerted()->bool:
	return false
