#include <stddef.h>
#include "world.h"

const float scale = 43.7445319335f;
const float g = 9.81f * scale;

const float PLAYER_FORCE = 3500.0f;
const float JUMP_FORCE = 22000.0f;

const float AIR_DRAG = 0.999f;

const float GROUND_FRICTION = 1200.0f;
const float MAX_PLAYER_SPEED = 300.0f;

const float BOUNCE = 0.45f;

const float ground_y = 550.0f;

Entity entities[MAX_ENTITIES];

Entity *player = NULL;

bool isSimulating = true;

float simTime = 0.0f;

void ApplyForce(Entity *e, Vector2 force)
{
    if (!e || !e->active)
        return;

    e->force.x += force.x;
    e->force.y += force.y;
}

bool IsGrounded(Entity *e)
{
    if (!e)
        return false;

    return (
        e->position.y +
        e->size * 0.5f >=
        ground_y - 2.0f
    );
}

Entity *SpawnEntity(
    float x,
    float y,
    float size,
    float mass,
    Color color)
{
    for (int i = 0; i < MAX_ENTITIES; i++)
    {
        if (!entities[i].active)
        {
            Entity *e = &entities[i];

            e->active = true;

            e->isPlayer = false;
            e->affectedByGravity = true;

            e->mass = mass;
            e->size = size;

            e->position = (Vector2){x, y};
            e->velocity = (Vector2){0, 0};
            e->acceleration = (Vector2){0, 0};
            e->force = (Vector2){0, 0};

            e->color = color;

            return e;
        }
    }

    return NULL;
}

void ClearWorld(void)
{
    for (int i = 0; i < MAX_ENTITIES; i++)
    {
        entities[i].active = false;
    }

    player = NULL;
}

void InitWorld(void)
{
    ClearWorld();

    player = SpawnEntity(
        120,
        120,
        40,
        1.0f,
        BLUE);

    if (player)
    {
        player->isPlayer = true;
    }

    for (int i = 0; i < 8; i++)
    {
        SpawnEntity(
            300 + i * 50,
            50,
            25,
            1.0f,
            RED);
    }

    simTime = 0.0f;
}

int CountEntities(void)
{
    int count = 0;

    for (int i = 0; i < MAX_ENTITIES; i++)
    {
        if (entities[i].active)
            count++;
    }

    return count;
}
