// F7. Лифт с динамометром (§24 в ch2) — переживание перегрузки и невесомости.
(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>Масса груза $m$, кг: <b id="F7-mv">1.0</b><input type="range" id="F7-m" min="0.1" max="10" step="0.1" value="1"></label>'
      + '<label>$a$ разгона, м/с²: <b id="F7-av">3</b><input type="range" id="F7-a" min="0.5" max="9.8" step="0.5" value="3"></label>'
    + '</div>'
    + '<canvas id="F7-cv" class="flag-canvas" width="640" height="460" style="height:460px"></canvas>'
    + '<div class="flag-controls">'
      + '<button class="flag-btn primary" id="F7-up">Разгон ⬆</button>'
      + '<button class="flag-btn primary" id="F7-dn">Разгон ⬇</button>'
      + '<button class="flag-btn" id="F7-stop">Стоп (a=0)</button>'
      + '<button class="flag-btn danger" id="F7-fall">Свободное падение!</button>'
      + '<button class="flag-btn" id="F7-reset">Сброс</button>'
    + '</div>'
    + '<div class="flag-stats">'
      + '<div class="flag-stat"><span class="lbl">Вес динамометра</span><span class="val" id="F7-P">9.8 Н</span></div>'
      + '<div class="flag-stat"><span class="lbl">Отношение P/mg</span><span class="val" id="F7-pmg">1.0 g</span></div>'
      + '<div class="flag-stat"><span class="lbl">$v$ лифта</span><span class="val" id="F7-v">0 м/с</span></div>'
      + '<div class="flag-stat"><span class="lbl">$h$ высота</span><span class="val" id="F7-h">0 м</span></div>'
    + '</div>'
    + '<div class="flag-feedback" id="F7-fb"></div>';

  const card = B().makeCard(secId,
    'F7. Лифт с динамометром',
    'Управляй лифтом — наблюдай, как меняется показание динамометра. $P = m(g + a)$. При $a = -g$ — невесомость.',
    body);
  if (!card) return false;

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

  let st = { y: 0, v: 0, a: 0, t: 0, mode: 'idle' };

  function readSliders(){
    document.getElementById('F7-mv').textContent = (+document.getElementById('F7-m').value).toFixed(2);
    document.getElementById('F7-av').textContent = (+document.getElementById('F7-a').value).toFixed(1);
  }

  function reset(){
    st = { y: 0, v: 0, a: 0, t: 0, mode: 'idle' };
    document.getElementById('F7-fb').className = 'flag-feedback';
    draw();
  }

  function tick(dt){
    const m = +document.getElementById('F7-m').value;
    const a_in = +document.getElementById('F7-a').value;
    const g = 9.8;
    /* Управление режимом */
    if (st.mode === 'up') st.a = a_in;
    else if (st.mode === 'dn') st.a = -a_in;
    else if (st.mode === 'stop') st.a = 0;
    else if (st.mode === 'fall') st.a = -g;
    else st.a = 0;
    st.v += st.a * dt;
    st.y += st.v * dt;
    /* ограничения */
    if (st.y < 0){ st.y = 0; if (st.v < 0) st.v = 0; }
    if (st.y > 50){ st.y = 50; if (st.v > 0) st.v = 0; }
    st.t += dt;
    /* Вес */
    const P = m * (g + st.a);
    const ratio = P/(m*g);
    document.getElementById('F7-P').textContent = P.toFixed(2) + ' Н';
    document.getElementById('F7-pmg').textContent = ratio.toFixed(2) + ' g';
    document.getElementById('F7-v').textContent = st.v.toFixed(2) + ' м/с';
    document.getElementById('F7-h').textContent = st.y.toFixed(1) + ' м';
    const fb = document.getElementById('F7-fb');
    if (Math.abs(P) < m*g*0.05){
      fb.className = 'flag-feedback warn show';
      fb.innerHTML = '&#9888; НЕВЕСОМОСТЬ! Динамометр показывает почти 0.';
    } else if (P < 0){
      fb.className = 'flag-feedback fail show';
      fb.innerHTML = 'P < 0: предмет «отрывается» от пола (или сильно прижимается к потолку).';
    } else if (ratio > 1.5){
      fb.className = 'flag-feedback warn show';
      fb.innerHTML = 'ПЕРЕГРУЗКА '+ratio.toFixed(1)+'g — космонавты тренируются на таких.';
    } else if (Math.abs(ratio - 1) < 0.05){
      fb.className = 'flag-feedback ok show';
      fb.innerHTML = 'Нормальный вес — $a = 0$ или равномерное движение.';
    } else {
      fb.className = 'flag-feedback';
    }
    draw();
  }

  function draw(){
    const col = C();
    ctx.fillStyle = col.bg || '#fafafa';
    ctx.fillRect(0, 0, W, H);
    /* Шахта */
    const shaftX = 80, shaftY = 30, shaftW = 280, shaftH = H - 60;
    ctx.fillStyle = col.bgSubtle || '#f8fafc';
    ctx.fillRect(shaftX, shaftY, shaftW, shaftH);
    ctx.strokeStyle = col.axis || '#1e293b';
    ctx.lineWidth = 2;
    ctx.strokeRect(shaftX, shaftY, shaftW, shaftH);
    /* Этажи */
    ctx.strokeStyle = col.grid || '#e5e7eb';
    ctx.lineWidth = 1;
    for (let i = 0; i <= 5; i++){
      const py = shaftY + (i/5) * shaftH;
      ctx.beginPath(); ctx.moveTo(shaftX, py); ctx.lineTo(shaftX + shaftW, py); ctx.stroke();
      ctx.fillStyle = col.textMuted || '#64748b';
      ctx.font = '11px Inter,sans-serif';
      ctx.fillText((5-i)+' эт', shaftX + 6, py + 12);
    }
    /* Лифт (кабина) */
    const yNorm = st.y / 50;  /* 0..1 */
    const liftY = shaftY + shaftH - 100 - yNorm * (shaftH - 120);
    ctx.fillStyle = col.bodyLight || '#cbd5e1';
    ctx.fillRect(shaftX + 50, liftY, shaftW - 100, 90);
    ctx.strokeStyle = col.bodyAccent || '#1e293b';
    ctx.lineWidth = 2;
    ctx.strokeRect(shaftX + 50, liftY, shaftW - 100, 90);
    /* Трос */
    ctx.strokeStyle = st.mode === 'fall' ? col.fail : col.axis || '#1e293b';
    ctx.lineWidth = st.mode === 'fall' ? 1 : 2.5;
    if (st.mode === 'fall'){
      ctx.setLineDash([4, 4]);
    }
    ctx.beginPath();
    ctx.moveTo(shaftX + shaftW/2, shaftY);
    ctx.lineTo(shaftX + shaftW/2, liftY);
    ctx.stroke();
    ctx.setLineDash([]);
    /* Динамометр внутри лифта */
    const dynaX = shaftX + shaftW/2, dynaY = liftY + 20;
    ctx.strokeStyle = col.axis || '#1e293b';
    ctx.lineWidth = 1.5;
    ctx.fillStyle = col.bg || '#fafafa';
    ctx.fillRect(dynaX - 12, dynaY, 24, 22);
    ctx.strokeRect(dynaX - 12, dynaY, 24, 22);
    /* стрелка */
    const m = +document.getElementById('F7-m').value;
    const g = 9.8;
    const P = m*(g + st.a);
    const Pmax = m*g*2.5;
    const norm = Math.max(0, Math.min(1, P/Pmax));
    const angle = -Math.PI*0.75 + norm * Math.PI*1.5;
    ctx.strokeStyle = col.fail || '#dc2626';
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.moveTo(dynaX, dynaY + 11);
    ctx.lineTo(dynaX + 9*Math.cos(angle), dynaY + 11 + 9*Math.sin(angle));
    ctx.stroke();
    /* Груз ниже динамометра */
    ctx.fillStyle = col.forceGravity || '#2563eb';
    const gSize = Math.min(30, 10 + m*3);
    ctx.fillRect(dynaX - gSize/2, dynaY + 30, gSize, gSize);
    ctx.strokeStyle = col.bodyAccent || '#1e293b';
    ctx.strokeRect(dynaX - gSize/2, dynaY + 30, gSize, gSize);
    ctx.fillStyle = '#fff';
    ctx.font = 'bold 10px Inter,sans-serif';
    ctx.textAlign = 'center';
    ctx.fillText(m.toFixed(1)+' кг', dynaX, dynaY + 30 + gSize/2 + 3);
    ctx.textAlign = 'left';
    /* подпись режима */
    ctx.fillStyle = col.text || '#0f172a';
    ctx.font = 'bold 13px Inter,sans-serif';
    const modeText = { idle: '— пауза —', up: '↑ РАЗГОН ВВЕРХ', dn: '↓ РАЗГОН ВНИЗ', stop: '— равномерно/стоит', fall: 'СВОБОДНОЕ ПАДЕНИЕ' }[st.mode];
    ctx.fillText(modeText, shaftX + shaftW + 20, 60);
    /* большой циферблат справа */
    const dialX = shaftX + shaftW + 130, dialY = 200, dialR = 70;
    ctx.fillStyle = col.bg || '#fafafa';
    ctx.beginPath(); ctx.arc(dialX, dialY, dialR, 0, Math.PI*2); ctx.fill();
    ctx.strokeStyle = col.axis || '#1e293b';
    ctx.lineWidth = 3;
    ctx.stroke();
    /* шкала 0..2.5 g */
    ctx.lineWidth = 2;
    for (let i = 0; i <= 10; i++){
      const a = Math.PI*0.75 + (i/10) * Math.PI*1.5;
      const r1 = dialR - 12, r2 = dialR;
      ctx.strokeStyle = col.axis || '#1e293b';
      ctx.beginPath();
      ctx.moveTo(dialX + r1*Math.cos(a), dialY + r1*Math.sin(a));
      ctx.lineTo(dialX + r2*Math.cos(a), dialY + r2*Math.sin(a));
      ctx.stroke();
      ctx.fillStyle = col.textMuted || '#64748b';
      ctx.font = '10px Inter,sans-serif';
      const lbl = (i*0.25).toFixed(1);
      const lblR = dialR - 25;
      ctx.fillText(lbl, dialX + lblR*Math.cos(a) - 8, dialY + lblR*Math.sin(a) + 4);
    }
    /* стрелка на большом */
    const normBig = Math.max(0, Math.min(1, P/(m*g*2.5)));
    const aBig = Math.PI*0.75 + normBig * Math.PI*1.5;
    ctx.strokeStyle = col.fail || '#dc2626';
    ctx.lineWidth = 4;
    ctx.lineCap = 'round';
    ctx.beginPath();
    ctx.moveTo(dialX, dialY);
    ctx.lineTo(dialX + (dialR-15)*Math.cos(aBig), dialY + (dialR-15)*Math.sin(aBig));
    ctx.stroke();
    ctx.fillStyle = col.fail || '#dc2626';
    ctx.beginPath(); ctx.arc(dialX, dialY, 5, 0, Math.PI*2); ctx.fill();
    /* подпись */
    ctx.fillStyle = col.text || '#0f172a';
    ctx.textAlign = 'center';
    ctx.font = 'bold 14px Inter,sans-serif';
    ctx.fillText(P.toFixed(1) + ' Н', dialX, dialY + dialR + 22);
    ctx.font = '11px Inter,sans-serif';
    ctx.fillText('(' + (P/(m*g)).toFixed(2) + ' g)', dialX, dialY + dialR + 38);
    ctx.textAlign = 'left';
  }

  document.getElementById('F7-up').addEventListener('mousedown', ()=>{ st.mode = 'up'; });
  document.getElementById('F7-up').addEventListener('mouseup', ()=>{ st.mode = 'stop'; });
  document.getElementById('F7-dn').addEventListener('mousedown', ()=>{ st.mode = 'dn'; });
  document.getElementById('F7-dn').addEventListener('mouseup', ()=>{ st.mode = 'stop'; });
  document.getElementById('F7-stop').addEventListener('click', ()=>{ st.mode = 'stop'; });
  document.getElementById('F7-fall').addEventListener('click', ()=>{ st.mode = 'fall'; });
  document.getElementById('F7-reset').addEventListener('click', reset);
  ['F7-m','F7-a'].forEach(id => document.getElementById(id).addEventListener('input', readSliders));

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

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

})();
