#include "component_control_redirect.h"

/* DEPENDENCIES: Physics, Redirect, Return */

static bool _component_control_redirect_reset_check(ComponentControlRedirect* self, ECS* ecs);
static void _component_control_redirect(ComponentControlRedirect* self, ECS* ecs);

/* Determines if you get your redirects back. */
static bool
_component_control_redirect_reset_check(ComponentControlRedirect* self, ECS* ecs)
{
	for (s32 i = 0; i < (s32)ecs->lists[ECS_COMPONENT_ACTION_REDIRECT].components.count; i++)
	{
		ComponentActionRedirect* actionRedirect;
	
		actionRedirect = vector_get(&ecs->lists[ECS_COMPONENT_ACTION_REDIRECT].components, i);

		if (actionRedirect->sender == self->component.id)
			return false;
	}

	return true;
}

/* Find all projectiles that can be redirected. */
/* The first valid one will be redirected. */
/* Valid ones are the ones closest to you and with a different enough angle. */
static void
_component_control_redirect(ComponentControlRedirect* self, ECS* ecs)
{
	ComponentRedirect* redirect;
	vec3 mousePosition;
	f32 mouseAngle;
	bool isSuccess;

	isSuccess = false;

	redirect = ecs_component_get(ecs, ECS_COMPONENT_REDIRECT, self->component.id);

	mouse_world_position_get(&ecs->game->input.mouse, &ecs->game->renderer, mousePosition);

	for (s32 i = 0; i < (s32)ecs->lists[ECS_COMPONENT_ACTION_REDIRECT].components.count; i++)
	{
		ComponentActionRedirect* actionRedirect;
		ComponentActionReturn* actionReturn;
		ComponentActionLock* actionLock;
	
		actionRedirect = ecs_component_from_index_get(ecs, ECS_COMPONENT_ACTION_REDIRECT, i);
		actionReturn = ecs_component_from_index_get(ecs, ECS_COMPONENT_ACTION_RETURN, i);
		actionLock = ecs_component_from_index_get(ecs, ECS_COMPONENT_ACTION_LOCK, i);

		if 
		(
			actionRedirect->sender == self->component.id &&
			!actionReturn->isReturning &&
			!actionLock->isLock
		)
		{
			isSuccess = true;
			actionRedirect->isRedirect = true;
		}
	}

	if (isSuccess)
	{
		redirect->value--;
		self->cooldown = self->cooldownMax;
	}
}

/* Initializes control redirect component. */
void
component_control_redirect_init(ComponentControlRedirect* self, u32 cooldown)
{
	self->cooldownMax = cooldown;
	self->cooldown = self->cooldownMax;
}

/* Ticks control redirect.. */
void
component_control_redirect_tick(ComponentControlRedirect* self, ECS* ecs)
{
	ComponentRedirect* redirect;

	if (self->cooldown > 0)
	{
		self->cooldown--;
		return;
	}

	redirect = ecs_component_get(ecs, ECS_COMPONENT_REDIRECT, self->component.id);

	/* Determine if there's no more projectiles of yours on the field. If there's none,
	 * you get your redirects back. */
	if (_component_control_redirect_reset_check(self, ecs))
	{
		redirect->value = redirect->max;
		redirect->isOut = false;
	}

	if (input_press(&ecs->game->input, INPUT_REDIRECT) && !redirect->isOut)
		_component_control_redirect(self, ecs);
}
