extends MarginContainer
## Menu allowing the user to adjust game configuration.

const SETTINGS_GROUP := "Settings"
const VOLUME_GROUP := "VolumeSliders"
const BINDINGS_GROUP := "ControlBindings"

@onready var bus_mixer_list: HBoxContainer = %BusMixerList
@onready var control_binding_list: VBoxContainer = %ControlBindingList


func _ready() -> void:
	populate_volume_mixers()
	populate_control_bindings()


func _get_settings_elements() -> Array[Setting]:
	var elements: Array[Setting] = []
	elements.assign(get_tree().get_nodes_in_group(SETTINGS_GROUP))
	return elements


func _get_volume_sliders() -> Array[VolumeSlider]:
	var elements: Array[VolumeSlider] = []
	elements.assign(get_tree().get_nodes_in_group(VOLUME_GROUP))
	return elements


func _get_control_bindings() -> Array[ControlBinding]:
	var elements: Array[ControlBinding] = []
	elements.assign(get_tree().get_nodes_in_group(BINDINGS_GROUP))
	return elements


func populate_control_bindings() -> void:
	for action: StringName in InputMap.get_actions():
		if not action.begins_with("ui_"):
			control_binding_list.add_child(ControlBinding.create(action))


func populate_volume_mixers() -> void:
	for idx: int in range(AudioServer.bus_count):
		bus_mixer_list.add_child(VolumeSlider.create(idx))


## Close menu without applying settings.
func cancel() -> void:
	queue_free()


## Apply all settings.
func apply() -> void:
	for setting: Setting in _get_settings_elements():
		setting.apply()
	for mixer: VolumeSlider in _get_volume_sliders():
		mixer.apply()
	for binding: ControlBinding in _get_control_bindings():
		binding.apply()


## Write all applied settings to disk.
func save_settings() -> void:
	Game.settings.write()


## Apply settings and close menu.
func accept() -> void:
	apply()
	save_settings()
	queue_free()
