extends Node2D

var positions_history : Array
var loop_stack : Array

signal started_drawing(pos:Vector2)
signal stopped_drawing

var is_drawing = false

func _ready() -> void:
	init_history_stack()
	loop_stack = []
	Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
	global_position = get_viewport_rect().size / 2
	
func _process(delta: float) -> void:
	$IconNormal.rotation_degrees = ((get_viewport_rect().size / 2) - Vector2(-10000, -10000)).normalized().dot(Vector2.from_angle(45.))

func _input(event: InputEvent) -> void:
	if event is InputEventMouseButton:
		Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
	if event is InputEventKey:
		if event.keycode == KEY_ESCAPE:
			Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
	if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
		var direction = event.relative.normalized()
		# truthfully should calibrate by mouse
		# need a max speed for fair gameplay
		# var speed = clamp(event.relative.length(), 0.0, 128.0)
		var speed = event.relative.length()
		global_position += direction * speed
		restrict_cursor()
		if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
			if not is_drawing:
				emit_signal("started_drawing", global_position)
				is_drawing = true
			push_history_stack(global_position)
			Globals.CURRENT_LINE = positions_history
		else:
			if is_close_to_loop():
				create_valid_loop()
			if is_drawing:
				emit_signal("stopped_drawing", positions_history)
				is_drawing = false
			init_history_stack()

func get_tail(max_length: int = 32) -> Array:
	var tail_length = min(positions_history.size(), max_length)
	var output = positions_history.slice(positions_history.size() - tail_length, positions_history.size())
	return output

func is_close_to_loop () -> bool:
	if positions_history.size() < 16:
		return false
	
	var to = positions_history[positions_history.size() - 1]
	var from = positions_history[0]
	var distance = (to - from).length()
	print(distance)
	
	if distance < Globals.SNAP_DISTANCE:
		print((to - from).length())
		return true
	return false

func init_history_stack() -> void:
	positions_history = []

func create_valid_loop() -> void:
	var smoothed_loop = positions_history
	var last = 0
	
	# clean up a bit
	while (smoothed_loop.pop_back() as Vector2).distance_to(smoothed_loop[0]) < Globals.SNAP_DISTANCE / 2:
		smoothed_loop.pop_back()
	for i in range(1,8):
		if (smoothed_loop[1] as Vector2).distance_to(smoothed_loop[0]) < Globals.SNAP_DISTANCE / 2:
			smoothed_loop.pop_front()
	
	# simplify
	for j in range(1):
		var new_loop = []
		for i in range(0, smoothed_loop.size(), 2):
			new_loop.append(smoothed_loop[i])
		smoothed_loop = new_loop
	
	loop_stack.append(smoothed_loop)

func push_history_stack(value : Vector2) -> void:
	if positions_history.size() < Globals.HISTORY_LENGTH:
		positions_history.append(value)
	# if positions_history.size() > Globals.HISTORY_LENGTH:
	#	positions_history.pop_front()

func restrict_cursor() -> void:
	if global_position.x < 0:
		global_position.x = 0
	if global_position.y < 0:
		global_position.y = 0
	if global_position.x > get_viewport_rect().size.x:
		global_position.x = get_viewport_rect().size.x
	if global_position.y > get_viewport_rect().size.y:
		global_position.y = get_viewport_rect().size.y
