<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Open World HUD</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%;
    font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    color: #f5f5f5;
  }

  /* WORLD LAYER */
  #map {
    position: absolute;
    inset: 0;
  }
  #game {
    position: absolute;
    inset: 0;
    pointer-events: none;
  }

  /* UI LAYER */
  #ui {
    position: absolute;
    inset: 0;
    pointer-events: none; /* children will re-enable where needed */
  }

  /* TOP BAR */
  .top-bar {
    position: absolute;
    top: 10px;
    left: 50%;
    transform: translateX(-50%);
    min-width: 400px;
    padding: 6px 14px;
    border-radius: 999px;
    background: rgba(10, 10, 20, 0.85);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 16px;
    pointer-events: auto;
    font-size: 12px;
  }
  .top-bar span.label {
    opacity: 0.7;
    margin-right: 4px;
  }

  /* MINI DASH (BOTTOM CENTER) */
  .mini-dash {
    position: absolute;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    padding: 10px 18px;
    border-radius: 16px;
    background: rgba(10, 10, 20, 0.9);
    display: flex;
    gap: 18px;
    align-items: center;
    pointer-events: auto;
    font-size: 13px;
  }
  .mini-dash .metric {
    display: flex;
    flex-direction: column;
    gap: 2px;
  }
  .mini-dash .metric-label {
    font-size: 11px;
    opacity: 0.7;
  }
  .mini-dash .metric-value {
    font-weight: 600;
  }
  .bar {
    width: 80px;
    height: 6px;
    border-radius: 999px;
    background: rgba(255,255,255,0.1);
    overflow: hidden;
  }
  .bar-fill {
    height: 100%;
    border-radius: inherit;
  }
  .bar-fill.health { background: #ff4b6a; }
  .bar-fill.fuel   { background: #ffcc33; }
  .bar-fill.vhp    { background: #4bff9a; }

  /* MINIMAP */
  .minimap-wrapper {
    position: absolute;
    bottom: 20px;
    left: 20px;
    pointer-events: auto;
  }
  .minimap {
    position: relative;
    border-radius: 16px;
    overflow: hidden;
    background: rgba(10, 10, 20, 0.9);
    transition: width 0.2s ease, height 0.2s ease;
  }
  .minimap.small  { width: 160px; height: 160px; }
  .minimap.medium { width: 220px; height: 220px; }
  .minimap.large  { width: 320px; height: 320px; }

  .minimap-inner {
    position: absolute;
    inset: 0;
    background: #111;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #888;
    font-size: 11px;
  }

  /* Minimap overlay UI */
  .minimap-overlay {
    position: absolute;
    inset: 0;
    pointer-events: none;
  }
  .minimap-compass {
    position: absolute;
    top: 6px;
    left: 6px;
    width: 32px;
    height: 32px;
    border-radius: 999px;
    background: rgba(0,0,0,0.7);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 11px;
  }
  .minimap-stats {
    position: absolute;
    bottom: 6px;
    left: 6px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    font-size: 11px;
  }
  .minimap-zoom {
    position: absolute;
    top: 6px;
    right: 6px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    pointer-events: auto;
  }
  .zoom-btn {
    width: 22px;
    height: 22px;
    border-radius: 6px;
    border: none;
    background: rgba(0,0,0,0.8);
    color: #f5f5f5;
    font-size: 14px;
    cursor: pointer;
  }

  /* PHONE, PAUSE, INVENTORY, QUEST, NOTIFICATIONS */
  .corner-buttons {
    position: absolute;
    bottom: 20px;
    right: 20px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    pointer-events: auto;
  }
  .corner-btn {
    padding: 8px 12px;
    border-radius: 999px;
    border: none;
    background: rgba(10,10,20,0.9);
    color: #f5f5f5;
    font-size: 12px;
    cursor: pointer;
  }

  .panel {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 420px;
    max-width: 90vw;
    max-height: 70vh;
    transform: translate(-50%, -50%);
    background: rgba(8, 8, 16, 0.96);
    border-radius: 18px;
    padding: 16px;
    display: none;
    flex-direction: column;
    gap: 10px;
    pointer-events: auto;
  }
  .panel-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-weight: 600;
    margin-bottom: 6px;
  }
  .panel-close {
    border: none;
    background: transparent;
    color: #aaa;
    cursor: pointer;
    font-size: 16px;
  }
  .panel-body {
    font-size: 13px;
    color: #ddd;
    overflow: auto;
  }

  /* Notifications */
  .notifications {
    position: absolute;
    top: 70px;
    right: 20px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    pointer-events: auto;
    font-size: 12px;
  }
  .notification {
    padding: 8px 12px;
    border-radius: 10px;
    background: rgba(10,10,20,0.9);
  }
</style>
</head>
<body>

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

<div id="ui">
  <!-- TOP BAR -->
  <div class="top-bar">
    <div>
      <span class="label">Time</span><span id="hud-time">12:00</span>
    </div>
    <div>
      <span class="label">Weather</span><span id="hud-weather">Clear</span>
    </div>
    <div>
      <span class="label">Money</span><span id="hud-money">$12,345</span>
    </div>
  </div>

  <!-- MINI DASH -->
  <div class="mini-dash">
    <div class="metric">
      <div class="metric-label">Speed</div>
      <div class="metric-value"><span id="hud-speed">0</span> km/h</div>
    </div>
    <div class="metric">
      <div class="metric-label">Fuel</div>
      <div class="bar"><div class="bar-fill fuel" id="hud-fuel-bar" style="width:80%;"></div></div>
    </div>
    <div class="metric">
      <div class="metric-label">Vehicle HP</div>
      <div class="bar"><div class="bar-fill vhp" id="hud-vhp-bar" style="width:100%;"></div></div>
    </div>
  </div>

  <!-- MINIMAP -->
  <div class="minimap-wrapper">
    <div class="minimap small" id="minimap">
      <div class="minimap-inner">
        Mini Map
      </div>
      <div class="minimap-overlay">
        <div class="minimap-compass" id="minimap-compass">N</div>
        <div class="minimap-stats">
          <div>HP: <span id="hud-hp">100</span></div>
          <div>Shield: <span id="hud-shield">50</span></div>
        </div>
        <div class="minimap-zoom">
          <button class="zoom-btn" id="minimap-zoom-in">+</button>
          <button class="zoom-btn" id="minimap-zoom-out">−</button>
        </div>
      </div>
    </div>
  </div>

  <!-- CORNER BUTTONS -->
  <div class="corner-buttons">
    <button class="corner-btn" id="btn-phone">Phone</button>
    <button class="corner-btn" id="btn-inventory">Inventory</button>
    <button class="corner-btn" id="btn-quests">Quests</button>
    <button class="corner-btn" id="btn-pause">Pause</button>
  </div>

  <!-- PANELS -->
  <div class="panel" id="panel-phone">
    <div class="panel-header">
      <span>Phone</span>
      <button class="panel-close" data-close="panel-phone">✕</button>
    </div>
    <div class="panel-body">
      <p>Contacts, missions, messages will appear here.</p>
    </div>
  </div>

  <div class="panel" id="panel-inventory">
    <div class="panel-header">
      <span>Inventory</span>
      <button class="panel-close" data-close="panel-inventory">✕</button>
    </div>
    <div class="panel-body">
      <p>Items, weapons, car parts, etc.</p>
    </div>
  </div>

  <div class="panel" id="panel-quests">
    <div class="panel-header">
      <span>Quest Log</span>
      <button class="panel-close" data-close="panel-quests">✕</button>
    </div>
    <div class="panel-body">
      <p>Active missions and completed quests.</p>
    </div>
  </div>

  <div class="panel" id="panel-pause">
    <div class="panel-header">
      <span>Pause Menu</span>
      <button class="panel-close" data-close="panel-pause">✕</button>
    </div>
    <div class="panel-body">
      <p>Settings, controls, exit to main menu.</p>
    </div>
  </div>

  <!-- NOTIFICATIONS -->
  <div class="notifications" id="notifications">
    <!-- Example notification -->
    <!-- <div class="notification">Welcome to the city.</div> -->
  </div>
</div>

<script src="https://unpkg.com/maplibre-gl@3.6.2/dist/maplibre-gl.js"></script>
<script>
/* ================= WORLD ENGINE ================= */
let map, player, canvas, ctx;
let lastTime = performance.now();

const keys = { up:false, down:false, left:false, right:false };

window.addEventListener("keydown", e => {
  if (e.key === "w") keys.up = true;
  if (e.key === "s") keys.down = true;
  if (e.key === "a") keys.left = true;
  if (e.key === "d") keys.right = true;
});

window.addEventListener("keyup", e => {
  if (e.key === "w") keys.up = false;
  if (e.key === "s") keys.down = false;
  if (e.key === "a") keys.left = false;
  if (e.key === "d") keys.right = false;
});

class Player {
  constructor(lng, lat) {
    this.lng = lng;
    this.lat = lat;
    this.speed = 0;          // m/s
    this.direction = 0;      // degrees
    this.maxSpeed = 20;      // m/s
    this.accel = 30;         // m/s²
    this.friction = 0.9;

    this.health = 100;
    this.shield = 50;
    this.fuel = 80;
    this.vehicleHp = 100;

    this.img = new Image();
    this.img.src = "player.png";
  }

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

  update(dt) {
    if (keys.up) this.speed += this.accel * dt;
    if (keys.down) this.speed -= this.accel * dt;

    this.speed *= this.friction;

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

    if (keys.left) this.direction -= 140 * dt;
    if (keys.right) this.direction += 140 * 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);
    this.lng = newLng;
    this.lat = newLat;

    // Simple fake fuel drain for now
    this.fuel = Math.max(0, this.fuel - dt * 0.5);
  }

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

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

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.5,
    pitch: 0,
    bearing: 0
  });

  map.keyboard.disable();
  map.dragRotate.enable();
  map.touchZoomRotate.disableRotation();

  canvas = document.getElementById("game");
  ctx = canvas.getContext("2d");
  resizeCanvas();
  window.addEventListener("resize", resizeCanvas);

  player = new Player(173.284, -41.270);

  map.on("render", gameLoop);

  initUI();
};

