`).join('');
}
/**
* Handles adding a new word from the form
*/
function addBvbWord(e) {
e.preventDefault();
const word = bvbNewWord.value.trim();
const definition = bvbNewDefinition.value.trim();
const sentence = bvbNewSentence.value.trim();
if (word && definition) {
bvbWordList.push({ word, definition, sentence });
bvbNewWord.value = '';
bvbNewDefinition.value = '';
bvbNewSentence.value = '';
renderAllBvbContent();
}
}
/**
* Handles deleting a word
*/
function deleteBvbWord(index) {
bvbWordList.splice(index, 1);
renderAllBvbContent();
}
// --- 4. FLASHCARD FUNCTIONS (Tab 2) ---
function resetBvbFlashcard() {
bvbFlashcardStartScreen.style.display = 'block';
bvbFlashcardActiveScreen.style.display = 'none';
bvbFlashcardStartBtn.disabled = bvbWordList.length === 0;
}
function startBvbFlashcards() {
if (bvbWordList.length === 0) return;
bvbFlashcardStartScreen.style.display = 'none';
bvbFlashcardActiveScreen.style.display = 'block';
bvbFlashcardIndex = 0;
showBvbFlashcard(bvbFlashcardIndex);
}
function showBvbFlashcard(index) {
const item = bvbWordList[index];
bvbFlashcardWord.textContent = item.word;
bvbFlashcardDefinition.textContent = item.definition;
bvbFlashcardSentence.textContent = item.sentence || '';
bvbFlashcardAnswer.style.display = 'none'; // Hide answer
bvbFlashcardFlipBtn.textContent = 'Flip Card';
}
function flipBvbCard() {
const isHidden = bvbFlashcardAnswer.style.display === 'none';
bvbFlashcardAnswer.style.display = isHidden ? 'block' : 'none';
bvbFlashcardFlipBtn.textContent = isHidden ? 'Hide Answer' : 'Flip Card';
}
function nextBvbFlashcard() {
bvbFlashcardIndex = (bvbFlashcardIndex + 1) % bvbWordList.length;
showBvbFlashcard(bvbFlashcardIndex);
}
// --- 5. QUIZ FUNCTIONS (Tab 3) ---
function resetBvbQuiz() {
bvbQuizStartScreen.style.display = 'block';
bvbQuizActiveScreen.style.display = 'none';
bvbQuizResultsScreen.style.display = 'none';
bvbQuizStartBtn.disabled = bvbWordList.length === 0;
}
function startBvbQuiz() {
if (bvbWordList.length === 0) return;
// Create a shuffled quiz list
const shuffledList = [...bvbWordList].sort(() => 0.5 - Math.random());
bvbQuizState = {
questions: shuffledList,
currentQuestionIndex: 0,
score: 0
};
bvbQuizStartScreen.style.display = 'none';
bvbQuizActiveScreen.style.display = 'block';
bvbQuizResultsScreen.style.display = 'none';
bvbQuizFeedback.innerHTML = '';
bvbQuizAnswer.value = '';
showBvbQuizQuestion();
}
function showBvbQuizQuestion() {
if (bvbQuizState.currentQuestionIndex >= bvbQuizState.questions.length) {
showBvbQuizResults();
return;
}
const question = bvbQuizState.questions[bvbQuizState.currentQuestionIndex];
bvbQuizProgress.textContent = `Question ${bvbQuizState.currentQuestionIndex + 1} of ${bvbQuizState.questions.length}`;
bvbQuizQuestion.textContent = `What is the definition of: "${question.word}"?`;
bvbQuizAnswer.value = '';
bvbQuizFeedback.innerHTML = '';
bvbQuizSubmitBtn.textContent = 'Submit Answer';
bvbQuizSubmitBtn.onclick = checkBvbAnswer; // Assign click handler
}
function checkBvbAnswer() {
const userAnswer = bvbQuizAnswer.value.trim().toLowerCase();
const correctAnswer = bvbQuizState.questions[bvbQuizState.currentQuestionIndex].definition.trim().toLowerCase();
if (userAnswer === correctAnswer) {
bvbQuizFeedback.textContent = "Correct!";
bvbQuizFeedback.className = 'bvb-feedback-correct';
bvbQuizState.score++;
} else {
bvbQuizFeedback.textContent = `Incorrect. The correct answer is: "${bvbQuizState.questions[bvbQuizState.currentQuestionIndex].definition}"`;
bvbQuizFeedback.className = 'bvb-feedback-incorrect';
}
bvbQuizState.currentQuestionIndex++;
bvbQuizSubmitBtn.textContent = 'Next Question';
bvbQuizSubmitBtn.onclick = showBvbQuizQuestion; // Re-assign click for next
}
function showBvbQuizResults() {
bvbQuizActiveScreen.style.display = 'none';
bvbQuizResultsScreen.style.display = 'block';
bvbQuizResultsSummary.textContent = `You scored ${bvbQuizState.score} out of ${bvbQuizState.questions.length}!`;
}
// --- 6. PDF DOWNLOAD FUNCTION (Spec C, 9) ---
async function downloadBvbPdf() {
if (typeof jspdf === 'undefined' || typeof html2canvas === 'undefined') {
alert('PDF libraries are still loading. Please try again in a moment.');
return;
}
const { jsPDF } = jspdf;
const dashboardContent = bvbContainer.querySelector('#bvb-dashboard-content');
// Add print-friendly class
bvbContainer.classList.add('bvb-pdf-view');
bvbPdfDownloadBtn.style.display = 'none';
try {
const canvas = await html2canvas(dashboardContent, {
scale: 2,
useCORS: true,
logging: false
});
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF('p', 'mm', 'a4');
const pdfWidth = pdf.internal.pageSize.getWidth();
const margin = 15;
const contentWidth = pdfWidth - (margin * 2);
const contentHeight = (canvas.height * contentWidth) / canvas.width;
pdf.setFont("helvetica", "bold");
pdf.setFontSize(18);
pdf.setTextColor(getComputedStyle(document.documentElement).getPropertyValue('--bvb-primary-color').trim());
pdf.text("My Vocabulary Word List", margin, margin + 5);
pdf.addImage(imgData, 'PNG', margin, margin + 15, contentWidth, contentHeight);
pdf.save('Vocabulary_Word_List.pdf');
} catch (error) {
console.error("BVB PDF Error:", error);
alert("An error occurred while generating the PDF.");
} finally {
// Clean up
bvbContainer.classList.remove('bvb-pdf-view');
bvbPdfDownloadBtn.style.display = 'block';
}
}
// --- 7. UTILITY FUNCTIONS ---
function escapeHTML(str) {
if (typeof str !== 'string') return '';
return str.replace(/[&<>"']/g, m => ({
'&': '&', '<': '<', '>': '>', '"': '"', "'": '''
}[m]));
}
// --- 8. EVENT BINDING (Spec IV.C) ---
// Tab buttons
bvbTabButtons.forEach((button, index) => {
button.addEventListener('click', () => showBvbTab(index));
});
// Navigation buttons
bvbNavNext.addEventListener('click', () => showBvbTab(currentBvbTab + 1));
bvbNavPrev.addEventListener('click', () => showBvbTab(currentBvbTab - 1));
// PDF Download
bvbPdfDownloadBtn.addEventListener('click', downloadBvbPdf);
// Config Tab
bvbAddWordForm.addEventListener('submit', addBvbWord);
bvbConfigWordList.addEventListener('click', (e) => {
if (e.target.classList.contains('bvb-delete-word')) {
const index = parseInt(e.target.dataset.index, 10);
if (!isNaN(index)) {
deleteBvbWord(index);
}
}
});
// Flashcard Tab
bvbFlashcardStartBtn.addEventListener('click', startBvbFlashcards);
bvbFlashcardFlipBtn.addEventListener('click', flipBvbCard);
bvbFlashcardNextBtn.addEventListener('click', nextBvbFlashcard);
// Quiz Tab
bvbQuizStartBtn.addEventListener('click', startBvbQuiz);
bvbQuizRestartBtn.addEventListener('click', startBvbQuiz);
// Note: Quiz submit button is handled in the quiz logic functions
// --- 9. INITIALIZATION ---
bvbWordList = [...bvbSampleData]; // Load sample data
renderAllBvbContent(); // Populate all tabs
showBvbTab(0); // Show the first tab
});