extends Node
class_name GameEngine

enum OPS {ADD,SUB,MUL,DIV}

static var gameEngineInstance: GameEngine = null
static var idaArray: Array
var idaCount: int
var gameSpeed: float = 3.0
var mainCamera: Camera3D = null
static var idaPack: Node3D = null
var idaBase: PackedScene = (load("res://Objects/playerClone.tscn") as PackedScene)
static var idaPrime: Node3D = null
var controlBox: Node3D = null
var gateSpawner: Node3D = null
var gateMovementSpeed: float = 10.0
var gateSpawnTime: float = 2.0
var gateSpawnChance: int = 3

func setupEngine() -> void:
	idaArray.clear()
	idaCount = 0

static func getGE() -> GameEngine:
	if gameEngineInstance == null:
		gameEngineInstance = GameEngine.new()
		gameEngineInstance.setupEngine()
	return gameEngineInstance
	
func moveIda(ida: Node3D, delta: float, prime: bool) -> void:
	if prime:
		idaPack.position.x = idaPack.position.move_toward(getGE().controlBox.getMoveToLocation(), getGE().getGameSpeed(delta)).x	
		
	ida.look_at(getGE().controlBox.getMoveToLocation(), Vector3(0,1,0), true)
	
func _process(delta: float) -> void:
	moveIda(idaPrime, delta, true)
	for ida in idaArray:
		moveIda(ida, delta, false)

func getGameSpeed(delta: float) -> float:
	return gameSpeed * delta

func calculateIdas(value: int) -> void:
	var newValue: int = idaCount + value
	if newValue < 0:
		newValue = 0
	
	idaCount = clampi(idaCount + value, 0, 2000)
	var idaOffset: int = idaArray.size() - idaCount	
	print(str(idaCount) + " - " + str(idaOffset))
	
	for i in range(abs(idaOffset)):
		if idaOffset < 0:
			var newIda = idaBase.instantiate()
			newIda.position = (idaPrime.position + (Vector3(-1.5 + randf() * 3, 0, -1.5 + randf() * 1.5)))
			idaPack.add_child(newIda)
			idaArray.push_back(newIda)
		elif idaOffset > 0:
			var currentIda = idaArray.pop_at(randi() % idaArray.size())
			currentIda.queue_free()

func modifyIdas(value: int, operation: OPS) -> void:
	var baseVal: int = 0
	match operation:
		OPS.ADD:
			baseVal += value
		OPS.SUB:
			baseVal -= value
		OPS.MUL:
			var newVal = ceil((1 + idaCount) * value) - idaCount
			baseVal += newVal - 1
		OPS.DIV:
			if idaCount != 0:
				var newVal = floor(float(1 + idaCount) / value)
				baseVal -= idaCount - (newVal - 1)
			else:
				baseVal = 0
	
	calculateIdas(baseVal)
