extends AnimatedSprite

enum { RIGHT, DOWN_RIGHT, DOWN, DOWN_LEFT, LEFT, UP_LEFT, UP, UP_RIGHT }

var sprite := UP
export (int) var threshold = 5  # Range to snap around axis direction, in degrees.

var time = 0.0
# Called when the node enters the scene tree for the first time.
func _ready():
	pass # Replace with function body.

func _process(delta):
	"""
	The sprite has its own representation of rotation, so we need to tweak things.
	The sprite inherits orientation from its parent (track) that must be canceled.
	"""
	var global = get_global_rotation_degrees()
	var local = get_rotation_degrees()
	var total = wrapf(global - local, -180.0, 180.0)
	var r = snap_rotation(total)
	if _update_sprite(r):
		print_debug("frame changed")
		set_frame(sprite)
		# We can just cancel out the "part of" the rotation
		# embedded in the sprites, leaving out a small
		# rotation for dynamic effect...
		#set_rotation_degrees(-r)
	# ...Or we just cancel out everything
	set_rotation_degrees(-total)
		
	get_node("/root/Track2/HBoxContainer/Rotation").set_text("%.1f°" % r)
	time += delta
	if time >= 0.1:
		print_debug("%.1f" % get_rotation_degrees(), "° | global: ", "%.1f" % get_global_rotation_degrees(), "°")


func snap_rotation(r):
	""" 
	Snap rotation to multiples of 45°
		Also snaps within a certain range of direction axis
	"""
	if r >= 0 - threshold and r <= 0 + threshold: # Right
		r = 0
	elif r >= 180 - threshold or r <= -180 + threshold: # Left
		r = 180
	elif r >= 90 - threshold and r <= 90 + threshold: # Down
		r = 90
	elif r >= -90 - threshold and r <= -90 + threshold: # Up
		r = -90
	elif r > 0 + threshold and r < 90 - threshold:
		r = 45
	elif r > 90 + threshold and r < 180 - threshold:
		r = 135
	elif r > -90 + threshold and r < 0 - threshold:
		r = -45
	elif r > -180 + threshold and r < -90 - threshold:
		r = -135
	return r	


func _update_sprite(rotation):
	""" 
	Updates the sprite index given direction of movement.
		Returns true if sprite was updated, false otherwise.
	"""
	var previous = sprite
	# Use a specific algorithm according to difficulty mode
	#__set_sprite_from_direction(round(direction.x), round(direction.y)) ## if abs(direction.y) > 0.1 else 0
	__set_sprite_from_rotation( rotation )
	return previous != sprite


func __set_sprite_from_direction(x, y):
	""" Set the matching sprite according to given direction vector """
	if x != 0 and y != 0:
		if x < 0 and y < 0:
			sprite = UP_LEFT
		elif x < 0 and y > 0:
			sprite = DOWN_LEFT
		elif x > 0 and y < 0:
			sprite = UP_RIGHT
		elif x > 0 and y > 0:
			sprite = DOWN_RIGHT
	elif x != 0:
		if x < 0:
			sprite = LEFT
		else:
			sprite = RIGHT
	elif y != 0:
		if y < 0:
			sprite = UP
		else:
			sprite = DOWN


func __set_sprite_from_rotation(r: int):
	""" Set the matching sprite according to given rotation (in degrees) """
	match r:
		0: sprite = RIGHT
		45: sprite = DOWN_RIGHT
		90: sprite = DOWN
		135: sprite = DOWN_LEFT
		180, -180: sprite = LEFT
		-45: sprite = UP_RIGHT
		-90: sprite = UP
		-135: sprite = UP_LEFT

# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
#	pass
