#TODO: ステートマシン
extends CharacterBody2D

#region Player Varibles

# Nodes
@onready var sprite: Sprite2D = %Sprite
@onready var collider: CollisionShape2D = %Collider
@onready var animator: AnimationPlayer = %Animator
@onready var States: Node = %StateMachine


# Physics varibles
const WalkSpeed := 150.0
const RunSpeed := 350.0
const AirSpeed := 50.0
const Acceleration := 20.0
const Deceleration := 40.0
const Gravity := 980.0
const JumpForce := -350.0

var moveSpeed := WalkSpeed
var moveDirectionX := 0.0
var facing := 1

# Input variables
var keyUp := false
var keyDown := false
var keyLeft := false
var keyRight := false
var keyRun := false
var keyJump := false
var keyJumpPressed := false

# State Machine
var currentState = null
var previousState = null

#endregion

#region Main loop Functions
func _ready() -> void:
	animator.animation_finished.connect(onAnimationFinished)
	#UNSAFE Intialise state machine
	#for state in States.get_children(): 
		#state.States = States
		#state.player = self
	#previousState = States.Fall
	#currentState = States.Fall
	pass


func _draw() -> void:
	#currentState.Draw()
	pass


func _physics_process(delta: float) -> void:
	# Get Input State
	GetInputState()
	
	# Update Current State
	#currentState.Update()
	
	# Handles Movements
	HandleGravity(delta)
	HorizontalMovement()
	HandleJumping()
	
	# Commit Movements
	move_and_slide()
	
	# Temp
	HandleAnimations()


func ChangeState(newState):
	if newState == null:
		return
	previousState = currentState
	currentState = newState
	previousState.ExitState()
	currentState.EnterState()
	
	print("State Change From: " + previousState.Name + "to " + currentState.Name) #Debug


#endregion

#region Custom Functions
func GetInputState():
	keyUp = Input.is_action_pressed("KeyUp")
	keyDown = Input.is_action_pressed("KeyDown")
	keyLeft = Input.is_action_pressed("KeyLeft")
	keyRight = Input.is_action_pressed("KeyRight")
	keyJump = Input.is_action_pressed("KeyJump")
	keyJumpPressed = Input.is_action_just_pressed("KeyJump")
	keyRun = Input.is_action_pressed("KeyRun")
	
	
	if (keyRight): facing = 1
	if (keyRight): facing = -1


func HorizontalMovement(acceleration: float = Acceleration, deceleration: float = Deceleration):
	
	if keyRun:
		moveSpeed = RunSpeed
	else: 
		moveSpeed = WalkSpeed
	
	moveDirectionX = Input.get_axis("KeyLeft", "KeyRight")
	
	if moveDirectionX != 0:
		velocity.x = move_toward(velocity.x, moveDirectionX * moveSpeed, acceleration)
	else:
		velocity.x = move_toward(velocity.x, moveDirectionX * moveSpeed, deceleration)


func HandleLanding():
	if is_on_floor():
		ChangeState(States.Landing)


func HandleGravity(delta, gravity: float = Gravity):
	if not is_on_floor():
		velocity.y += gravity * delta


func HandleJumping():
	if keyJumpPressed:
		if not is_on_floor():
			return
		animator.play("JumpStart")
		onAnimationFinished("JumpStart")



func HandleFalling():
	if not is_on_floor():
		ChangeState(States.Fall)


func HandleAnimations():
	#Filp the sprite
	sprite.flip_h = (moveDirectionX < 0)
	
	if is_on_floor():
		if velocity.x != 0:
			if keyRun: 
				animator.play("Run")
			else:
				animator.play("Walk")
			
		else:
			animator.play("StandingIdle")
	else:
		if velocity.y < 0:
			animator.queue("JumpIdle")
		else:
			animator.play("Falling")


func onAnimationFinished(animationName):
	if animationName == "JumpStart":
		velocity.y = JumpForce
#endregion