extends Control
class_name MMNodeLink

var end
var source = null
var target = null

var generator = null
var param_name : String = ""
var creating : bool = false

func _init(parent) -> void:
	size_flags_horizontal = SIZE_EXPAND_FILL
	size_flags_vertical = SIZE_EXPAND_FILL
	rect_size = parent.rect_size
	rect_clip_content = true
	parent.add_child(self)

func pick(s, g, n : String, c : bool = false) -> void:
	source = s
	end = get_global_transform().xform_inv(source.get_global_transform().xform(0.5*source.rect_size))
	generator = g
	param_name = n
	creating = c
	set_process_input(true)

func show_link(s, t) -> void:
	set_process_input(false)
	mouse_filter = Control.MOUSE_FILTER_IGNORE
	source = s
	target = t
	update()

func closest(rect, point) -> Vector2:
	return Vector2(max(rect.position.x, min(rect.end.x, point.x)), max(rect.position.y, min(rect.end.y, point.y)))

func find_control(gp) -> Dictionary:
	for c in get_parent().get_children():
		if c is GraphNode:
			if c.get("controls") != null:
				for w in c.controls:
					var widget = c.controls[w]
					if is_instance_valid(widget) and Rect2(widget.rect_global_position, widget.rect_size*widget.get_global_transform().get_scale()).has_point(gp):
						return { node=c, widget=widget }
	return {}

func _draw() -> void:
	var start = get_global_transform().xform_inv(source.get_global_transform().xform(0.5*source.rect_size))
	var color = Color(1, 0.5, 0.5, 0.5)
	var rect
	if target != null:
		color = Color(0.5, 1, 0.5, 0.5)
		rect = get_global_transform().xform_inv(target.get_global_transform().xform(Rect2(Vector2(0, 0), target.rect_size)))
		draw_rect(rect, color, false)
		end = closest(rect, start)
	rect = get_global_transform().xform_inv(source.get_global_transform().xform(Rect2(Vector2(0, 0), source.rect_size)))
	draw_rect(rect, color, false)
	start = closest(rect, end)
	draw_line(start, end, color, 1, true)

func _input(event: InputEvent) -> void:
	if event is InputEventKey:
		if event.scancode == KEY_ESCAPE:
			set_process_input(false)
			queue_free()
	elif event is InputEventMouseMotion:
		var control = find_control(event.global_position)
		end = get_global_transform().xform_inv(event.global_position)
		target = control.widget if control != null and !control.empty() and generator.can_link_parameter(param_name, control.node.generator, control.widget.name) else null
		update()
	elif event is InputEventMouseButton:
		if event.pressed:
			if event.button_index == BUTTON_LEFT:
				var control = find_control(event.global_position)
				if !control.empty():
					generator.link_parameter(param_name, control.node.generator, control.widget.name)
				elif creating:
					generator.remove_parameter(param_name)
			set_process_input(false)
			queue_free()
	get_tree().set_input_as_handled()
