#include "component_behavior_hop.h"

/* DEPENDENCIES: Physics, Health */

static void _component_behavior_hop_reset(ComponentBehaviorHop* self, ECS* ecs);
static void _hop(ComponentBehaviorHop* self, ECS* ecs);

/* Resets after a hop is finished. */
static void
_component_behavior_hop_reset(ComponentBehaviorHop* self, ECS* ecs)
{
	ComponentLevel* level;

	level = ecs_component_get(ecs, ECS_COMPONENT_LEVEL, self->component.id);

	self->isHop = false;
	self->isHopping = false;
	self->timer = self->timerMax - (COMPONENT_BEHAVIOR_HOP_LEVEL_TIMER_MULTIPLIER * (level->value - 1));
	self->timer = MIN(self->timer, COMPONENT_BEHAVIOR_HOP_TIMER_MINIMUM);
}

static void
_hop(ComponentBehaviorHop* self, ECS* ecs)
{
	ComponentPhysics* physics;
	ComponentGameObject* gameObject;
	ComponentPhysics* targetPhysics;
	ComponentLevel* level;
	f32 angle;
	f32 speed;


	level = ecs_component_get(ecs, ECS_COMPONENT_LEVEL, self->component.id);
	physics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, self->component.id);
	gameObject = ecs_component_get(ecs, ECS_COMPONENT_GAME_OBJECT, self->component.id);
	targetPhysics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, self->targetID);

	/* this should not happen. */
	if (!targetPhysics)
		_component_behavior_hop_reset(self, ecs);

	angle = ATAN
	(
		physics->position[0],
		targetPhysics->position[0],
		physics->position[1],
		targetPhysics->position[1]
	);

	speed = self->speed + (COMPONENT_BEHAVIOR_HOP_LEVEL_SPEED_MULTIPLIER * (level->value - 1));
	speed = MAX(speed, COMPONENT_BEHAVIOR_HOP_SPEED_MAX);

	physics->velocity[0] = cos(angle) * speed;
	physics->velocity[1] = sin(angle) * speed;

	gameObject->heightVelocity = self->heightVelocity;

	self->isHopping = true;

	sound_play(&ecs->game->resources.sounds[SOUND_CUPPER_HOP], SOUND_NO_PRIORITY);
}

/* Sets behavior_hop component info. */
void
component_behavior_hop_init
(
 	ComponentBehaviorHop* self, 
	f32 heightVelocity,
	f32 speed,
	u32 timer,
	u32 targetID
)
{
	self->speed = speed;
	self->heightVelocity = heightVelocity;
	self->timerMax = timer;
	self->timer = self->timerMax;
	self->targetID = targetID;
}

/* Ticks behavior_hop component. */
void
component_behavior_hop_tick(ComponentBehaviorHop* self, ECS* ecs)
{	
	if (self->isHop)
	{
		ComponentGameObject* gameObject;

		if (!self->isHopping)
		{
			_hop(self, ecs);
			return;
		}

		gameObject = ecs_component_get(ecs, ECS_COMPONENT_GAME_OBJECT, self->component.id);

		if (gameObject->height <= 0)
			_component_behavior_hop_reset(self, ecs);
	}
	else
	{
		if (self->timer > 0)
		{
			self->timer--;

			if (self->timer <= 0)
			{
				self->timer = 0;
				self->isHop = true;
			}
		}
	}
}
