extends Node

# Main scene
var mainSceneInstance

# Screen
var screen_size = Vector2(1920.0, 1080.0)  # Default screen size (this is a float for some reason)
var viewport_size
@onready var extent: Rect2 = get_viewport().get_visible_rect()

# utils.
var rng = RandomNumberGenerator.new()
var eps: float = 1e-4

# managers
var foodManager: FoodManager2D

# A world "current"
# polar
var flow_dir: float  # [0, 2pi)
var flow_mag: float  # [0, 1]
# cartesian
var flow_x: float
var flow_y: float
# Swap period
var flowT: float = 10

# A game timer
var t: float = 0.0


func _ready() -> void:
	# Start game
	mainSceneInstance = get_tree().root.get_child(-1)

	# Create viewport
	viewport_size = get_viewport().get_visible_rect().size

	# initial world current
	get_new_flow()


func _physics_process(delta: float) -> void:
	t += delta
	
	# Flow current change
	if abs(fmod(t, flowT)) < eps:
		get_new_flow()

func switch_scene(name:String) -> void:
	if name == "respawn":
		mainSceneInstance.go_to_respawn_scene()

# TODO: This needs to be called from a script inheriting a CharacterBody2D (e.g. the player)
# Alternative would be to pass the player reference to this script (which might be better?)
func init_screen_size(x:float, y:float) -> void:
	screen_size.x = x
	screen_size.y = y

# This can take a vector of any size (but should be 2d, other components are unused)
func get_boundaried_position(position):
	# clamp
	#return position.clamp(Vector2.ZERO, screen_size)
	
	# periodic
	position.x = wrapf(position.x, 0, screen_size.x)
	position.y = wrapf(position.y, 0, screen_size.y)
	return position

func get_new_flow():
	flow_dir = rng.randf()*2*PI
	flow_mag = rng.randf()
	
	flow_x = flow_mag * cos(flow_dir)
	flow_y = flow_mag * sin(flow_dir)


func calc_distance(one, two) -> float:
	var candidate = one.distance_to(two)
	var onedup = one
	if one.x < screen_size.x/2:
		if one.y < screen_size.y/2:
			# top left
			onedup.y -= screen_size.y
			candidate = min(candidate, onedup.distance_to(two))	
			onedup.y += screen_size.y
			onedup.x -= screen_size.x
			candidate = min(candidate, onedup.distance_to(two))	
		else:
			# bottom left
			onedup.y += screen_size.y
			candidate = min(candidate, onedup.distance_to(two))	
			onedup.y -= screen_size.y
			onedup.x -= screen_size.x
			candidate = min(candidate, onedup.distance_to(two))	
	else:
		if one.y < screen_size.y/2:
			# top  right
			onedup.y -= screen_size.y
			candidate = min(candidate, onedup.distance_to(two))	
			onedup.y += screen_size.y
			onedup.x += screen_size.x
			candidate = min(candidate, onedup.distance_to(two))	
		else:
			# bottom right
			onedup.y += screen_size.y
			candidate = min(candidate, onedup.distance_to(two))	
			onedup.y -= screen_size.y
			onedup.x += screen_size.x
			candidate = min(candidate, onedup.distance_to(two))	
	return candidate
