@tool
class_name MagicCircle extends Node2D


@export var base_rad : float = 20;
@export var layer_rad_inc : float = 1.1;
@export var layers : int = 10
@export var vis_layers : float = 10.0
@export var main_color : Color = Color(1, 1, 1, 1)
@export var fixed_seed : int = 1234;
@export var squish : float = 0.7
@export var rot_speed : float = 0.1;
@export var line_width : float = 0.6

var runes : Texture2D = load("res://assets/vfx/runes.png");

var rot = 0;
var time = 0;

func _process(_delta):
	queue_redraw()

# absloute angle, NO rot
func _draw_arc(radius, start_angle, end_angle, color, segments=10):
	var segment_size : float = (end_angle - start_angle) / segments
	var last_pos = Vector2(cos(start_angle), sin(start_angle)) * radius
	for i in range(segments+1):
		var angle = start_angle + (i * segment_size)
		
		var next_pos = Vector2(cos(angle), sin(angle)) * radius
		draw_line(last_pos, next_pos, color, line_width)
		last_pos = next_pos

# yes rot
func _draw_circle(radius, small_circles, small_radius, color, segments = 50):
	if (small_circles == 0):
		_draw_arc(radius, 0, 2*PI, color, segments)
		return

	var arc_segments = segments / small_circles
	var arc_size = (2*PI) / small_circles
	# arc_length = angle * radius
	# angle = arc_length / radius
	var small_circle_angle =  (small_radius / radius)
	
	for i in range(small_circles):
		var small_angle = i * arc_size;
		var start_angle = i * arc_size + small_circle_angle
		var end_angle = (i + 1) * arc_size - small_circle_angle
		_draw_arc(radius, start_angle, end_angle, color, arc_segments)
	
		var circle_pos = Vector2(cos(small_angle), sin(small_angle)) * radius
		draw_arc(circle_pos, small_radius, 0, 2*PI, 10, color, line_width)
		_draw_rand_rune(circle_pos, color)

func _draw_text_circle(radius, rune_num, color, segments = 50):
	_draw_circle(radius + 10, 0, 0, color, segments)
	_draw_circle(radius - 10, 0, 0, color, segments)
	var rune_diff = (2 * PI) / rune_num
	for i in range(rune_num):
		var angle = i * rune_diff
		var pos = Vector2(cos(angle), sin(angle)) * radius
		_draw_rand_rune(pos, color)

# yes rot
func _draw_polygon(radius, segments, skip, color):
	var segment_angle = (2*PI) / segments
	var last_pos = Vector2(1, 0) * radius
	for i in range(segments +1):
		var angle = (i * skip) * segment_angle
		var next_pos = Vector2(cos(angle), sin(angle)) * radius
		draw_line(last_pos, next_pos, color, line_width)
		
		last_pos = next_pos

func _draw_rand_rune(draw_pos, color):
	var pos = draw_pos
	pos.x -= 5;#
	pos.y -= 5
	draw_texture_rect_region(runes, Rect2(pos.x, pos.y, 10, 10), Rect2(rand_r(0, 4) * 10, 0, 10, 10), color)

# inclusive
func rand_r(min_v, max_v):
	return randi() % (max_v - min_v + 1) + min_v


func _draw():
	seed(fixed_seed)
	for i in range(1, layers):
		var layer_type = randf();
		var layer_counter = float(i) / layers # 0 - 1
		var layer_inv_counter = 1 - layer_counter # 1 - 0
		
		var layer_dir = -1 if rand_r(0, 1) else 1;
		var layer_rot_mult = rand_r(1, 12) * rot_speed * layer_dir
		var layer_rot = Time.get_ticks_msec() * layer_inv_counter * layer_rot_mult * 0.001;

		var layer_radius = i * pow(base_rad, layer_rad_inc)
		var layer_color = main_color
		layer_color.a = clamp(vis_layers - i, 0, 1)
		
		draw_set_transform(Vector2.ZERO, layer_rot, Vector2.ONE)
		if layer_type < 0.2:
			var small_circles = rand_r(0, 5)
			var small_radius = layer_radius * 0.1
			_draw_circle(layer_radius, small_circles, small_radius, layer_color)
		elif layer_type < 0.7:
			var vertices = rand_r(5, 8)
			var skip = rand_r(1, 2)
			_draw_polygon(layer_radius, vertices, skip, layer_color)
		elif layer_type <= 1:
			var rune_num = round(4 + layer_counter * 32)
			_draw_text_circle(layer_radius, rune_num, layer_color)
		scale.y = squish
