#include "component_action_shoot.h"

/* DEPENDENCIES: Physics */

static void _position_get(ComponentActionShoot* self, ECS* ecs, vec3 position);
static void _velocity_set(ComponentActionShoot* self, ECS* ecs, u32 projectile);

/* Sets starting point of projectile. */
static void
_position_get(ComponentActionShoot* self, ECS* ecs, vec3 position)
{
	ComponentPhysics* physics;

	physics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, self->component.id);

	glm_vec3_copy(physics->position, position);

	position[0] += -cos(physics->angle) * self->offset;
	position[1] += -sin(physics->angle) * self->offset;
}

/* Obtains the velocity for the fired projectile. */
static void
_velocity_set(ComponentActionShoot* self, ECS* ecs, u32 projectile)
{
	ComponentPhysics* physics;
	ComponentPhysics* projectilePhysics;
	f32 angle;
	f32 magnitude;
	f32 moveMagnitude;
	vec3 velocity;
	vec3 moveVelocity;

	physics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, self->component.id);
	projectilePhysics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, projectile);

	angle = physics->angle;

	glm_vec3_zero(velocity);

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

	glm_vec3_copy(velocity, moveVelocity);

	magnitude = glm_vec3_norm(velocity);

	glm_vec3_add(moveVelocity, physics->velocity, moveVelocity);

	moveMagnitude = glm_vec3_norm(moveVelocity);

	if (moveMagnitude > magnitude)
		glm_vec3_copy(moveVelocity, velocity);
	
	glm_vec3_copy(velocity, projectilePhysics->velocity);
	projectilePhysics->angle = angle;
}

/* Sets action_shoot component info. */
void
component_action_shoot_init
(
	ComponentActionShoot* self, 
	ProjectileInit projectileInit, 
	f32 speed, 
	f32 offset,
	f32 height
)
{
	self->projectileInit = projectileInit;
	self->baseSpeed = speed;
	self->speed = self->baseSpeed;
	self->offset = offset;
	self->height = height;
}

/* Ticks action_shoot component. */
void
component_action_shoot_tick(ComponentActionShoot* self, ECS* ecs)
{
	if (self->isFire)
	{
		u32 projectile;
		vec3 position;
		ComponentGameObject* projectileGameObject;
		ComponentGameEntityType* projectileGameEntityType;
		ComponentActionReturn* projectileReturn;

		projectile = ecs_entity_add(ecs);

		_position_get(self, ecs, position);
	
		self->projectileInit(ecs, projectile, position, self->component.id);

		_velocity_set(self, ecs, projectile);

		projectileGameObject = ecs_component_get(ecs, ECS_COMPONENT_GAME_OBJECT, projectile);
		projectileGameEntityType = ecs_component_get(ecs, ECS_COMPONENT_GAME_ENTITY_TYPE, projectile);
		projectileReturn = ecs_component_get(ecs, ECS_COMPONENT_ACTION_RETURN, projectile);
	
		projectileGameObject->height = self->height;

		if (projectileReturn)
			projectileReturn->lifetime += self->lifetimeBonus;

		switch (projectileGameEntityType->type)
		{
			case GAME_ENTITY_CHIP:
				sound_play(&ecs->game->resources.sounds[SOUND_CHIP_SHOOT], SOUND_NO_PRIORITY);
				break;
			case GAME_ENTITY_SNAKE:
				sound_play(&ecs->game->resources.sounds[SOUND_SNAKE_SHOOT], SOUND_NO_PRIORITY);
				break;
			default:
				break;
		}



		self->isFire = false;
	}
}
