// F3. Тахометр + спидометр + одометр (§11-13) — игра в автогонщика.
(function(){
'use strict';
const B = () => window.PHYS9_FLAG_BASE;
const C = () => window.PHYS9_COLORS || {};

function init(secId){
  if (!B()) return false;
  const body = ''
    + '<div class="flag-sliders">'
      + '<label>Газ (a₊, м/с²): <b id="F3-gv">2</b><input type="range" id="F3-g" min="0" max="8" step="0.5" value="2"></label>'
      + '<label>Тормоз (|a₋|, м/с²): <b id="F3-bv">4</b><input type="range" id="F3-b" min="0" max="10" step="0.5" value="4"></label>'
      + '<label>Цель скорости, м/с: <b id="F3-tv">16.7</b><input type="range" id="F3-t" min="5" max="30" step="0.5" value="16.7"></label>'
    + '</div>'
    + '<canvas id="F3-cv" class="flag-canvas" width="640" height="400" style="height:400px"></canvas>'
    + '<div class="flag-controls">'
      + '<button class="flag-btn primary" id="F3-gas">⬆ Газ</button>'
      + '<button class="flag-btn danger" id="F3-brake">⬇ Тормоз</button>'
      + '<button class="flag-btn" id="F3-coast">Отпустить</button>'
      + '<button class="flag-btn" id="F3-reset">Сброс</button>'
    + '</div>'
    + '<div class="flag-stats">'
      + '<div class="flag-stat"><span class="lbl">Время</span><span class="val" id="F3-t-st">0 с</span></div>'
      + '<div class="flag-stat"><span class="lbl">$v$ (спидометр)</span><span class="val" id="F3-v">0 м/с</span></div>'
      + '<div class="flag-stat"><span class="lbl">$a$ (тахометр)</span><span class="val" id="F3-a">0 м/с²</span></div>'
      + '<div class="flag-stat"><span class="lbl">$\\Delta x$ (одометр)</span><span class="val" id="F3-x">0 м</span></div>'
      + '<div class="flag-stat"><span class="lbl">Рекорд скорости</span><span class="val" id="F3-rec">0 м/с</span></div>'
    + '</div>'
    + '<div class="flag-feedback" id="F3-fb"></div>';

  const card = B().makeCard(secId,
    'F3. Тахометр + спидометр + одометр',
    'Управляй автомобилем кнопками. Тахометр (a), спидометр (v) и одометр (Δx) — связаны. Разгонись до цели и затормози.',
    body);
  if (!card) return false;

  const cv = document.getElementById('F3-cv');
  const ctx = cv.getContext('2d');
  const W = cv.width, H = cv.height;

  let st = { t: 0, v: 0, x: 0, a: 0, mode: 'coast', history: [], targetHit: false };

  function readSliders(){
    document.getElementById('F3-gv').textContent = (+document.getElementById('F3-g').value).toFixed(1);
    document.getElementById('F3-bv').textContent = (+document.getElementById('F3-b').value).toFixed(1);
    document.getElementById('F3-tv').textContent = (+document.getElementById('F3-t').value).toFixed(1);
  }

  function reset(){
    st = { t: 0, v: 0, x: 0, a: 0, mode: 'coast', history: [], targetHit: false };
    document.getElementById('F3-fb').className = 'flag-feedback';
  }

  function tick(dt){
    const gas = +document.getElementById('F3-g').value;
    const brake = +document.getElementById('F3-b').value;
    const target = +document.getElementById('F3-t').value;
    if (st.mode === 'gas') st.a = gas;
    else if (st.mode === 'brake') st.a = st.v > 0.1 ? -brake : 0;
    else /* coast */ st.a = st.v > 0.05 ? -0.5 : 0;  /* лёгкое торможение от трения */
    st.v = Math.max(0, st.v + st.a * dt);
    st.x += st.v * dt;
    st.t += dt;
    st.history.push({ t: st.t, v: st.v, a: st.a });
    if (st.history.length > 600) st.history.shift();
    /* Цель достигнута? */
    if (!st.targetHit && Math.abs(st.v - target) < 0.5){
      st.targetHit = true;
      const fb = document.getElementById('F3-fb');
      fb.className = 'flag-feedback ok show';
      fb.innerHTML = '&#10003; Цель достигнута! Скорость '+st.v.toFixed(1)+' м/с (~'+(st.v*3.6).toFixed(0)+' км/ч). Теперь затормози.';
    }
    /* Рекорд */
    const rec = B().saveRecord('F3_max_v', st.v);
    document.getElementById('F3-rec').textContent = rec.toFixed(1) + ' м/с';
    /* UI */
    document.getElementById('F3-t-st').textContent = st.t.toFixed(1) + ' с';
    document.getElementById('F3-v').textContent = st.v.toFixed(1) + ' м/с';
    document.getElementById('F3-a').textContent = st.a.toFixed(1) + ' м/с²';
    document.getElementById('F3-x').textContent = st.x.toFixed(1) + ' м';
    draw();
  }

  function drawGauge(cx, cy, r, val, min, max, label, unit, color){
    const col = C();
    /* фон */
    ctx.fillStyle = col.bgSubtle || '#f8fafc';
    ctx.beginPath(); ctx.arc(cx, cy, r, 0, Math.PI*2); ctx.fill();
    ctx.strokeStyle = col.axis || '#1e293b';
    ctx.lineWidth = 2;
    ctx.beginPath(); ctx.arc(cx, cy, r, 0, Math.PI*2); ctx.stroke();
    /* шкала */
    const a0 = Math.PI*0.75, a1 = Math.PI*2.25;
    ctx.strokeStyle = col.text || '#0f172a';
    ctx.lineWidth = 2;
    for (let i = 0; i <= 10; i++){
      const a = a0 + (a1 - a0) * (i/10);
      const x1 = cx + (r-10) * Math.cos(a), y1 = cy + (r-10) * Math.sin(a);
      const x2 = cx + r * Math.cos(a), y2 = cy + r * Math.sin(a);
      ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.stroke();
    }
    /* стрелка */
    const norm = Math.max(0, Math.min(1, (val - min)/(max - min)));
    const a = a0 + (a1 - a0) * norm;
    const tipX = cx + (r-15) * Math.cos(a), tipY = cy + (r-15) * Math.sin(a);
    ctx.strokeStyle = color;
    ctx.lineWidth = 4;
    ctx.lineCap = 'round';
    ctx.beginPath(); ctx.moveTo(cx, cy); ctx.lineTo(tipX, tipY); ctx.stroke();
    ctx.fillStyle = color;
    ctx.beginPath(); ctx.arc(cx, cy, 5, 0, Math.PI*2); ctx.fill();
    /* подписи */
    ctx.fillStyle = col.text || '#0f172a';
    ctx.font = 'bold 11px Inter,sans-serif';
    ctx.textAlign = 'center';
    ctx.fillText(label, cx, cy - r - 6);
    ctx.font = 'bold 18px Inter,sans-serif';
    ctx.fillText(val.toFixed(1), cx, cy + r/2);
    ctx.font = '11px Inter,sans-serif';
    ctx.fillText(unit, cx, cy + r/2 + 14);
    ctx.textAlign = 'left';
  }

  function draw(){
    const col = C();
    ctx.fillStyle = col.bg || '#fafafa';
    ctx.fillRect(0, 0, W, H);
    /* 3 прибора в верху */
    drawGauge(110, 80, 55, st.a, -10, 8, 'ТАХОМЕТР (a)', 'м/с²', col.acceleration || '#ea580c');
    drawGauge(320, 80, 55, st.v, 0, 35, 'СПИДОМЕТР (v)', 'м/с', col.velocity || '#0891b2');
    drawGauge(530, 80, 55, st.x % 1000, 0, 1000, 'ОДОМЕТР (Δx)', 'м', col.displacement || '#2563eb');
    /* график v(t) и a(t) внизу */
    const gx = 20, gy = 180, gw = W - 40, gh = 180;
    ctx.fillStyle = col.bgSubtle || '#f8fafc';
    ctx.fillRect(gx, gy, gw, gh);
    ctx.strokeStyle = col.axis || '#1e293b';
    ctx.lineWidth = 1.5;
    ctx.beginPath();
    ctx.moveTo(gx, gy + gh/2); ctx.lineTo(gx + gw, gy + gh/2);  /* ось t для a */
    ctx.moveTo(gx, gy + gh); ctx.lineTo(gx + gw, gy + gh);  /* ось t для v */
    ctx.stroke();
    /* сетка */
    ctx.strokeStyle = col.grid || '#e5e7eb';
    ctx.lineWidth = 1;
    const tMax = Math.max(20, st.t);
    for (let i = 0; i <= 10; i++){
      const px = gx + (i/10)*gw;
      ctx.beginPath(); ctx.moveTo(px, gy); ctx.lineTo(px, gy+gh); ctx.stroke();
    }
    /* подписи */
    ctx.fillStyle = col.textMuted || '#64748b';
    ctx.font = '10px Inter,sans-serif';
    ctx.fillText('v(t)', gx + 4, gy + gh - 4);
    ctx.fillText('a(t)', gx + 4, gy + gh/2 - 4);
    ctx.fillText('t, с', gx + gw - 24, gy + gh + 12);
    /* линии */
    if (st.history.length > 1){
      ctx.strokeStyle = col.velocity || '#0891b2';
      ctx.lineWidth = 2.5;
      ctx.beginPath();
      for (let i = 0; i < st.history.length; i++){
        const p = st.history[i];
        const px = gx + (p.t / tMax) * gw;
        const py = gy + gh - (p.v / 35) * (gh/2);
        if (i === 0) ctx.moveTo(px, py); else ctx.lineTo(px, py);
      }
      ctx.stroke();
      ctx.strokeStyle = col.acceleration || '#ea580c';
      ctx.beginPath();
      for (let i = 0; i < st.history.length; i++){
        const p = st.history[i];
        const px = gx + (p.t / tMax) * gw;
        const py = gy + gh/2 - (p.a / 12) * (gh/4);
        if (i === 0) ctx.moveTo(px, py); else ctx.lineTo(px, py);
      }
      ctx.stroke();
    }
    /* цель скорости — горизонталь */
    const target = +document.getElementById('F3-t').value;
    ctx.strokeStyle = '#fbbf24';
    ctx.setLineDash([6, 4]);
    ctx.lineWidth = 2;
    const targetY = gy + gh - (target / 35) * (gh/2);
    ctx.beginPath(); ctx.moveTo(gx, targetY); ctx.lineTo(gx + gw, targetY); ctx.stroke();
    ctx.setLineDash([]);
    ctx.fillStyle = '#92400e';
    ctx.font = 'bold 11px Inter,sans-serif';
    ctx.fillText('★ цель '+target.toFixed(1)+' м/с', gx + gw - 110, targetY - 4);
  }

  document.getElementById('F3-gas').addEventListener('mousedown', ()=>{ st.mode = 'gas'; });
  document.getElementById('F3-gas').addEventListener('mouseup', ()=>{ st.mode = 'coast'; });
  document.getElementById('F3-brake').addEventListener('mousedown', ()=>{ st.mode = 'brake'; });
  document.getElementById('F3-brake').addEventListener('mouseup', ()=>{ st.mode = 'coast'; });
  document.getElementById('F3-coast').addEventListener('click', ()=>{ st.mode = 'coast'; });
  document.getElementById('F3-reset').addEventListener('click', reset);
  ['F3-g','F3-b','F3-t'].forEach(id => document.getElementById(id).addEventListener('input', readSliders));

  readSliders();
  draw();
  B().startLoop('F3', cv, tick);
  return true;
}

if (window.PHYS9_FLAG_BASE) window.PHYS9_FLAG_BASE.register('F3', { init: init, cleanup: function(){} });
else document.addEventListener('DOMContentLoaded', ()=>{
  if (window.PHYS9_FLAG_BASE) window.PHYS9_FLAG_BASE.register('F3', { init: init, cleanup: function(){} });
});

})();
