import { Cancel, Source } from "./source";

export type PhysicsTick = ["physics"];
export type RenderTick = ["render", number];

export function tick(fps: number): Source<PhysicsTick | RenderTick> {
  function tickSource(): PhysicsTick;
  function tickSource(
    callback: (tick: PhysicsTick | RenderTick) => void
  ): Cancel;
  function tickSource(callback?: (tick: PhysicsTick | RenderTick) => void) {
    if (callback) {
      let lastPhysicsTick: number = new Date().getTime();

      const physicsInterval = setInterval(() => {
        lastPhysicsTick = new Date().getTime();
        callback(["physics"]);
      }, 1000 / fps);

      let animationFrame = requestAnimationFrame(function animationTick() {
        const now = new Date().getTime();
        callback(["render", now - lastPhysicsTick]);
        animationFrame = requestAnimationFrame(animationTick);
      });

      return () => {
        clearInterval(physicsInterval);
        cancelAnimationFrame(animationFrame);
      };
    } else {
      return ["physics"];
    }
  }

  return tickSource;
}