#include "component_physics.h"

static void _component_physics_rectangle_get(ComponentPhysics* self, vec4 rectangle);
static void _component_physics_collide_tick(ComponentPhysics* self, ECS* ecs);

/* Obtains the colliding rectangle of a physics object. */
static void
_component_physics_rectangle_get(ComponentPhysics* self, vec4 rectangle)
{
	rectangle[0] = self->position[0] - (self->size[0] / 2);
	rectangle[1] = self->position[1] - (self->size[1] / 2);
	rectangle[2] = rectangle[0] + self->size[0];
	rectangle[3] = rectangle[1] + self->size[1];
}

/* Check collisions. */
static void
_component_physics_collide_tick(ComponentPhysics* self, ECS* ecs)
{
	vec4 rectangle;

	_component_physics_rectangle_get(self, rectangle);

	for (s32 i = 0; i < (s32)ecs->lists[ECS_COMPONENT_PHYSICS].components.count; i++)
	{
		ComponentPhysics* physics;
		vec4 checkRectangle;

		physics = vector_get(&ecs->lists[ECS_COMPONENT_PHYSICS].components, i);

		if (physics->component.id == self->component.id)
			continue;

		_component_physics_rectangle_get(physics, checkRectangle);

		if (rectangle_collide(rectangle, checkRectangle))
			vector_push(&self->collisions, (void*)&physics->component.id);
	}
}

/* Sets physics component info. */
void
component_physics_init
(
	ComponentPhysics* self, 
	vec2 size,
	vec3 position, 
	f32 velocityMax, 
	f32 friction
)
{
	glm_vec2_copy(size, self->size);
	glm_vec3_copy(position, self->position);
	glm_vec3_zero(self->velocity);
	self->friction = friction;
	self->velocityMax = velocityMax;
}

/* Adds a physics component. */
void
component_physics_add(ComponentPhysics* self, ECS* ecs)
{
	vector_init(&self->collisions, sizeof(u32));
}

/* Deletes a physics component. */
void
component_physics_delete(ComponentPhysics* self, ECS* ecs)
{
	vector_free(&self->collisions);
}

/* Ticks physics component. */
void
component_physics_tick(ComponentPhysics* self, ECS* ecs)
{
	if (self->collisions.count > 0)
		vector_clear(&self->collisions);

	self->velocity[0] = CLAMP(self->velocity[0], -self->velocityMax, self->velocityMax);
	self->velocity[1] = CLAMP(self->velocity[1], -self->velocityMax, self->velocityMax);
	self->velocity[2] = CLAMP(self->velocity[2], -self->velocityMax, self->velocityMax);
	
	glm_vec3_add(self->velocity, self->position, self->position);

	glm_vec3_scale(self->velocity, self->friction, self->velocity);

	_component_physics_collide_tick(self, ecs);
}
