const keys = { w:false, s:false, a:false, d:false };

window.onkeydown = e => keys[e.key] = true;
window.onkeyup = e => keys[e.key] = false;

let map, player, ctx;

class Player {
  constructor(lng, lat) {
    this.lng = lng;
    this.lat = lat;

    this.heading = 0;
    this.speed = 0;

    this.maxSpeed = 40;
    this.accel = 20;
    this.brake = 30;
    this.turnRate = 120;
    this.friction = 8;
  }

  update(dt) {

    const speedFactor = Math.abs(this.speed) / this.maxSpeed;
    const turn = this.turnRate * (0.3 + speedFactor);

    if (keys.a) this.heading -= turn * dt;
    if (keys.d) this.heading += turn * dt;

    if (keys.w) this.speed += this.accel * dt;
    if (keys.s) this.speed -= this.brake * dt;

    if (!keys.w && !keys.s) {
      this.speed *= 0.98;
    }

    const rad = this.heading * Math.PI/180;
    const p = map.project([this.lng, this.lat]);

    const np = {
      x: p.x + Math.cos(rad)*this.speed*dt,
      y: p.y + Math.sin(rad)*this.speed*dt
    };

    const ll = map.unproject(np);
    this.lng = ll.lng;
    this.lat = ll.lat;
  }
}

function initMenu() {
  const m = document.getElementById("menu");

  m.innerHTML = `
    accel <input id="accel" type="range" min="1" max="50">
    brake <input id="brake" type="range" min="1" max="60">
    maxSpeed <input id="maxSpeed" type="range" min="5" max="100">
    friction <input id="friction" type="range" min="0" max="20">
    turnRate <input id="turnRate" type="range" min="30" max="300">

    zoom <input id="zoom" type="range" min="15" max="20" step="0.1">
    pitch <input id="pitch" type="range" min="0" max="80">

    lng <input id="lng" type="number">
    lat <input id="lat" type="number">

    <button id="spawn">Respawn</button>
    <button id="reset">Reset</button>
  `;

  ["accel","brake","maxSpeed","friction","turnRate"].forEach(id=>{
    document.getElementById(id).oninput = e=>{
      player[id] = parseFloat(e.target.value);
    };
  });

  document.getElementById("zoom").oninput = e=> map.setZoom(e.target.value);
  document.getElementById("pitch").oninput = e=> map.setPitch(e.target.value);

  document.getElementById("spawn").onclick = ()=>{
    player.lng = parseFloat(lng.value);
    player.lat = parseFloat(lat.value);
  };
}

window.onload = ()=>{

  map = new maplibregl.Map({
    container:"map",
    style:"./map-style.json",
    center:[173.284, -41.270],
    zoom:17.5,
    pitch:55
  });

  const canvas = document.getElementById("game");
  ctx = canvas.getContext("2d");
  canvas.width = innerWidth;
  canvas.height = innerHeight;

  player = new Player(173.284, -41.270);

  initMenu();

  let last = performance.now();

  map.on("render", ()=>{
    const now = performance.now();
    const dt = (now-last)/1000;
    last = now;

    player.update(dt);
    map.setCenter([player.lng, player.lat]);

    ctx.clearRect(0,0,canvas.width,canvas.height);
  });
};