function resizeCanvas() {
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
}

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

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

  ctx.clearRect(0, 0, canvas.width, canvas.height);
  player.draw(ctx);

  updateHUD(dt);
}

/* ================= HUD / UI LOGIC ================= */
function initUI() {
  // Minimap size cycle
  const minimap = document.getElementById("minimap");
  const sizes = ["small", "medium", "large"];
  let sizeIndex = 0;
  minimap.addEventListener("click", () => {
    sizeIndex = (sizeIndex + 1) % sizes.length;
    minimap.className = "minimap " + sizes[sizeIndex];
  });

  // Zoom buttons (for future minimap map instance)
  document.getElementById("minimap-zoom-in").addEventListener("click", e => {
    e.stopPropagation();
    // hook into minimap zoom later
  });
  document.getElementById("minimap-zoom-out").addEventListener("click", e => {
    e.stopPropagation();
  });

  // Panels
  const panels = {
    phone: document.getElementById("panel-phone"),
    inventory: document.getElementById("panel-inventory"),
    quests: document.getElementById("panel-quests"),
    pause: document.getElementById("panel-pause")
  };

  document.getElementById("btn-phone").addEventListener("click", () => togglePanel(panels.phone));
  document.getElementById("btn-inventory").addEventListener("click", () => togglePanel(panels.inventory));
  document.getElementById("btn-quests").addEventListener("click", () => togglePanel(panels.quests));
  document.getElementById("btn-pause").addEventListener("click", () => togglePanel(panels.pause));

  document.querySelectorAll(".panel-close").forEach(btn => {
    btn.addEventListener("click", () => {
      const id = btn.getAttribute("data-close");
      const panel = document.getElementById(id);
      if (panel) panel.style.display = "none";
    });
  });

  // Example notification
  pushNotification("Welcome to the city.");
}

