@tool
class_name NumericSlider extends HBoxContainer
## HSlider with an attached SpinBox

signal value_changed(value: float)

@export_category("Shared Range Properties")

@export var min_value := 0.0:
	set(v):
		_set_shared("min_value", v)
		min_value = v

@export var max_value := 100.0:
	set(v):
		_set_shared("max_value", v)
		max_value = v

@export var step := 1.0:
	set(v):
		_set_shared("step", v)
		step = v

@export var page := 0:
	set(v):
		_set_shared("page", v)
		page = v

@export var value: float:
	get:
		return _value
	set(v):
		_value = v
		value_changed.emit(v)

@export var exp_edit := false:
	set(v):
		_set_shared("exp_edit", v)
		exp_edit = v

@export var rounded := false:
	set(v):
		_set_shared("rounded", v)
		rounded = v

@export var allow_greater := false:
	set(v):
		_set_shared("allow_greater", v)
		allow_greater = v

@export var allow_lesser := false:
	set(v):
		_set_shared("allow_lesser", v)
		allow_lesser = v

var _value := 0.0:
	set(v):
		if slider:
			slider.set_value_no_signal(v)
		if spin_box:
			spin_box.set_value_no_signal(v)
		_value = v

@onready var slider: HSlider = $HSlider
@onready var spin_box: SpinBox = $SpinBox


func _ready() -> void:
	# Force propagation of properties to shared range elements
	min_value = min_value
	max_value = max_value
	step = step
	page = page
	_value = _value
	exp_edit = exp_edit
	rounded = rounded
	allow_greater = allow_greater
	allow_lesser = allow_lesser


func set_value_no_signal(new_value: float) -> void:
	_value = new_value


func _set_shared(property: String, new_value: Variant) -> void:
	if slider:
		slider.set(property, new_value)
	if spin_box:
		spin_box.set(property, new_value)


func _on_spin_box_value_changed(new_value: float) -> void:
	value = new_value


func _on_slider_value_changed(new_value: float) -> void:
	value = new_value
