import sys, os

src = os.path.join(os.path.dirname(__file__), '../../frontend/js/labs/opticsbench.js')

with open(src, 'r', encoding='utf-8') as f:
    content = f.read()

# ─────────────────────────────────────────────────────────────────────────────
# PATCH: Insert new glue functions after lensPreset, before _lensUpdateUI
# ─────────────────────────────────────────────────────────────────────────────

MARKER = 'function _lensUpdateUI(info) {'

idx = content.find(MARKER)
if idx == -1:
    print('ERROR: _lensUpdateUI not found'); sys.exit(1)

NEW_FUNCS = (
    '/* ── Lens animated ray + LM controls (Feature 1 & 3) ── */\n'
    'function lensToggleLM(on) {\n'
    '  const sliders = document.getElementById(\'ob-lm-sliders\');\n'
    '  const fRow    = document.querySelector(\'#ob-ctrl-lens .proj-slider-row\');\n'
    '  if (sliders) sliders.style.display = on ? \'\' : \'none\';\n'
    '  // hide/show simple f slider\n'
    '  const fSlRow = document.getElementById(\'sl-lens-f\');\n'
    '  if (fSlRow && fSlRow.parentElement) fSlRow.parentElement.style.display = on ? \'none\' : \'\';\n'
    '  if (lensSim) lensSim.setLensMode(!on);\n'
    '  if (on && lensSim) {\n'
    '    // sync sliders to current LM params\n'
    '    const r1 = lensSim._lmR1, r2 = lensSim._lmR2, n = lensSim._lmN;\n'
    '    const s1 = document.getElementById(\'sl-lm-r1\'), l1 = document.getElementById(\'lm-r1-val\');\n'
    '    const s2 = document.getElementById(\'sl-lm-r2\'), l2 = document.getElementById(\'lm-r2-val\');\n'
    '    const sn = document.getElementById(\'sl-lm-n\'),  ln = document.getElementById(\'lm-n-val\');\n'
    '    if (s1) s1.value = r1; if (l1) l1.textContent = r1.toFixed(0);\n'
    '    if (s2) s2.value = r2; if (l2) l2.textContent = r2.toFixed(0);\n'
    '    if (sn) sn.value = n;  if (ln) ln.textContent = n.toFixed(2);\n'
    '  }\n'
    '}\n'
    '\n'
    'function lensLMParam(name, val) {\n'
    '  const v = parseFloat(val);\n'
    '  const lblMap = { R1: \'lm-r1-val\', R2: \'lm-r2-val\', n: \'lm-n-val\' };\n'
    '  const el = document.getElementById(lblMap[name]);\n'
    '  if (el) el.textContent = name === \'n\' ? v.toFixed(2) : v.toFixed(0);\n'
    '  if (lensSim) {\n'
    '    lensSim.setLMParam(name, v);\n'
    '    // update f display\n'
    '    const fl = document.getElementById(\'lens-f-val\');\n'
    '    if (fl) fl.textContent = lensSim.f.toFixed(0);\n'
    '  }\n'
    '}\n'
    '\n'
    '/* ── Mirror R-slider + parabolic controls (Feature 2) ── */\n'
    'function mirrorToggleR(on) {\n'
    '  const rRow = document.getElementById(\'ob-mirror-R-row\');\n'
    '  if (rRow) rRow.style.display = on ? \'\' : \'none\';\n'
    '  const pbtn = document.getElementById(\'mirror-parab-btn\');\n'
    '  if (pbtn) pbtn.style.display = on ? \'\' : \'none\';\n'
    '  if (mirrorSim) mirrorSim._useR = !!on;\n'
    '  if (on && mirrorSim) {\n'
    '    const sv = document.getElementById(\'sl-mirror-R\');\n'
    '    const lv = document.getElementById(\'mirror-R-val\');\n'
    '    if (sv) sv.value = mirrorSim._R;\n'
    '    if (lv) lv.textContent = mirrorSim._R;\n'
    '    mirrorSim.setMirrorR(mirrorSim._R);\n'
    '  } else if (mirrorSim) { mirrorSim.draw(); }\n'
    '}\n'
    '\n'
    'function mirrorRParam(val) {\n'
    '  const v = parseFloat(val);\n'
    '  const el = document.getElementById(\'mirror-R-val\');\n'
    '  if (el) el.textContent = v;\n'
    '  if (mirrorSim) mirrorSim.setMirrorR(v);\n'
    '}\n'
    '\n'
    'function mirrorToggleParabolic(btn) {\n'
    '  if (!mirrorSim) return;\n'
    '  mirrorSim._parabolic = !mirrorSim._parabolic;\n'
    '  if (btn) btn.textContent = mirrorSim._parabolic ? \'Параболическое\' : \'Сферическое\';\n'
    '  if (btn) btn.style.color = mirrorSim._parabolic ? \'#7BF5A4\' : \'#888\';\n'
    '  mirrorSim.draw();\n'
    '}\n'
    '\n'
)

new_content = content[:idx] + NEW_FUNCS + content[idx:]

with open(src, 'w', encoding='utf-8') as f:
    f.write(new_content)

print('OK lines:', new_content.count('\n'))
