#ifndef _fencer_rigidbody_h
#define _fencer_rigidbody_h

#include "shape.h"
#include "transformable.h"
#include "list.h"
#include "stdint.h"
#include "physics.h"

typedef struct {
    Collision hit;
    float duration;
} Contact;

typedef struct RigidBody RigidBody;
typedef struct PhysicsEntity PhysicsEntity;

typedef void (*CollisionHandlerFn)(void* obj, List* collisions);

// Referenced transform is stored but not owned by the rigidbody.
extern RigidBody* rigidbody_make(PhysicsEntity owner);
extern void rigidbody_destroy(RigidBody* self);

extern void rigidbody_add_contact(RigidBody* self, struct Collision hit);
extern void rigidbody_collect_contacts(RigidBody* self);
extern List* rigidbody_get_contacts(RigidBody* self);

extern void rigidbody_integrate_forces(RigidBody* self);

extern float rigidbody_get_mass(const RigidBody* self);
extern void rigidbody_set_mass(RigidBody* self, float mass);

extern float rigidbody_get_bounce(const RigidBody* self);
extern void rigidbody_set_bounce(RigidBody* self, float bounce);

extern void rigidbody_add_impulse(RigidBody* self, Vector force, int use_mass);
extern void rigidbody_accelerate(RigidBody* self, Vector force, int use_mass);

extern PhysicsMask rigidbody_get_layers(RigidBody* self);
extern void rigidbody_set_layers(RigidBody* self, PhysicsMask layers);

extern PhysicsMask rigidbody_get_collision_mask(RigidBody* self);
extern void rigidbody_set_collision_mask(RigidBody* self, PhysicsMask mask);

extern int rigidbody_get_overlap(RigidBody* self);
extern void rigidbody_set_overlap(RigidBody* self, int value);

extern int rigidbody_is_static(RigidBody* self);
extern void rigidbody_set_static(RigidBody* self, int value);

extern Vector rigidbody_get_velocity(const RigidBody* self);
extern void rigidbody_set_velocity(RigidBody* self, Vector velocity);

extern Vector rigidbody_get_force(RigidBody* self);

extern void rigidbody_add_collider(RigidBody* self, Collider* collider);
extern void rigidbody_remove_collider(RigidBody* self, Collider* collider);
extern List* rigidbody_get_colliders(RigidBody* self);

extern void rigidbody_debug_draw_contacts(RigidBody* self);

extern Transform* rigidbody_get_transform(RigidBody* self);

impl_Transformable_for(RigidBody,
    rigidbody_get_transform
)

#endif // !_fencer_rigidbody_h
