extends Control

onready var _action_list = $"%ActionKeyList"
onready var changes_made := false
onready var changes_saved := false

var block_ui_cancel = false

func _ready() -> void:
	$InputMapper.connect('profile_changed', self, 'rebuild')
	$InputMapper.initialize_profiles()
	$"%ProfilesMenu".initialize($InputMapper)
	$"%ProfilesMenu".grab_focus()
	$InputMapper.change_profile($"%ProfilesMenu".selected)
	
func _input(event: InputEvent) -> void:
	# TODO Static quit button esc
	if !event.is_action("ui_cancel") || !self.visible:
		return
	if block_ui_cancel:
		block_ui_cancel = false
		return
	$"%Back"._on_button_up()

func rebuild(input_profile):
	_action_list.clear()
	var first = true
	var prev_line
	for order_action in $InputMapper.profile_order:

		var input_action := ""

		for action in input_profile.keys():
			if action == order_action:
				input_action = action
		
		if input_action == "":
			continue

		if(input_action.ends_with("_old") || input_action.begins_with(("ui_"))):
			continue
		var line = _action_list.add_input_line(input_action, input_profile[input_action])
		if first:
			$"%ProfilesMenu".focus_neighbour_bottom = line.get_child(2).get_path()
			$"%Back".focus_neighbour_top = line.get_child(2).get_path()
			$"%Save".focus_neighbour_top = line.get_child(2).get_path()
			$"%Reset".focus_neighbour_top = line.get_child(2).get_path()
			first = false
		else:
			line.get_child(2).focus_neighbour_top = prev_line.get_path()
			prev_line.focus_neighbour_bottom = line.get_child(2).get_path()
		line.get_child(2).focus_neighbour_left = $"%Back".get_path()
		line.get_child(2).focus_neighbour_right = $"%Save".get_path()
		prev_line = line.get_child(2)
		line.connect('change_button_pressed', self, '_on_InputLine_change_button_pressed', [input_action, line])

func close():
	self.visible = false
	$"%PauseOverlay".visible = true
	$"%Continue".grab_focus()

func _on_InputLine_change_button_pressed(action_name, line):
	var old_event = $InputMapper.get_selected_profile()[action_name]
	$"%KeySelectMenu".open()
	var event = yield($"%KeySelectMenu", "key_selected")
	if event == null:
		return
		
	#Check if events are basically the same
	#TODO Problem with different physical locations of the same key
	if "scancode" in old_event && "scancode" in event:
			if event.scancode == old_event.scancode:
				return
			elif event == old_event:
				return
	
	var action_with_same_event: String = check_doubled_event(event)
	
	# Routine to swap buttons
	# TODO put into function
	if action_with_same_event != "":
		# Check doubled reads from the InputMap and alternative actions are only virtual
		if action_with_same_event == action_name:
			action_with_same_event = "alt " + action_name
		$"%SwapKeysMenu".open(action_name, action_with_same_event, old_event, event)
		var swap = yield($"SwapKeysMenu", "selection_made")
		if swap:
			swap_buttons(action_name, action_with_same_event, old_event, event)
		print("bakayaroo!")
		return
	
	if $InputMapper.change_action_key(action_name, event, old_event):
		changes_made = true
		changes_saved = false
		line.update_key(event)

func check_doubled_event(event: InputEvent) -> String:
	for action in $InputMapper.get_selected_profile().keys():
		if action.begins_with("ui_") || action.ends_with("_old"):
			continue
		var assigned_event: InputEvent = $InputMapper.get_selected_profile()[action]
		if "scancode" in assigned_event && "scancode" in event:
			if event.scancode == assigned_event.scancode:
					return action
			else:
				if event == assigned_event:
					return action
	return ""

func swap_buttons(action1, action2, old_event, new_event) -> void:
	var input_line1 = $"%ActionKeyList".get_input_line(action1)
	var input_line2 = $"%ActionKeyList".get_input_line(action2)
	if $InputMapper.change_action_key(action1, new_event, old_event):
		changes_made = true
		changes_saved = false
		input_line1.update_key(new_event)
	else:
		return

	# Avoid erasing the just assigned "old" event from the input map,
	# when swapping alternative button assignments in place
	if action1.trim_prefix("alt ") == action2.trim_prefix("alt "):
		new_event = old_event

	if $InputMapper.change_action_key(action2, old_event, new_event):
		input_line2.update_key(old_event)
