// F10. Виртуальный аквариум (§29 в ch3) — Архимед, плавание тел.
(function(){
'use strict';
const B = () => window.PHYS9_FLAG_BASE;
const C = () => window.PHYS9_COLORS || {};

const MATERIALS = [
  { id:'wood',    name:'дерево',     rho:600,   col:'#a16207' },
  { id:'foam',    name:'пенопласт',  rho:50,    col:'#fef3c7' },
  { id:'plastic', name:'пластик',    rho:950,   col:'#06b6d4' },
  { id:'ice',     name:'лёд',        rho:917,   col:'#bfdbfe' },
  { id:'al',      name:'алюминий',   rho:2700,  col:'#94a3b8' },
  { id:'iron',    name:'железо',     rho:7800,  col:'#475569' },
  { id:'gold',    name:'золото',     rho:19300, col:'#fbbf24' }
];

const LIQUIDS = {
  water:   { rho:1000,  name:'вода',    col:'rgba(96,165,250,0.5)' },
  oil:     { rho:800,   name:'масло',   col:'rgba(217,119,6,0.4)' },
  mercury: { rho:13600, name:'ртуть',   col:'rgba(229,231,235,0.7)' }
};

function init(secId){
  if (!B()) return false;
  let buttons = '';
  MATERIALS.forEach(m => {
    buttons += '<button class="flag-btn" data-mat="'+m.id+'" style="background:'+m.col+';color:'+(m.rho>5000?'#fff':'#0f172a')+';font-size:.78rem;padding:6px 10px">'+m.name+' (ρ='+m.rho+')</button>';
  });
  const body = ''
    + '<div style="margin-bottom:10px;font-size:.85rem;color:var(--muted)">Жидкость:</div>'
    + '<div class="flag-controls" style="margin-bottom:6px">'
      + '<button class="flag-btn primary" data-liq="water">Вода (1000)</button>'
      + '<button class="flag-btn" data-liq="oil">Масло (800)</button>'
      + '<button class="flag-btn" data-liq="mercury">Ртуть (13600)</button>'
    + '</div>'
    + '<div style="margin-bottom:10px;font-size:.85rem;color:var(--muted)">Кликни по телу, чтобы бросить его в аквариум:</div>'
    + '<div class="flag-controls">'+buttons+'</div>'
    + '<canvas id="F10-cv" class="flag-canvas" width="640" height="380" style="height:380px"></canvas>'
    + '<div class="flag-controls">'
      + '<button class="flag-btn danger" id="F10-clear">Очистить</button>'
    + '</div>'
    + '<div class="flag-feedback" id="F10-fb"></div>';

  const card = B().makeCard(secId,
    'F10. Виртуальный аквариум',
    'Выбери жидкость и бросай тела. Тело $\\rho_T < \\rho_Ж$ — плавает. Равны — висит. Тяжелее — тонет. Попробуй золото в ртути!',
    body);
  if (!card) return false;

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

  let bodies = [];  /* { x, y, vy, mat, size, settled } */
  let liquid = 'water';

  function addBody(matId){
    const mat = MATERIALS.find(m => m.id === matId);
    if (!mat) return;
    const size = 22 + Math.random()*10;
    bodies.push({ x: 60 + Math.random()*(W - 120), y: 30, vy: 0, mat: mat, size: size, settled: false });
  }

  function clear(){ bodies = []; }

  function tick(dt){
    const liq = LIQUIDS[liquid];
    bodies.forEach(b => {
      if (b.settled) return;
      const g = 9.8;
      const inLiquid = b.y > liqTop;
      const submerged = Math.min(1, Math.max(0, (b.y - liqTop + b.size/2) / b.size));
      /* Сила тяжести вниз: m*g, m = ρ_T * V (V в условных единицах ∝ size^2) */
      const V = (b.size * b.size) / 1000;
      const Fg = b.mat.rho * V * g;
      const Fa = liq.rho * V * g * submerged;
      const Fnet = Fg - Fa;
      /* a = Fnet / m, m = ρ_T * V */
      const a = Fnet / (b.mat.rho * V);
      b.vy += a * dt * 30;  /* px/m scale */
      /* демпфирование в жидкости */
      if (inLiquid) b.vy *= 0.96;
      b.y += b.vy * dt;
      /* дно */
      if (b.y > H - b.size/2){ b.y = H - b.size/2; b.vy = 0; }
      /* потолок жидкости — для плавающих */
      if (b.y < liqTop && b.vy < 0){
        b.y = liqTop;
        b.vy = 0;
      }
      /* «осёл» — если скорость мала и в равновесии, settling */
      if (Math.abs(b.vy) < 0.05 && Math.abs(a) < 0.1){
        b.settled = true;
      }
    });
    draw();
  }

  function draw(){
    const col = C();
    /* небо */
    ctx.fillStyle = col.gas || '#dbeafe';
    ctx.fillRect(0, 0, W, liqTop);
    /* жидкость */
    const liq = LIQUIDS[liquid];
    ctx.fillStyle = liq.col;
    ctx.fillRect(0, liqTop, W, H - liqTop);
    /* поверхность воды */
    ctx.strokeStyle = col.liquid || '#3b82f6';
    ctx.lineWidth = 2;
    ctx.beginPath(); ctx.moveTo(0, liqTop); ctx.lineTo(W, liqTop); ctx.stroke();
    /* стенки аквариума */
    ctx.strokeStyle = col.axis || '#1e293b';
    ctx.lineWidth = 3;
    ctx.beginPath();
    ctx.moveTo(0, liqTop - 5); ctx.lineTo(0, H);
    ctx.moveTo(W, liqTop - 5); ctx.lineTo(W, H);
    ctx.moveTo(0, H); ctx.lineTo(W, H);
    ctx.stroke();
    /* подпись жидкости */
    ctx.fillStyle = col.text || '#0f172a';
    ctx.font = 'bold 13px Inter,sans-serif';
    ctx.fillText(liq.name + ' (ρ = ' + liq.rho + ' кг/м³)', 12, 24);
    /* тела */
    bodies.forEach(b => {
      ctx.fillStyle = b.mat.col;
      ctx.fillRect(b.x - b.size/2, b.y - b.size/2, b.size, b.size);
      ctx.strokeStyle = col.bodyAccent || '#1e293b';
      ctx.lineWidth = 1.5;
      ctx.strokeRect(b.x - b.size/2, b.y - b.size/2, b.size, b.size);
      ctx.fillStyle = b.mat.rho > 5000 ? '#fff' : '#0f172a';
      ctx.font = '10px Inter,sans-serif';
      ctx.textAlign = 'center';
      ctx.fillText(b.mat.rho, b.x, b.y + 3);
      ctx.textAlign = 'left';
    });
    /* feedback */
    if (bodies.length > 0){
      const last = bodies[bodies.length-1];
      if (last.settled){
        const fb = document.getElementById('F10-fb');
        const liqRho = LIQUIDS[liquid].rho;
        if (last.mat.rho < liqRho){
          fb.className = 'flag-feedback ok show';
          fb.innerHTML = '&#10003; '+last.mat.name+' ('+last.mat.rho+') ПЛАВАЕТ в '+liq.name+' ('+liqRho+'): $\\rho_T < \\rho_Ж$.';
        } else if (last.mat.rho > liqRho){
          fb.className = 'flag-feedback warn show';
          fb.innerHTML = last.mat.name+' ('+last.mat.rho+') ТОНЕТ в '+liq.name+' ('+liqRho+'): $\\rho_T > \\rho_Ж$.';
        } else {
          fb.className = 'flag-feedback ok show';
          fb.innerHTML = last.mat.name+' ВИСИТ в толще: $\\rho_T = \\rho_Ж$.';
        }
        try { if(window.renderMathInElement) window.renderMathInElement(fb, { delimiters:[{left:'$',right:'$',display:false}], throwOnError:false }); } catch(e){}
      }
    }
  }

  /* binding */
  card.querySelectorAll('[data-mat]').forEach(btn => {
    btn.addEventListener('click', () => addBody(btn.dataset.mat));
  });
  card.querySelectorAll('[data-liq]').forEach(btn => {
    btn.addEventListener('click', () => {
      liquid = btn.dataset.liq;
      card.querySelectorAll('[data-liq]').forEach(b => b.classList.remove('primary'));
      btn.classList.add('primary');
      /* «разбудить» все тела */
      bodies.forEach(b => b.settled = false);
    });
  });
  document.getElementById('F10-clear').addEventListener('click', clear);

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

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

})();
