import { createAirfield, createInstructor } from './scene.js?v=classroom-20260920'; const $=id=>document.getElementById(id); const marshallingSignals=[ {title:'STAND READY',brief:'Inspect the stand, aircraft path, stop position and equipment restraint area before accepting the aircraft.',detail:'Remove or report FOD and keep equipment outside the movement path. The FAUT stand still requires local validation.',source:'AM Risk 2023 course · ICAO Doc 10121'}, {title:'IDENTIFY GATE',brief:'Face the flight crew, remain clearly visible and identify the gate before giving movement guidance.',detail:'Use approved high-visibility equipment and maintain continuous eye contact.',source:'AM Risk 2023 course · module 7'}, {title:'PROCEED STRAIGHT',brief:'Guide the aircraft along the intended line while maintaining full-aircraft clearance.',detail:'Observe both wingtips, the tail and the nose-wheel track. A correct signal never cancels an obstruction.',source:'AM Risk 2023 controlled signal section'}, {title:'TURN LEFT',brief:'Give the turn from the pilot’s point of view and keep the wingtip and stand hazards in the shared picture.',detail:'Stop the exercise if learner and instructor do not share the same orientation.',source:'AM Risk 2023 controlled signal section'}, {title:'NORMAL STOP',brief:'Bring the planned manoeuvre to a controlled stop with a clear, deliberate signal.',detail:'Continue observing until aircraft movement has ended.',source:'AM Risk 2023 controlled signal section'}, {title:'EMERGENCY STOP',brief:'Use the agreed immediate stop action when any obstruction, uncertainty or loss of visual contact makes movement unsafe.',detail:'Every team member must understand the emergency stop before movement starts.',source:'AM Risk 2023 · ICAO Doc 10121'}, {title:'BRAKES & CHOCKS',brief:'Use the approved brake and chock sequence only after the aircraft reaches the stop position.',detail:'Do not place or remove chocks until the applicable aircraft and local procedure authorises it.',source:'AM Risk practical evaluation · ICAO Doc 10121'}, {title:'SAFE TO APPROACH',brief:'Hold service providers outside the hazard area until the aircraft is confirmed safe to approach.',detail:'A stopped aircraft with active systems or anti-collision lights may still be hazardous.',source:'AM Risk 2023 course · ICAO Doc 10121'} ]; const avopStages=[ {title:'Pre-drive gate',text:'Confirm permit prerequisites, PPE, vehicle condition, radio availability and fitness to operate.',hold:false}, {title:'Apron orientation',text:'Identify the apron, service road, restricted areas and the approved local route. Local route data is still TBC.',hold:true}, {title:'Hold point',text:'Stop before any controlled crossing. Confirm authority and local procedure; never follow another vehicle as implied clearance.',hold:true}, {title:'Aircraft interface',text:'Yield to aircraft, avoid jet blast and prop wash, and park only where the local overlay permits.',hold:true} ]; let airfield=null,instructor=null,course='marshalling',signalIndex=0,avopIndex=0,paused=false,narration=''; const speechOK='speechSynthesis' in window && 'SpeechSynthesisUtterance' in window; function speak(text){narration=text;$('guide-text').textContent=text;if(!speechOK){$('voice-status').textContent='TEXT MODE · DEVICE VOICE UNAVAILABLE';return;}window.speechSynthesis.cancel();const u=new SpeechSynthesisUtterance(text);u.lang='en-GB';u.rate=.93;u.onstart=()=>{$('voice-status').textContent='GUIDE SPEAKING';instructor?.speak(true);};u.onend=()=>{$('voice-status').textContent='YOUR TURN';instructor?.speak(false);};u.onerror=()=>{$('voice-status').textContent='VOICE UNAVAILABLE · READ THE TEXT';instructor?.speak(false);};window.speechSynthesis.speak(u);} function renderMarshalling(){const s=marshallingSignals[signalIndex];$('scene-title').textContent=`Marshalling / ${s.title}`;$('scene-subtitle').textContent=s.brief;return `

AIRCRAFT MARSHALLING · 3D GUIDED

Read the signal. Protect the stand.

Practise the full sequence from stand preparation to safe approach.

SOURCE-MAPPED DRAFT
${s.title}
STEP ${String(signalIndex+1).padStart(2,'0')} / ${marshallingSignals.length}

${s.brief}

${s.detail}

${s.source}
OBSERVEAircraft path, extremities and hazards
COMMUNICATEVisible signals and shared stop action
STOPAny uncertainty pauses movement
`;} function renderAvop(){const s=avopStages[avopIndex];$('scene-title').textContent=`FAUT AVOP / ${s.title}`;$('scene-subtitle').textContent=s.text;return `

FAUT AVOP · 3D GUIDED

Explore the practice route.

Move through the training gates. When a local fact is missing, the correct action is to stop and validate it.

LOCAL OVERLAY PENDING
RFFSGATEHOLDSTAND●
GATE ${String(avopIndex+1).padStart(2,'0')} / ${avopStages.length}

${s.title}

${s.text}

${s.hold?'HOLD: this decision requires the verified airport overlay before it can become a scored local task.':'Preparation gate: use the controlled AVOP core.'}

ROUTEGeneric training path until FAUT map is approved
RADIOVehicle call signs and frequencies remain TBC
ASSESSInstructor uses the controlled AVOP practical
`;} function renderCourse(){ $('course-content').innerHTML=course==='marshalling'?renderMarshalling():renderAvop();bindCourse();} function bindCourse(){if(course==='marshalling'){$('signal-hear').onclick=()=>speak(marshallingSignals[signalIndex].brief);$('signal-next').onclick=()=>{signalIndex=(signalIndex+1)%marshallingSignals.length;airfield?.observe(signalIndex%3);renderCourse();speak(marshallingSignals[signalIndex].brief);};}else{$('avop-next').onclick=()=>{if(avopIndexspeak(avopStages[avopIndex].text);}} document.querySelectorAll('[data-course]').forEach(b=>b.onclick=()=>{course=b.dataset.course;airfield?.setTrainingMode(course);if(course==='avop')airfield?.moveVehicle(avopIndex);document.querySelectorAll('[data-course]').forEach(x=>x.classList.toggle('active',x===b));renderCourse();speak(course==='marshalling'?'Aircraft Marshalling selected. Start with the stop signal and protect the stand.':'FAUT AVOP selected. Start at the pre-drive gate and stop when local data is missing.');}); $('brief-button').onclick=()=>speak(course==='marshalling'?marshallingSignals[signalIndex].brief:avopStages[avopIndex].text);$('replay-button').onclick=()=>speak(narration||'Select a course to begin.');$('motion-button').onclick=()=>{paused=!paused;airfield?.setPaused(paused);instructor?.setPaused(paused);$('motion-button').textContent=paused?'▶ Resume motion':'Ⅱ Pause motion';};document.querySelectorAll('[data-view]').forEach(b=>b.onclick=()=>{airfield?.view(b.dataset.view);document.querySelectorAll('[data-view]').forEach(x=>x.classList.toggle('selected',x===b));}); renderCourse(); try{airfield=createAirfield($('scene'),(pointIndex)=>{if(course==='marshalling'){signalIndex=pointIndex%marshallingSignals.length;renderCourse();}},{fire:false});}catch(e){$('scene-fallback').hidden=false;} try{instructor=createInstructor($('guide'));instructor.setPaused(false);}catch(e){} window.addEventListener('pagehide',()=>window.speechSynthesis?.cancel());