function togglePanel(panel) {
  const visible = panel.style.display === "flex";
  panel.style.display = visible ? "none" : "flex";
}

function pushNotification(text) {
  const container = document.getElementById("notifications");
  const div = document.createElement("div");
  div.className = "notification";
  div.textContent = text;
  container.appendChild(div);
  setTimeout(() => {
    div.remove();
  }, 5000);
}

function updateHUD(dt) {
  // Speed in km/h (rough)
  const speedKmh = Math.abs(player.speed) * 3.6;
  document.getElementById("hud-speed").textContent = speedKmh.toFixed(0);

  // Fuel / vehicle HP bars
  document.getElementById("hud-fuel-bar").style.width = player.fuel + "%";
  document.getElementById("hud-vhp-bar").style.width = player.vehicleHp + "%";

  // Player HP / shield
  document.getElementById("hud-hp").textContent = player.health.toFixed(0);
  document.getElementById("hud-shield").textContent = player.shield.toFixed(0);

  // Time (fake for now)
  const t = new Date();
  const hh = String(t.getHours()).padStart(2, "0");
  const mm = String(t.getMinutes()).padStart(2, "0");
  document.getElementById("hud-time").textContent = `${hh}:${mm}`;

  // Compass always pointing North (static "N" for now)
  // Later: rotate based on map bearing if you want.
}

/* ================= FUTURE: JSON LOCATIONS =================
Example structure for locations.json:

[
  {
    "name": "KarModShop",
    "type": "car_mod_shop",
    "lat": -41.27000,
    "lng": 173.28450,
    "distortion": 1.04
  },
  {
    "name": "SafeHouse01",
    "type": "safe_house",
    "lat": -41.27123,
    "lng": 173.28678,
    "distortion": 0.98
  }
]

You’ll load it with fetch() and render icons on the minimap and world later.
=========================================================== */
</script>

</body>
</html>