class_name StateMachineAnimatedActor extends StateMachine

func change_state(new_state: State) -> void:
	if current_state:
		current_state.exit()
		# Set parameters for information
		if new_state is StateAnimatedActor and current_state is StateAnimatedActor:
			set_previous_animation( current_state, new_state)

	current_state = new_state
	current_state.enter()
	if(state_modifiers.size() > 0 and debug_state_machine):
		print("Active Modifiers:")
		for mods in state_modifiers:
			print(mods.name)

func set_previous_animation( old_state: StateAnimatedActor, new_state: StateAnimatedActor ) -> void:
	# added this to help prevent nul index crashes. (Usually because of signal based state changes.)
	if old_state.mod_animation_sequence:
		new_state.previous_animation_name = old_state.mod_animation_sequence[old_state.current_animation_sequence]
	new_state.previous_state_frame_number = old_state.animations.frame
	new_state.previous_state_name = old_state.name
	new_state.previous_speed_multiplier = old_state.speed_multiplier
	#animation_name :String, frame_number : int, animation_sequence :Array
	return

# Initialize the state machine by giving each child state a reference to the
# parent object it belongs to and enter the default starting_state.
func init_animated_actor(parent: KinematicBody2D, animations: AnimatedSprite, move_component: MovementComponent) -> void:
	animations.connect("animation_finished", self, "_on_AnimatedSprite_animation_finished")
	for child in get_children():
		if child is StateAnimatedActor:
			if debug_state_machine:
				print("Initializing State Node for ", parent.name, ": ", child.name)
			child.parent = parent
			child.animations = animations
			child.move_component = move_component
			child.modifier_stack_ref = state_modifiers
			if debug_state_machine:
				child.debug_state = true

	# Initialize to the default state
	change_state(get_node(starting_state))
	

func process_frame(delta: float) -> void:
	# Check the state modifiers for timeouts, and maybe more conditions later
	# If the modifier is no longer valid, pop it from the stack. 
	# We could iterate through a whole list of states but I'm not sure i want
	# states to be that complex. 
	var current_anim_state :StateAnimatedActor = current_state
	if state_modifiers.empty() == false:
		for i in range(state_modifiers.size()):
			# if this modifer is a timer based one
			if state_modifiers[i].state_timeout.time_left == 0 and state_modifiers[i].timeout_seconds !=0:
				# Need to do extra stuff if it's an animation based one
				if state_modifiers[i].modifier_type == "Animation Suffix":
					if debug_state_machine:
						print("State Modifier Timeout: ", state_modifiers[i].name, " -> ",  state_modifiers[i].animation_name)
					# Reset animation suffix
					current_anim_state.animation_suffix = ''
					# Get the current frame of animation
					var current_frame = current_anim_state.animations.frame
					
					# Set the animation index to the current one
					current_anim_state.animation_index = current_anim_state.current_animation_sequence
					#current_anim_state.current_animation_sequence
					#current_anim_state.animations.play()
	
					current_anim_state.animations.play(
						current_anim_state.mod_animation_sequence[current_anim_state.animation_index])
					# Try to set the current frame to the same as before.
					current_anim_state.animations.frames.frames.size() >= current_frame
					current_anim_state.animations.frame = current_frame

					##TODO:
					# no longer needed this way maybe. way to overengineer man. 
#					if current_anim_state.animation_sequence.size() >= current_anim_state.mod_animation_sequence.size():
#						print("Change sequence!: ", current_anim_state.mod_animation_sequence)
#						print("Origin sequence!: ", current_state.mod_animation_sequence)
#						current_anim_state.animations.play(
#							current_anim_state.mod_animation_sequence[current_anim_state.animation_index])
#						# Try to set the current frame to the same as before.
#						current_anim_state.animations.frames.frames.size() >= current_frame
#						current_anim_state.animations.frame = current_frame
#					else:
#						current_anim_state.animations.play(
#							current_anim_state.animation_sequence[0])
					
				
					if debug_state_machine:
						print("Pop State Modifier: ", state_modifiers[i].name)
						state_modifiers.pop_at(i)
		
#		if state_modifiers[-1].state_timeout.time_left == 0 and state_modifiers[-1].pre_append_animation == false:
#			if debug_state_machine:
#				print("Pop State Modifier: ", state_modifiers[-1].name)
#			state_modifiers.pop_back()
#			# Reset animation suffix
#			current_state.animation_suffix = ''
#			var current_frame = current_state.animations.frame
#			#current_state.animations.play(current_state.animation_sequence[current_state.animation_index])
#			#TODO: Bodge to fix crash 
#			current_state.animation_index = 0
#			current_state.current_animation_sequence = 0
#			current_state.animations.play(current_state.animation_sequence[0])
#			current_state.animations.frame = current_frame;
	var new_state = current_state.process_frame(delta)
	if new_state:
		change_state(new_state)


func _on_AnimatedSprite_animation_finished():
	
	##TODO: 
	# It's hard to pop an exit animation off when it's stacked with another kind of animation.
	for i in state_modifiers.size():
		if state_modifiers[i].modifier_type == "Exit Animation":
			#print("Time to pop state modifer: ", state_modifiers[i].animation_name, current_state.animation_suffix, " <-> ", current_state.animations.animation + current_state.animation_suffix)
			if (state_modifiers[i].animation_name + current_state.animation_suffix) == current_state.animations.animation:
				print("Time to pop state modifer: ", state_modifiers[i].animation_name, current_state.animation_suffix, " <-> ", current_state.animations.animation )
				print(current_state.mod_animation_sequence)
				state_modifiers.pop_at(i)
				current_state.animation_index += 1
				break
				
		
#	if state_modifiers.empty() == false:
#		if state_modifiers[-1].pre_append_animation == true:
#			if debug_state_machine:
#				print("Pop State Modifier: ", state_modifiers[-1].name)
#			state_modifiers.pop_back()
	##TODO:
	# consider just stopping the animation and index increment here. 
	if current_state.animations.frames.get_animation_loop(
		current_state.animations.animation) == false:
		if current_state.animation_sequence.size() > 0:
			print("<-- next anim.")
			current_state.animation_index += 1
		



