<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Nelson Free Drive</title>

<link href="https://unpkg.com/maplibre-gl@3.6.2/dist/maplibre-gl.css" rel="stylesheet">

<style>
  html, body {
    margin: 0;
    padding: 0;
    overflow: hidden;
    height: 100%;
  }
  #map {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
  }
  #game {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
  }
</style>
</head>
<body>

<div id="map"></div>
<canvas id="game"></canvas>

<script src="https://unpkg.com/maplibre-gl@3.6.2/dist/maplibre-gl.js"></script>

<script>
let map;
let car;
let canvas, ctx;
let lastTime = performance.now();
let cameraLocked = true;

/* ---------------- INPUT ---------------- */
const keys = {
  carUp:false, carDown:false, carLeft:false, carRight:false,
  camUp:false, camDown:false, camLeft:false, camRight:false
};

window.addEventListener("keydown", e => {
  if (e.key === "w") keys.carUp = true;
  if (e.key === "s") keys.carDown = true;
  if (e.key === "a") keys.carLeft = true;
  if (e.key === "d") keys.carRight = true;

  if (e.key === "ArrowUp") { keys.camUp = true; cameraLocked = false; }
  if (e.key === "ArrowDown") { keys.camDown = true; cameraLocked = false; }
  if (e.key === "ArrowLeft") { keys.camLeft = true; cameraLocked = false; }
  if (e.key === "ArrowRight") { keys.camRight = true; cameraLocked = false; }
});

window.addEventListener("keyup", e => {
  if (e.key === "w") keys.carUp = false;
  if (e.key === "s") keys.carDown = false;
  if (e.key === "a") keys.carLeft = false;
  if (e.key === "d") keys.carRight = false;

  if (e.key === "ArrowUp") keys.camUp = false;
  if (e.key === "ArrowDown") keys.camDown = false;
  if (e.key === "ArrowLeft") keys.camLeft = false;
  if (e.key === "ArrowRight") keys.camRight = false;
});

/* ---------------- CAR ---------------- */
class Car {
  constructor(lng, lat) {
    this.lng = lng;
    this.lat = lat;
    this.speed = 0;
    this.direction = 0;
    this.maxSpeed = 12;
    this.accel = 3;
    this.friction = 0.92;

    this.img = new Image();
    this.img.src = "/car.png"; // Replace with your actual car sprite
  }

  moveMetres(dx, dy) {
    const p = map.project([this.lng, this.lat]);
    const newPoint = { x: p.x + dx, y: p.y + dy };
    const newLngLat = map.unproject(newPoint);
    return [newLngLat.lng, newLngLat.lat];
  }

  isOnRoad(lng, lat) {
    const p = map.project([lng, lat]);
    const features = map.queryRenderedFeatures([p.x, p.y], {
      layers: ["transportation"]
    });
    return features.length > 0;
  }

  update(dt) {
    if (keys.carUp) this.speed += this.accel * dt;
    if (keys.carDown) this.speed -= this.accel * 0.7 * dt;

    this.speed *= this.friction;

    if (this.speed > this.maxSpeed) this.speed = this.maxSpeed;
    if (this.speed < -this.maxSpeed * 0.5) this.speed = -this.maxSpeed * 0.5;

    if (keys.carLeft) this.direction -= 120 * dt;
    if (keys.carRight) this.direction += 120 * dt;

    const rad = this.direction * Math.PI / 180;
    const metres = this.speed * dt;

    const dx = Math.sin(rad) * metres;
    const dy = -Math.cos(rad) * metres;

    const [newLng, newLat] = this.moveMetres(dx, dy);

    if (this.isOnRoad(newLng, newLat)) {
      this.lng = newLng;
      this.lat = newLat;
    } else {
      this.speed = 0;
    }

    if (Math.abs(this.speed) > 0.1) {
      cameraLocked = true;
    }
  }

  draw(ctx, map) {
    const pos = map.project([this.lng, this.lat]);
    const size = 40;

    ctx.save();
    ctx.translate(pos.x, pos.y);
    ctx.rotate(Math.PI); // Car always points up
    ctx.drawImage(this.img, -size/2, -size/2, size, size);
    ctx.restore();
  }
}

/* ---------------- INIT ---------------- */
window.onload = () => {
  map = new maplibregl.Map({
    container: 'map',
    style: 'https://api.maptiler.com/maps/019d3452-4395-7ecd-bbf0-c64a3d5060cd/style.json?key=uHmPABwBFcVhiPJcdCzb',
    center: [173.284, -41.270],
    zoom: 17,
    pitch: 0,
    bearing: 0
  });

  canvas = document.getElementById("game");
  ctx = canvas.getContext("2d");

  resizeCanvas();
  window.addEventListener("resize", resizeCanvas);

  car = new Car(173.284, -41.270);

  map.on("dragstart", () => cameraLocked = false);
  map.on("rotatestart", () => cameraLocked = false);

  map.on("render", gameLoop);
};

/* ---------------- HELPERS ---------------- */
function resizeCanvas() {
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
}

/* ---------------- MAIN LOOP ---------------- */
function gameLoop() {
  const now = performance.now();
  const dt = (now - lastTime) / 1000;
  lastTime = now;

  const camSpeed = 10;
  if (keys.camUp)    map.panBy([0, -camSpeed], { animate:false });
  if (keys.camDown)  map.panBy([0,  camSpeed], { animate:false });
  if (keys.camLeft)  map.panBy([-camSpeed, 0], { animate:false });
  if (keys.camRight) map.panBy([ camSpeed, 0], { animate:false });

  car.update(dt);

  if (cameraLocked) {
    map.setCenter([car.lng, car.lat]);
    map.setBearing(-car.direction);
  }

  ctx.clearRect(0, 0, canvas.width, canvas.height);
  car.draw(ctx, map);
}
</script>

</body>
</html>