// Interface for the two engineering questions. No plant-specific operating data implied.
export function setupEngineering({getLanguage,onThermal,onVibration,onForced,onChange,getExcitation,setExcitation,getResult,getNodeCount}){
const zh=()=>getLanguage()==='zh',el=id=>document.getElementById(id);
const bar=document.createElement('div');bar.className='engineering-tabs';bar.innerHTML='';document.querySelector('main').before(bar);
const panel=document.createElement('details');panel.id='forced-tools';panel.innerHTML='
';
document.getElementById('dynamic-tools').before(panel);
const thermal=document.createElement('div');thermal.id='thermal-insight';thermal.className='thermal-insight';document.getElementById('viewport').append(thermal);
function setTask(vibration){bar.querySelectorAll('button').forEach((b,i)=>b.classList.toggle('active',i===Number(vibration)));panel.open=vibration;el('dynamic-tools').open=vibration;}
el('thermal-task').onclick=()=>{setTask(false);onThermal();};el('vibration-task').onclick=()=>{setTask(true);onVibration();};el('forced-run').onclick=()=>{if(commit())onForced();};
function commit(){const p={node:+el('force-node').value,axis:+el('force-axis').value,force:+el('force-value').value,frequency:+el('force-frequency').value,zeta:+el('force-zeta').value/100};if(!(p.force>=1&&p.force<=10000&&p.frequency>=.1&&p.frequency<=2000&&p.zeta>=.001&&p.zeta<=.1)){sync();return false;}if(JSON.stringify(p)!==JSON.stringify(getExcitation()))setExcitation(p);return true;}
// Commit on the explicit solve button: avoid replacing a partially typed number.
function sync(){const p=getExcitation(),n=getNodeCount();el('force-node').replaceChildren(...Array.from({length:n},(_,i)=>new Option((zh()?'连接点 ':'Joint ')+(i+1),i+1)));el('force-node').value=p.node;el('force-axis').value=p.axis;el('force-value').value=p.force;el('force-frequency').value=p.frequency;el('force-zeta').value=+(p.zeta*100).toFixed(3);
const labels=zh()?{'thermal-task':'热位移与支吊架','vibration-task':'振动与减振','scope-note':'四大管道研究 · 通用组件示例','forced-label':'受迫振动 / 周期力','forced-hint':'指定振源,比较同一测点加装阻尼器前后的响应。','force-node-label':'施力与测量位置','force-axis-label':'力与测量方向','force-label':'力幅值 / N','force-frequency-label':'激励频率 / Hz','zeta-label':'假设模态阻尼比 / %','forced-run':'计算振幅与扫频'}:{'thermal-task':'Thermal movement & supports','vibration-task':'Vibration & mitigation','scope-note':'Power piping research · generic component example','forced-label':'FORCED VIBRATION / HARMONIC FORCE','forced-hint':'Specify the excitation. Compare the same measurement with and without the added damper.','force-node-label':'Force & probe joint','force-axis-label':'Force & probe direction','force-label':'Force amplitude / N','force-frequency-label':'Excitation / Hz','zeta-label':'Assumed modal damping / %','forced-run':'Compute response & sweep'};
for(const [id,text] of Object.entries(labels))el(id).textContent=text;}
return {sync,thermal(view){thermal.hidden=view!=='static';const r=getResult();if(!r)return;const u=r.q.slice(0,3),F=r.supportForces[0],M=r.reaction.slice(3,6);thermal.textContent=zh()?`入口接口载荷 ${Math.hypot(...F)/1000<.01?'0.00':(Math.hypot(...F)/1000).toFixed(2)} kN · ${ (Math.hypot(...M)/1000).toFixed(2)} kN·m|入口固定,非设备允许载荷`:`Inlet reaction ${(Math.hypot(...F)/1000).toFixed(2)} kN · ${(Math.hypot(...M)/1000).toFixed(2)} kN·m | Fixed inlet, not an allowable load`;}};
}