/* quiz.js — Quiz-Builder, Review-Screen, Feedback-Bogen */
/* ══════════════════════════════════════════════
STEP 4 — QUIZ
══════════════════════════════════════════════ */
function isQComplete(q){return q.question.trim()&&q.answers.every(a=>a.trim())&&q.correct!==null;}
function getQ(fi){return ST.quizData.find(q=>q.fieldIndex===fi);}
function buildQuiz(){
const qidx=ST.fields.map((f,i)=>f==='quiz'?i:-1).filter(i=>i>=0);
qidx.forEach(fi=>{if(!ST.quizData.find(q=>q.fieldIndex===fi))ST.quizData.push({fieldIndex:fi,question:'',answers:['','','',''],correct:null});});
ST.quizData=ST.quizData.filter(q=>qidx.includes(q.fieldIndex));
const area=document.getElementById('quizArea');area.innerHTML='';
if(qidx.length===0){
area.innerHTML=`
Beispielfragen
Alle leeren Felder automatisch ausfüllen
${done}/${qidx.length}`;}
}
function mkQCard(q,idx){
// XSS-sicher: fieldIndex wird zu Integer geclampt, Frage/Antworten via esc() (entschärft <,>,&,",')
const comp=isQComplete(q);
const fi = parseInt(q.fieldIndex)|0; // hart casten
const c=document.createElement('div');c.className='card quiz-card'+(comp?' complete':'');c.id='qc_'+fi;
const fl=fi===0?'Start':fi===ST.fieldCount-1?'Ziel':'Feld '+fi;
const ans = LETTERS.map((L,i)=>{
const v = esc(q.answers[i]||'');
return ``;
}).join('');
const corr = LETTERS.map((L,i)=>`${L} `).join('');
c.innerHTML=`
${idx+1}
Quiz-Frage ${idx+1}
${comp?'✓ Fertig':'⏳ Ausfüllen'}
Frage (📍 ${fl})
Die vier Antworten
${ans}
✅ Richtige Antwort:
${corr}
💡 Tipps
• Stelle eine klare, eindeutige Frage • Alle 4 Antworten sollten plausibel klingen • Nur eine Antwort ist korrekt • Beziehe die Frage auf dein Spielthema!
`;
return c;
}
function updQ(fi,field,val){
const q=getQ(fi);if(!q)return;
if(field==='q')q.question=val;
else q.answers[parseInt(field.slice(1))]=val;
refQCard(fi);updQNext();
}
function setCorr(fi,idx){
const q=getQ(fi);if(!q)return;q.correct=idx;
LETTERS.forEach((_,i)=>{const w=document.getElementById(`aw_${fi}_${i}`);if(w)w.className='ans-wrap '+(i===idx?'correct':'');});
const card=document.getElementById('qc_'+fi);if(card)card.querySelectorAll('.correct-btn').forEach((b,i)=>b.classList.toggle('selected',i===idx));
refQCard(fi);updQNext();
}
function refQCard(fi){
const q=getQ(fi);if(!q)return;
const comp=isQComplete(q);
const c=document.getElementById('qc_'+fi);if(!c)return;
c.classList.toggle('complete',comp);
const st=document.getElementById('qst_'+fi);if(st){st.className='qc-status '+(comp?'done':'todo');st.textContent=comp?'✓ Fertig':'⏳ Ausfüllen';}
const num=document.getElementById('qnum_'+fi);if(num)num.style.background=comp?'linear-gradient(135deg,#10b981,#059669)':'linear-gradient(135deg,#7c3aed,#f5a623)';
}
function autoFill(){
ST.quizData.forEach((q,i)=>{if(!isQComplete(q)){const ex=QUIZ_EX[i%QUIZ_EX.length];q.question=ex.q;q.answers=[...ex.a];q.correct=ex.c;}});
buildQuiz();showToast('✅ Beispielfragen eingefügt!');
}
/* ══════════════════════════════════════════════
STEP 5 — REVIEW + TEST
══════════════════════════════════════════════ */
function buildReview(){
const fig=FIGURES.find(f=>f.id===ST.figure)||{e:'🎮',n:'Figur'};
const bg=BACKGROUNDS.find(b=>b.id===ST.background)||{scene:'🌍',n:'Welt'};
const area=document.getElementById('reviewArea');area.innerHTML='';
// Hero card
const hero=document.createElement('div');hero.className='hero-card';
hero.innerHTML=`${esc(bg.scene)}${esc(fig.e)}
${esc(ST.name||'Mein Spiel')}
${esc(ST.desc||'Keine Beschreibung.')}
`;
area.appendChild(hero);
// Rules
const rules=document.createElement('div');rules.className='card';
const filled=ST.fields.slice(1,ST.fieldCount-1).filter(Boolean).length;
rules.innerHTML=`⚙️ Spielregeln
🎲 Bewegung
${ST.rules.movement==='dice'?'🎲 Würfeln':'👣 Ein Feld'}
${ST.rules.fail==='lives'?'❤️ Leben':'⭐ Punkte'}
${ST.rules.fail==='lives'?ST.rules.lives+' Leben':'+'+ST.rules.pts+' Pts'}
🕹️ Mini-Games
${filled} Felder
📖 Erzähltexte
${ST.storyItems.length}
`;
area.appendChild(rules);
// Timeline
const tlCard=document.createElement('div');tlCard.className='card';
tlCard.innerHTML='🗺️ Spielablauf
';
const tl=document.createElement('div');tl.className='tl';
for(let i=0;im.id===g):null;
const isSt=i===0,isEn=i===ST.fieldCount-1;
ST.storyItems.filter(s=>s.position==='before'&&s.fieldIndex===i).forEach(s=>{
const it=document.createElement('div');it.className='tl-item story-it';
it.innerHTML=`${esc(s.emoji||'📖')}
Erzähl-Text
${esc(s.text||'(noch leer)')}
Vor Feld ${i}
`;
tl.appendChild(it);
});
const it=document.createElement('div');it.className='tl-item';
let dCls,lCls,lbl,sub,badge='';
if(isSt){dCls='s';lCls='s';lbl='🟢 Start';sub='Das Abenteuer beginnt!';}
else if(isEn){dCls='e';lCls='e';lbl='🏁 Ziel';sub='Hier gewinnt man!';}
else if(mg){dCls='g';lCls='g';lbl='Feld '+i;sub=mg.n;badge=`${esc(mg.e)} ${esc(mg.n)}
`;}
else{dCls='em';lCls='em';lbl='Feld '+i;sub='Leeres Durchgangsfeld';}
it.innerHTML=`${isSt?'🟢':isEn?'🏁':mg?esc(mg.e):'⬜'}
${esc(lbl)}
${esc(sub)}
${badge}
`;
tl.appendChild(it);
ST.storyItems.filter(s=>s.position==='after'&&s.fieldIndex===i).forEach(s=>{
const it2=document.createElement('div');it2.className='tl-item story-it';
it2.innerHTML=`${esc(s.emoji||'📖')}
Erzähl-Text
${esc(s.text||'(noch leer)')}
Nach Feld ${i}
`;
tl.appendChild(it2);
});
}
tlCard.appendChild(tl);area.appendChild(tlCard);
// Quiz preview
if(ST.quizData.length>0){
const qc=document.createElement('div');qc.className='card';
qc.innerHTML='❓ Quiz-Fragen
';
const ql=document.createElement('div');ql.className='qp-list';
ST.quizData.forEach((q,i)=>{
const qi=document.createElement('div');qi.className='qp-item';
qi.innerHTML=`Frage ${i+1}: ${esc(q.question||'(leer)')}
${LETTERS.map((L,j)=>`
${esc(L)} ${esc(q.answers[j]||'?')}${q.correct===j?' ✓':''}
`).join('')}
`;
ql.appendChild(qi);
});
qc.appendChild(ql);area.appendChild(qc);
}
// Checklist
const cc=document.createElement('div');cc.className='card';cc.innerHTML='🔍 Checkliste
';
const cl=document.createElement('div');cl.className='checklist';
const qDone=ST.quizData.filter(isQComplete).length;
[
{ok:!!ST.name,t:ST.name?`Spielname: "${esc(ST.name)}"`:'Kein Spielname vergeben'},
{ok:!!(ST.figure&&ST.background),t:ST.figure?`Figur & Setting: ${esc(fig.n)} / ${esc(bg.n)}`:'Figur oder Setting fehlt'},
{ok:filled>0,t:`${filled} von ${ST.fieldCount-2} Spielfeldern belegt`},
{ok:ST.quizData.length===0||qDone===ST.quizData.length,t:ST.quizData.length===0?'Keine Quiz-Felder (ok)':`${qDone}/${ST.quizData.length} Quiz-Fragen ausgefüllt`},
].forEach(ch=>{const it=document.createElement('div');it.className='chk-item '+(ch.ok?'ok':'warn');it.innerHTML=`${ch.ok?'✅':'⚠️'} ${ch.t}`;cl.appendChild(it);});
cc.appendChild(cl);area.appendChild(cc);
// Fill launch card
document.getElementById('lhFig').textContent=fig.e;
document.getElementById('lhName').textContent=ST.name||'Mein Spiel';
document.getElementById('lhDesc').textContent=ST.desc||'';
document.getElementById('lhPills').innerHTML=[
`${fig.e} ${fig.n}
`,
`🌍 ${bg.n}
`,
`⬛ ${ST.fieldCount} Felder
`,
`${ST.rules.fail==='lives'?'❤️ '+ST.rules.lives+' Leben':'⭐ Punkte'}
`,
].join('');
const uniqueG=[...new Set(ST.fields.filter(Boolean))];
document.getElementById('launchChk').innerHTML=[
{i:'🎲',t:`${ST.fieldCount} Felder · ${filled} Mini-Games`},
{i:'🕹️',t:`Games: ${uniqueG.map(g=>{const m=MINIGAMES.find(x=>x.id===g);return m?m.e:'❓';}).join(' ')||'—'}`},
{i:'📖',t:`${ST.storyItems.length} Erzähltexte`},
{i:'🎵',t:`Musik-Theme: ${bg.n}`},
].map(x=>`${x.i} ${x.t} ✓
`).join('');
}
let gamePlayed=false;
function doLaunch(){
save();
const w=window.open('game.html','Spiel',`width=${Math.min(1100,screen.width-60)},height=${Math.min(800,screen.height-60)},left=40,top=30,resizable=yes,scrollbars=no`);
if(!w){showToast('⚠️ Popup blockiert! Bitte Popups erlauben.');return;}
document.getElementById('btnLaunch').textContent='⏳ Warte auf Spielende...';
document.getElementById('btnLaunch').disabled=true;
const poll=setInterval(()=>{if(w.closed){clearInterval(poll);onGameDone();}},800);
}
function onGameDone(){
gamePlayed=true;
document.getElementById('btnLaunch').textContent='🔄 Nochmal spielen';
document.getElementById('btnLaunch').disabled=false;
document.getElementById('playedBadge').classList.add('visible');
const fc=document.getElementById('fbCard');fc.style.display='block';
fc.style.animation='slideIn 0.4s ease both';
setTimeout(()=>fc.scrollIntoView({behavior:'smooth',block:'start'}),500);
fbCur=0;fbAnswers={};renderFB();
}
/* ══════════════════════════════════════════════
FEEDBACK
══════════════════════════════════════════════ */
let fbCur=0,fbAnswers={};
function renderFB(){
const q=FB_QS[fbCur];
document.getElementById('fbFill').style.width=(fbCur/FB_QS.length*100)+'%';
document.getElementById('fbPrev').style.display=fbCur>0?'':'none';
document.getElementById('fbNext').textContent=fbCurFrage ${fbCur+1} von ${FB_QS.length}${q.q}
${q.sub?`${q.sub}
`:''}`;
if(q.t==='mc'){
const opts=document.createElement('div');opts.className='mc-opts';
q.opts.forEach((o,i)=>{const btn=document.createElement('div');btn.className='mc-opt'+(fbAnswers[q.id]===i?' sel':'');btn.innerHTML=`
${o}`;btn.addEventListener('click',()=>{fbAnswers[q.id]=i;opts.querySelectorAll('.mc-opt').forEach(b=>b.classList.remove('sel'));btn.classList.add('sel');document.getElementById('fbNext').disabled=false;});opts.appendChild(btn);});
area.appendChild(opts);
}
if(q.t==='scale'){
const row=document.createElement('div');row.className='scale-row';
for(let i=1;i<=5;i++){const btn=document.createElement('button');btn.className='scale-btn'+(fbAnswers[q.id]===i?' sel':'');btn.textContent=i;btn.addEventListener('click',()=>{fbAnswers[q.id]=i;row.querySelectorAll('.scale-btn').forEach(b=>b.classList.remove('sel'));btn.classList.add('sel');document.getElementById('fbNext').disabled=false;});row.appendChild(btn);}
area.appendChild(row);
const lbl=document.createElement('div');lbl.className='scale-lbls';lbl.innerHTML=`${q.min} ${q.max} `;area.appendChild(lbl);
}
if(q.t==='text'){
const ta=document.createElement('textarea');ta.className='fb-ta';ta.rows=3;ta.placeholder=q.ph||'';ta.value=fbAnswers[q.id]||'';ta.addEventListener('input',()=>{fbAnswers[q.id]=ta.value;document.getElementById('fbNext').disabled=ta.value.trim().length<3;});area.appendChild(ta);
}
document.getElementById('fbNext').disabled=fbAnswers[q.id]===undefined;
}
function fbFwd(){
fbCur++;
if(fbCur>=FB_QS.length){showSummaryCard();return;}
renderFB();
}
function fbBack(){if(fbCur>0){fbCur--;renderFB();}}