@tool
extends ColorRect


@export_tool_button('Randomize', 'RandomNumberGenerator') var randomize_action = randomize


@export var noise: FastNoiseLite:
	set(x):
		if noise: noise.changed.disconnect(_changed_noise)
		noise = x
		if noise: noise.changed.connect(_changed_noise)

@export var steps := 12:
	set(x): material.set_shader_parameter('steps', x)
	get(): return material.get_shader_parameter('steps')

@export var gradient_start := Color(.18, 0, .45):
	set(x): material.set_shader_parameter('gradient_start', x)
	get(): return material.get_shader_parameter('gradient_start')

@export var gradient_end := Color.YELLOW:
	set(x): material.set_shader_parameter('gradient_end', x)
	get(): return material.get_shader_parameter('gradient_end')

@export var rng_seed := 0:
	set(x):
		rng_seed = x
		_regenerate()


var _noise_texture := NoiseTexture2D.new():
	set(x):
		_noise_texture = x
		_changed_noise()


func _changed_noise() -> void:
	_noise_texture.noise = noise
	material.set_shader_parameter('noise', _noise_texture)


func _resized() -> void:
	_noise_texture.width = ceili(size.x)
	_noise_texture.height = ceili(size.y)
	_changed_noise()


func _ready() -> void:
	_resized()
	resized.connect(_resized)


func _regenerate() -> void:
	var rng := RandomNumberGenerator.new()
	rng.seed = rng_seed
	noise.fractal_type = rng.randi_range(0, 3) as FastNoiseLite.FractalType
	match noise.fractal_type:
		3: noise.fractal_octaves = 2
		2: noise.fractal_octaves = 3
		_: noise.fractal_octaves = 5
	noise.frequency = rng.randf_range(0.002, 0.004)
	noise.seed = rng.seed
	match rng.randi_range(1, 5):
		1: steps = 2
		2: steps = 5
		3: steps = 12
		4: steps = 24
		5: steps = 128
	var lighter := rng.randf_range(0.4, 0.8)
	var darker := rng.randf_range(0.2, 0.6)
	var color1 := Color.from_ok_hsl(rng.randf(), rng.randf() * 0.8 + 0.2, lighter)
	var color2 := Color.from_ok_hsl(rng.randf(), rng.randf(), lighter - darker)
	match rng.randi_range(1, 2):
		1: gradient_start = color1; gradient_end = color2
		_: gradient_start = color2; gradient_end = color1


func randomize() -> void:
	rng_seed = randi()
