class_name NodeStateMachine
extends Node

#TODO make it where the parent node will set it's self instead of each state needing export vars

#the state that the state machine will start with
@export var initialNodeState: NodeState

#the variables
var nodeState: Dictionary = {}
var currentNodeState: NodeState
var currentNodeStateName: String

func _ready() -> void:
	#will get the all the states that are a chils of the state machine
	for child in get_children():
		#checks if the node is the correct type
		if child is NodeState:
			#adds the node to the node state dictonary
			nodeState[child.name.to_lower()] = child
			child.transition.connect(transition_to)
	
	#checks if intial node was set
	if initialNodeState:
		#does the enter function for the starting state
		initialNodeState.enter()
		#sets the current state to inittal state
		currentNodeState = initialNodeState
	else:
		#this is here cause im stupid and will forget to add the intial state
		print_debug("you forgot to asign an initital node")

#both processes just does the states precesses functions
func _process(delta: float) -> void:
	#print(currentNodeStateName)
	if currentNodeState:
		currentNodeState.on_process(delta)

func _physics_process(delta: float) -> void:
	if currentNodeState:
		currentNodeState.on_phyisics_process(delta)
	

#this function is called in the state machine controller
func transition_to(nodeStateName: String):
	#this checks if the state that it's trying to switch to is the same as the current state
	#if it's trying to switch to the same state it returns void
	if nodeStateName == currentNodeState.name.to_lower():
		return
	
	#this gets the state that it's trying to switch to and puts it into a var
	var newNodeState: NodeState = nodeState.get(nodeStateName.to_lower())
	
	#if new node state is null it returns void
	if !newNodeState:
		return
	
	#calls the exit function of the current state
	if currentNodeState:
		currentNodeState.exit()
	
	#this calls the enter function in new state
	newNodeState.enter()
	#sets the current state to new state
	currentNodeState = newNodeState
	#this sets the current state name to the new state name
	currentNodeStateName = currentNodeState.name.to_lower()
