/*
 * DamNums: by Xaser Acheron
 *
 * Events. 'Nuff said.
 */

class DamNumEventHandler : StaticEventHandler
{
	/*
	 * Raw DamNum spawner for "shotgun spray" mode.
	 * Everything else is handled by DamNumTracker.
	 */
	override void WorldThingDamaged(WorldEvent e)
	{
		if (dam_enabled && self.ShouldSpawn(e.Thing) && dam_spray && e.DamageType != 'Massacre')
		{
			Vector3 spawnPos = e.Thing.pos + (0, 0, e.Thing.height);
			DamNum.spawnDamageNumbers(spawnPos, e.Damage, e.DamageType);
		}
	}

	/*
	 * Create a DamNumTracker when an actor spawns or is revived.
	 */
	override void WorldThingSpawned(WorldEvent e)
	{
		if (self.ShouldSpawn(e.Thing))
		{
			DamNumTracker.Create(e.thing);
		}
	}
	override void WorldThingRevived(WorldEvent e)
	{
		if (self.ShouldSpawn(e.Thing))
		{
			DamNumTracker.Create(e.thing);
		}
	}

	/*
	 * Determine if we should spawn/track a particular thing. Basically
	 * an easy abstraction for the dam_shootable parameter.
	 */
	bool ShouldSpawn(Actor thing) {
		return thing && (thing.bIsMonster || (dam_shootable && thing.bShootable));
	}
}

/*
 * The Tracker. Observes an actor, tracks damage changes over the
 * course of a tic, and spawns damage numbers once the tic is complete.
 */
class DamNumTracker : Inventory
{
	int currentHealth;

	/*
	 * Create & set up Tracker for the specified actor.
	 *
	 * TODO: remove this function if it turns out it isn't needed.
	 */
	static void Create(Actor thing)
	{
		if (thing) {
			thing.GiveInventoryType('DamNumTracker');
		}
	}

	/*
	 * Initialize the tracker just before its first tic.
	 */
	override void PostBeginPlay()
	{
		// Don't spawn a tracker if the tracked thing is gone or already dead.
		// This stops numbers from spawning for PE-spawned Lost Souls that die
		// instantly due to being in a wall. Was amusing, but unintentional. :P
		if (!self.owner || self.owner.health < 1) {
			self.Destroy();
			return;
		}

		self.currentHealth = self.owner.health;

		Super.PostBeginPlay();
	}

	/*
	 * Track damage and spawn stuff while the actor is alive.
	 */
	override void Tick()
	{
		if (self.owner) {
			if (dam_enabled && !dam_spray && self.owner.health != self.currentHealth) {
				self.SpawnNumbers();
				self.currentHealth = self.owner.health;
			}
		} else {
			// clean up after oneself just in case an actor gets
			// Thing_Remove'd or similar.
			self.Destroy();
		}
		Super.Tick();
	}

	/*
	 * Upon owner death, spawn the last round of numbers. This is necessary to
	 * cover the case where an actor is removed immediately upon death. 
	 */
	override void OwnerDied()
	{
		self.SpawnNumbers();
		self.owner.RemoveInventory(self);
	}

	/*
	 * Do the actual number spawn. There's a bit of calculation and checking
	 * that's common to all Tracker spawns, so it's done here for convenience.
	 */
	void SpawnNumbers()
	{
		if (dam_enabled && !dam_spray && self.owner && self.owner.DamageTypeReceived != 'Massacre')
		{
			Vector3 position = self.owner.pos + (0, 0, self.owner.height);
			int totalDamage = 0;
			If(self.currentHealth > self.owner.health) //Damage
			{
				totalDamage = self.currentHealth - self.owner.health;
				DamNum.spawnDamageNumbers(position, totalDamage, self.owner.DamageTypeReceived);
			}
			Else If(self.currentHealth < self.owner.health)
			{
				totalDamage =  self.owner.health - self.currentHealth;
				DamNum.spawnDamageNumbers(position, totalDamage, "Healing");
			}
			// don't show negative damge (healing) for now. May change later as a feature addition.
			//if(totalDamage > 0) {
				
			//}
		}
	}
}
