class_name Player extends CharacterBody2D


const DEADZONE = 0.1

@export var max_speed: float = 300.0

@onready var sprite: AnimatedSprite2D = $AnimatedSprite2D
@onready var state_machine: StateMachine = $PlayerStateMachine

var h_press_tick: int = 0  ## last time horizontal axis was pressed
var v_press_tick: int = 0  ## last time vertical axis was pressed

var speed_mult: float = 1.0

var room: Room
var x_min_wrap: float
var x_max_wrap: float
var y_min_wrap: float
var y_max_wrap: float
var wrapping: bool


func _ready() -> void:
	# TODO: better way to get current room (signal maybe?)
	room = get_parent() as Room
	assert(room != null, "no room attached")
	
	if room.config.loopable:
		x_min_wrap = room.config.loop_size.position.x
		x_max_wrap = room.config.loop_size.size.x
		y_min_wrap = room.config.loop_size.position.y
		y_max_wrap = room.config.loop_size.size.y
	
	wrapping = true if room.config.loopable else false
	
	EventBus.connect("room_loop_toggled", _on_loop_toggled)


func _input(event: InputEvent) -> void:
	if event.is_action_pressed("move_left") or event.is_action_pressed("move_right"):
		h_press_tick = Time.get_ticks_msec()
	if event.is_action_pressed("move_up") or event.is_action_pressed("move_down"):
		v_press_tick = Time.get_ticks_msec()


func get_movement_vector() -> Vector2:
	var x_strength: float = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
	var y_strength: float = Input.get_action_strength("move_down") - Input.get_action_strength("move_up")
	
	if absf(x_strength) < DEADZONE and absf(y_strength) < DEADZONE:
		return Vector2.ZERO
	
	if absf(x_strength) < DEADZONE: return Vector2(0, signf(y_strength))
	if absf(y_strength) < DEADZONE: return Vector2(signf(x_strength), 0)
	
	# use most recent axis press
	if h_press_tick > v_press_tick: return Vector2(signf(x_strength), 0)
	else: return Vector2(0, signf(y_strength))


func _physics_process(_delta: float) -> void:
	if wrapping:
		position.x = wrapf(position.x, x_min_wrap, x_max_wrap)
		position.y = wrapf(position.y, y_min_wrap, y_max_wrap)
		reset_physics_interpolation()


func _on_loop_toggled(enabled: bool, loop_size: Rect2i) -> void:
	if enabled:
		x_min_wrap = loop_size.position.x
		x_max_wrap = loop_size.size.x
		y_min_wrap = loop_size.position.y
		y_max_wrap = loop_size.size.y
		wrapping = true
	
	else: wrapping = false
