/*
 * Copyright (c) 2024 Marco Cawthorne <marco@icculus.org>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

/* Utility class that handles sh_scientist entities across all game modes */
class
ScientistManager
{
	const void PopulateLevel(int sciNum, string decl);
	const void ClearScientists(string decl);
	const void RespawnSingle(entity scientistEntity, float waitTime);
	const void TeleportToSpot(entity scientistEntity);
};

static void
_RespawnTimerFinished(void)
{
	ents.Input(self.owner, "Respawn", "", self.owner);
	ScientistManager::TeleportToSpot(self.owner);
	remove(self);
}

void
ScientistManager::RespawnSingle(entity scientistEntity, float waitTime)
{
	entity timer = spawn();
	timer.owner = scientistEntity;
	timer.think = _RespawnTimerFinished;
	timer.nextthink = time + waitTime;
}

void
ScientistManager::TeleportToSpot(entity scientistEntity)
{
	entity spawnPoint = game.FindRandomClassObject("monster_scientist");
	setorigin(scientistEntity, spawnPoint.origin);
	scientistEntity.angles = spawnPoint.angles;
}

void
ScientistManager::PopulateLevel(int sciNum, string decl)
{
	int newMax = 0i;

	for (entity s = world; (s = find(s, ::classname, "monster_scientist"));) {
		newMax += 1i;
	}

	if (sciNum > newMax) {
		NSWarning("Scientists spawns for %i desired, can only deliver %i", sciNum, newMax);
		sciNum = newMax;
	}

	for (int i = 0; i < sciNum; i++) {
		entity scientistEntity = ents.Create(decl, g_vec_null);
		TeleportToSpot(scientistEntity);
	}
}

void
ScientistManager::ClearScientists(string decl)
{
	for (entity s = world; (s = find(s, ::classname, decl));) {
		remove(s);
	}
}
