#include "local.h"

static alias_R _physics_speed = 1;

alias_Physics2DBundle * Engine_physics_2d_bundle(void) {
  static alias_Physics2DBundle bundle;
  static bool init = false;
  if(!init) {
    alias_Physics2DBundle_initialize(Engine_ecs(), &bundle, Engine_transform_bundle());
    init = true;
  }
  return &bundle;
}

alias_R Engine_physics_speed(void) {
  return _physics_speed;
}

void Engine_set_physics_speed(alias_R speed) {
  _physics_speed = speed;
}

//alias_R Engine_frame_time(void) {
//  return Backend_get_frame_time();
//}
//
//alias_R Engine_time(void) {
//  return Backend_get_time();
//}

void Engine__update_physics(void) {
  const float timestep = 1.0f / 60.0f;

  static float p_time = 0.0f;
  static float s_time = 0.0f;

  static uint64_t last_hrtime = 0;
  uint64_t hrtime = uv_hrtime();

  if(hrtime < last_hrtime) {
    s_time += (float)((double)(hrtime - last_hrtime) * (double)_physics_speed * (1.0d / 1000000000.0d));
  }

  last_hrtime = hrtime;

  if(p_time >= s_time) {
    alias_transform_update2d_serial(Engine_ecs(), Engine_transform_bundle());
  }

  while(p_time < s_time) {
    alias_physics_update2d_serial_pre_transform(Engine_ecs(), Engine_physics_2d_bundle(), timestep);

    alias_transform_update2d_serial(Engine_ecs(), Engine_transform_bundle());

    alias_physics_update2d_serial_post_transform(Engine_ecs(), Engine_physics_2d_bundle(), timestep);

    p_time += timestep;
  }
}