// F12. Американские горки (§35 в ch4) — нарисуй профиль, шарик катится, ЗСМЭ.
(function(){
'use strict';
const B = () => window.PHYS9_FLAG_BASE;
const C = () => window.PHYS9_COLORS || {};

function init(secId){
  if (!B()) return false;
  const body = ''
    + '<div style="margin-bottom:8px;font-size:.85rem;color:var(--muted)">Нажми и проведи мышкой по канвасу — нарисуй профиль горки (слева направо).</div>'
    + '<canvas id="F12-cv" class="flag-canvas" width="700" height="360" style="height:360px;cursor:crosshair"></canvas>'
    + '<div class="flag-sliders">'
      + '<label>$\\mu$ трение: <b id="F12-muv">0</b><input type="range" id="F12-mu" min="0" max="0.5" step="0.02" value="0"></label>'
      + '<label>Масса шарика, кг: <b id="F12-mv">1</b><input type="range" id="F12-m" min="0.1" max="5" step="0.1" value="1"></label>'
    + '</div>'
    + '<div class="flag-controls">'
      + '<button class="flag-btn primary" id="F12-go">Старт</button>'
      + '<button class="flag-btn" id="F12-reset">Сброс</button>'
      + '<button class="flag-btn" id="F12-preset1">Шаблон: горка</button>'
      + '<button class="flag-btn" id="F12-preset2">Шаблон: петля</button>'
      + '<button class="flag-btn danger" id="F12-clear">Очистить</button>'
    + '</div>'
    + '<div class="flag-stats">'
      + '<div class="flag-stat"><span class="lbl">$E_p$ (mgh)</span><span class="val" id="F12-Ep">0 Дж</span></div>'
      + '<div class="flag-stat"><span class="lbl">$E_k$ (mv²/2)</span><span class="val" id="F12-Ek">0 Дж</span></div>'
      + '<div class="flag-stat"><span class="lbl">$E$ полная</span><span class="val" id="F12-Et">0 Дж</span></div>'
      + '<div class="flag-stat"><span class="lbl">$v$</span><span class="val" id="F12-v">0 м/с</span></div>'
    + '</div>';

  const card = B().makeCard(secId,
    'F12. Американские горки',
    'Нарисуй профиль горки и запусти шарик. Без трения $E_k + E_p = $ const. Со трением — энергия диссипирует.',
    body);
  if (!card) return false;

  const cv = document.getElementById('F12-cv');
  const ctx = cv.getContext('2d');
  const W = cv.width, H = cv.height;
  const m_per_px = 0.05;  /* 5 см / px */

  let profile = [];  /* отсортированный по x массив {x, y} */
  let drawing = false;
  let ball = { idx: 0, fraction: 0, vAlong: 0, energy0: 0, lossE: 0, running: false };

  function getPos(e){
    const rect = cv.getBoundingClientRect();
    const sx = cv.width / rect.width;
    const sy = cv.height / rect.height;
    const x = ((e.touches ? e.touches[0].clientX : e.clientX) - rect.left) * sx;
    const y = ((e.touches ? e.touches[0].clientY : e.clientY) - rect.top) * sy;
    return { x, y };
  }

  function start(e){
    drawing = true;
    profile = [getPos(e)];
    e.preventDefault();
    draw();
  }
  function move(e){
    if (!drawing) return;
    const p = getPos(e);
    const last = profile[profile.length-1];
    if (p.x > last.x + 3) profile.push(p);
    e.preventDefault();
    draw();
  }
  function end(){ drawing = false; }

  function presetHill(){
    profile = [];
    for (let x = 30; x <= W - 30; x += 8){
      const norm = x / (W - 60);
      const y = 50 + 250 * Math.abs(norm - 0.5) * (1 - norm*0.8);
      profile.push({ x, y });
    }
    reset();
  }
  function presetLoop(){
    profile = [];
    /* три горки */
    for (let x = 30; x <= W - 30; x += 6){
      const t = (x - 30) / (W - 60);
      const y = 70 + 240 * (1 - t) * 0.4 + 100 * Math.sin(t * Math.PI * 2.2);
      profile.push({ x, y: Math.max(40, Math.min(H - 20, y)) });
    }
    reset();
  }
  function clear(){ profile = []; reset(); }

  function reset(){
    if (profile.length > 1){
      ball = { idx: 0, fraction: 0, vAlong: 0, running: false };
      const m = +document.getElementById('F12-m').value;
      const h = (H - profile[0].y) * m_per_px;
      ball.energy0 = m * 9.8 * h;
      ball.lossE = 0;
    }
    document.getElementById('F12-go').textContent = 'Старт';
    draw();
  }

  function tick(dt){
    if (!ball.running || profile.length < 2) { draw(); return; }
    /* Движение по профилю: используем сегменты. */
    const m = +document.getElementById('F12-m').value;
    const mu = +document.getElementById('F12-mu').value;
    const g = 9.8;
    /* Текущая высота */
    const i = ball.idx;
    if (i >= profile.length - 1){ ball.running = false; document.getElementById('F12-go').textContent='Старт'; draw(); return; }
    const p1 = profile[i], p2 = profile[i+1];
    const segLen_px = Math.hypot(p2.x - p1.x, p2.y - p1.y);
    const segLen = segLen_px * m_per_px;
    const slope = (p2.y - p1.y) / (p2.x - p1.x);
    const sinA = slope / Math.sqrt(1 + slope*slope);  /* y SVG вниз — slope>0 = вниз */
    const cosA = 1 / Math.sqrt(1 + slope*slope);
    /* Ускорение вдоль профиля: a = g*sinA - μ*g*cosA*sign(v) */
    let aAlong = g * sinA;
    if (Math.abs(ball.vAlong) > 0.01) aAlong -= Math.sign(ball.vAlong) * mu * g * cosA;
    /* шаг */
    ball.vAlong += aAlong * dt;
    /* трение тратит энергию */
    if (mu > 0) ball.lossE += mu * m * g * cosA * Math.abs(ball.vAlong * dt);
    const ds = ball.vAlong * dt;  /* в метрах */
    ball.fraction += ds / Math.max(0.01, segLen);
    /* переход к следующему сегменту */
    while (ball.fraction >= 1 && ball.idx < profile.length - 1){
      ball.fraction -= 1;
      ball.idx++;
    }
    while (ball.fraction < 0 && ball.idx > 0){
      ball.fraction += 1;
      ball.idx--;
    }
    if (ball.idx >= profile.length - 1 || ball.idx < 0){
      ball.running = false;
      document.getElementById('F12-go').textContent='Старт';
    }
    /* статистика */
    const px = p1.x + ball.fraction * (p2.x - p1.x);
    const py = p1.y + ball.fraction * (p2.y - p1.y);
    const h = (H - py) * m_per_px;
    const v = Math.abs(ball.vAlong);
    const Ep = m * g * h;
    const Ek = m * v * v / 2;
    document.getElementById('F12-Ep').textContent = Ep.toFixed(1) + ' Дж';
    document.getElementById('F12-Ek').textContent = Ek.toFixed(1) + ' Дж';
    document.getElementById('F12-Et').textContent = (Ep + Ek).toFixed(1) + ' Дж';
    document.getElementById('F12-v').textContent = v.toFixed(2) + ' м/с';
    draw();
  }

  function draw(){
    const col = C();
    ctx.fillStyle = col.bg || '#fafafa';
    ctx.fillRect(0, 0, W, H);
    /* земля */
    ctx.fillStyle = col.surface || '#a16207';
    ctx.fillRect(0, H - 10, W, 10);
    if (profile.length < 2){
      ctx.fillStyle = col.textMuted || '#64748b';
      ctx.font = '15px Inter,sans-serif';
      ctx.fillText('Нарисуй профиль горки слева направо мышкой/пальцем', 90, H/2);
      return;
    }
    /* профиль */
    ctx.strokeStyle = col.bodyAccent || '#1e293b';
    ctx.lineWidth = 4;
    ctx.lineJoin = 'round';
    ctx.beginPath();
    ctx.moveTo(profile[0].x, profile[0].y);
    for (let i = 1; i < profile.length; i++) ctx.lineTo(profile[i].x, profile[i].y);
    ctx.stroke();
    /* заливка под профилем */
    ctx.fillStyle = 'rgba(161,98,7,0.2)';
    ctx.beginPath();
    ctx.moveTo(profile[0].x, H);
    for (let i = 0; i < profile.length; i++) ctx.lineTo(profile[i].x, profile[i].y);
    ctx.lineTo(profile[profile.length-1].x, H);
    ctx.closePath();
    ctx.fill();
    /* шарик */
    if (ball.idx < profile.length - 1){
      const p1 = profile[ball.idx], p2 = profile[ball.idx+1];
      const px = p1.x + ball.fraction * (p2.x - p1.x);
      const py = p1.y + ball.fraction * (p2.y - p1.y) - 9;
      ctx.fillStyle = col.fail || '#dc2626';
      ctx.beginPath(); ctx.arc(px, py, 9, 0, Math.PI*2); ctx.fill();
      ctx.strokeStyle = '#fff'; ctx.lineWidth = 1.5; ctx.stroke();
    }
    /* Линия энергии — горизонтальный уровень energy0 показывает потери при трении */
    if (ball.energy0 > 0){
      const m = +document.getElementById('F12-m').value;
      const g = 9.8;
      const E_height = ball.energy0 / (m*g);   /* высота, эквивалентная энергии */
      const E_py = H - E_height / m_per_px;
      ctx.strokeStyle = '#10b981';
      ctx.setLineDash([8, 5]);
      ctx.lineWidth = 1.5;
      ctx.beginPath(); ctx.moveTo(0, E_py); ctx.lineTo(W, E_py); ctx.stroke();
      ctx.setLineDash([]);
      ctx.fillStyle = '#10b981';
      ctx.font = 'bold 11px Inter,sans-serif';
      ctx.fillText('E₀ = ' + ball.energy0.toFixed(1) + ' Дж', 8, E_py - 4);
      /* линия потерь */
      if (ball.lossE > 0){
        const lossH = ball.lossE / (m*g);
        const py = E_py + lossH / m_per_px;
        ctx.strokeStyle = '#dc2626';
        ctx.setLineDash([4, 3]);
        ctx.beginPath(); ctx.moveTo(0, py); ctx.lineTo(W, py); ctx.stroke();
        ctx.setLineDash([]);
        ctx.fillStyle = '#dc2626';
        ctx.fillText('потери: ' + ball.lossE.toFixed(1) + ' Дж', 8, py - 4);
      }
    }
  }

  cv.addEventListener('mousedown', start);
  cv.addEventListener('mousemove', move);
  cv.addEventListener('mouseup', end);
  cv.addEventListener('mouseleave', end);
  cv.addEventListener('touchstart', start, {passive:false});
  cv.addEventListener('touchmove', move, {passive:false});
  cv.addEventListener('touchend', end);

  document.getElementById('F12-go').addEventListener('click', ()=>{
    if (profile.length < 2) return;
    if (ball.idx >= profile.length - 1) reset();
    ball.running = !ball.running;
    document.getElementById('F12-go').textContent = ball.running ? 'Пауза' : 'Старт';
  });
  document.getElementById('F12-reset').addEventListener('click', reset);
  document.getElementById('F12-preset1').addEventListener('click', presetHill);
  document.getElementById('F12-preset2').addEventListener('click', presetLoop);
  document.getElementById('F12-clear').addEventListener('click', clear);
  ['F12-mu','F12-m'].forEach(id => document.getElementById(id).addEventListener('input', () => {
    document.getElementById('F12-muv').textContent = (+document.getElementById('F12-mu').value).toFixed(2);
    document.getElementById('F12-mv').textContent = (+document.getElementById('F12-m').value).toFixed(1);
    if (!ball.running) reset();
  }));

  presetHill();
  B().startLoop('F12', cv, tick);
  return true;
}

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

})();
