extends MultiplayerSynchronizer

class_name PlayerInput

const SCOPE: int = 0b1
const CROUCH: int = 0b10
const WALK: int = 0b100

#region SYNC
@export var direction: Vector2
@export var compressed_states: int
#endregion

signal jumped
signal drop
signal switch_weapon(to_slot: StringName)
signal fire_begin
signal fire_end
signal alternate_state
signal switch_firemode
signal reload
signal scope_begin
signal scope_end
signal crouch_begin
signal crouch_end
signal walk_begin
signal walk_end
signal interact_begin
signal interact_end

func _process(_delta: float) -> void:
	if not is_multiplayer_authority(): return
	direction = Input.get_vector("plr_strafe_r","plr_strafe_l", "plr_back","plr_forward")

func _input(event: InputEvent) -> void:
	if not is_multiplayer_authority(): return
	if event.is_action_pressed("plr_ult"):
		switch_on_server.rpc_id(1,"ultimate")
	elif event.is_action_pressed("plr_bomb"):
		switch_on_server.rpc_id(1,"bomb")
	elif event.is_action_pressed("plr_primary"):
		switch_on_server.rpc_id(1,"primary")
	elif event.is_action_pressed("plr_active_first"):
		switch_on_server.rpc_id(1,"ability_first")
	elif event.is_action_pressed("plr_active_second"):
		switch_on_server.rpc_id(1,"ability_second")
	elif event.is_action_pressed("plr_active_third"):
		switch_on_server.rpc_id(1,"ability_third")
	elif event.is_action_pressed("plr_secondary"):
		switch_on_server.rpc_id(1,"secondary")
	elif event.is_action_pressed("plr_knife"):
		switch_on_server.rpc_id(1,"knife")
	
	if event.is_action_pressed("plr_fire"):
		fire_on_server.rpc_id(1,false)
	if event.is_action_released("plr_fire"):
		fire_on_server.rpc_id(1,true)
	if event.is_action_pressed("plr_scope"):
		alternate_state_on_server.rpc_id(1)
	if event.is_action_pressed("plr_firemode"):
		switch_firemode_on_server.rpc_id(1)
		
	if event.is_action_pressed("plr_drop"):
		drop_on_server.rpc_id(1)
	
	var crouching: bool = compressed_states & CROUCH
	var walking: bool = compressed_states & WALK
	var scoping: bool = compressed_states & SCOPE
	
	if event.is_action_pressed("plr_crouch"):
		if ClientSettings.TOGGLE_CROUCH:
			crouch_on_server.rpc_id(1,crouching)
			compressed_states ^= CROUCH
		elif not crouching:
			compressed_states |= CROUCH
			crouch_on_server.rpc_id(1,false)
	if event.is_action_released("plr_crouch") and not ClientSettings.TOGGLE_CROUCH and crouching:
		compressed_states &= ~CROUCH
		crouch_on_server.rpc_id(1,true)
		
	if event.is_action_pressed("plr_walk"):
		if ClientSettings.TOGGLE_WALK:
			walk_on_server.rpc_id(1,walking)
			compressed_states ^= WALK
		elif not walking:
			compressed_states |= WALK
			walk_on_server.rpc_id(1,false)
	if event.is_action_released("plr_walk") and not ClientSettings.TOGGLE_WALK and walking:
		compressed_states &= ~WALK
		walk_on_server.rpc_id(1,true)
	
	if event.is_action_pressed("plr_scope"):
		if ClientSettings.TOGGLE_SCOPE:
			scope_on_server.rpc_id(1,scoping)
			compressed_states ^= SCOPE
		elif not scoping:
			compressed_states |= SCOPE
			scope_on_server.rpc_id(1,false)
	if event.is_action_released("plr_scope") and not ClientSettings.TOGGLE_SCOPE and scoping:
		compressed_states &= ~SCOPE
		scope_on_server.rpc_id(1,true)
	
	if event.is_action_pressed("plr_reload"):
		reload_on_server.rpc_id(1)
	
	if event.is_action_pressed("plr_interact"):
		interact_on_server.rpc_id(1,false)
	if event.is_action_released("plr_interact"):
		interact_on_server.rpc_id(1,true)
	
	if event.is_action_pressed("plr_jump"):
		jump_on_server.rpc_id(1)

@rpc("authority","call_local","reliable")
func switch_on_server(slot: StringName) -> void:
	if not multiplayer.is_server(): return
	switch_weapon.emit(slot)

@rpc("authority","call_local","reliable")
func drop_on_server() -> void:
	if not multiplayer.is_server(): return
	drop.emit()

@rpc("authority","call_local","reliable")
func fire_on_server(end: bool) -> void:
	if not multiplayer.is_server(): return
	if end:
		fire_end.emit()
	else:
		fire_begin.emit()

@rpc("authority","call_local","reliable")
func alternate_state_on_server() -> void:
	if not multiplayer.is_server(): return
	alternate_state.emit()

@rpc("authority","call_local","reliable")
func switch_firemode_on_server() -> void:
	if not multiplayer.is_server(): return
	switch_firemode.emit()

@rpc("authority","call_local","reliable")
func crouch_on_server(end: bool) -> void:
	if not multiplayer.is_server(): return
	if end:
		crouch_end.emit()
	else:
		crouch_begin.emit()

@rpc("authority","call_local","reliable")
func walk_on_server(end: bool) -> void:
	if not multiplayer.is_server(): return
	if end:
		walk_end.emit()
	else:
		walk_begin.emit()

@rpc("authority","call_local","reliable")
func scope_on_server(end: bool) -> void:
	if not multiplayer.is_server(): return
	if end:
		scope_end.emit()
	else:
		scope_begin.emit()

@rpc("authority","call_local","reliable")
func reload_on_server() -> void:
	if not multiplayer.is_server(): return
	reload.emit()

@rpc("authority","call_local","reliable")
func interact_on_server(end: bool) -> void:
	if not multiplayer.is_server(): return
	if end:
		interact_end.emit()
	else:
		interact_begin.emit()

@rpc("authority","call_local","reliable")
func jump_on_server() -> void:
	if not multiplayer.is_server(): return
	jumped.emit()
