class_name FieldVisualizer
extends Node2D
## Визуализация магнитных силовых линий.
## Показывает направление и силу магнитного поля в виде стрелок.

## Количество линий по горизонтали и вертикали
@export var grid_resolution: int = 10

## Размер области визуализации
@export var area_size: Vector2 = Vector2(1152, 648)

## Длина стрелки при максимальной силе
@export var max_arrow_length: float = 30.0

## Цвет стрелок
@export var arrow_color: Color = Color(0.5, 0.5, 0.5, 0.4)

## Включена ли визуализация
@export var is_visible_field: bool = true


func _process(_delta: float) -> void:
	if is_visible_field:
		queue_redraw()


func _draw() -> void:
	if not is_visible_field:
		return

	var magnets := get_tree().get_nodes_in_group("magnets")
	if magnets.is_empty():
		return

	var step_x := area_size.x / grid_resolution
	var step_y := area_size.y / grid_resolution

	for ix in range(grid_resolution + 1):
		for iy in range(grid_resolution + 1):
			var point := Vector2(ix * step_x, iy * step_y)
			var field := _calculate_field_at(point, magnets)
			var field_strength := field.length()

			if field_strength < 0.1:
				continue

			# Нормализуем и масштабируем длину стрелки
			var arrow_length := minf(field_strength * 0.01, max_arrow_length)
			var direction := field.normalized()
			var end_point := point + direction * arrow_length

			# Рисуем линию
			var alpha := clampf(field_strength * 0.005, 0.1, 0.6)
			var color := Color(arrow_color.r, arrow_color.g, arrow_color.b, alpha)
			draw_line(point, end_point, color, 1.5)

			# Рисуем наконечник стрелки
			var arrow_head_size := 4.0
			var perp := direction.rotated(PI / 2) * arrow_head_size
			draw_line(end_point, end_point - direction * arrow_head_size + perp, color, 1.5)
			draw_line(end_point, end_point - direction * arrow_head_size - perp, color, 1.5)


## Рассчитать суммарное поле в точке от всех магнитов
func _calculate_field_at(point: Vector2, magnets: Array[Node]) -> Vector2:
	var total_field := Vector2.ZERO

	for magnet_node in magnets:
		if not magnet_node is Magnet:
			continue
		var magnet: Magnet = magnet_node
		var direction := magnet.global_position - point
		var distance := direction.length()
		if distance < 20.0:
			continue

		var field_strength := magnet.strength / (distance * distance)
		total_field += direction.normalized() * field_strength

	return total_field
