Conflict: ${event.warConflict}
`;
if (event.theater) metaHtml += `
Theater/Front: ${event.theater}
`;
if (event.category) metaHtml += `
Category: ${event.category}
`;
card.innerHTML = `
${event.displayDate}
${event.title}
${metaHtml}
${event.description.replace(/\n/g, '
')}
`;
timelinePreviewDiv.appendChild(card);
});
}
function handlePdfDownload() {
if (!jsPDF_constructor_for_tool) {
alert("PDF library is not available."); return;
}
const eventsToExport = getSortedEvents();
const pdfTimelineTitle = timelineTitleInput.value;
if (eventsToExport.length === 0) {
alert("No events to export."); return;
}
const pdf = new jsPDF_constructor_for_tool({ orientation: 'p', unit: 'mm', format: 'a4' });
const primaryColor = primaryColorInput.value;
const textColor = textColorInput.value;
const pageBgColor = bgColorInput.value;
pdf.setFillColor(pageBgColor);
pdf.rect(0, 0, pdf.internal.pageSize.getWidth(), pdf.internal.pageSize.getHeight(), 'F');
const margin = 15;
const contentWidth = pdf.internal.pageSize.getWidth() - 2 * margin;
let currentY = margin;
pdf.setFontSize(18);
pdf.setTextColor(primaryColor);
const titleLines = pdf.splitTextToSize(pdfTimelineTitle, contentWidth);
pdf.text(titleLines, pdf.internal.pageSize.getWidth() / 2, currentY, { align: 'center' });
currentY += (titleLines.length * 18 * 0.35) + 10;
let pageFirstEventY = currentY;
eventsToExport.forEach(event => {
let estimatedBlockHeight = 0;
pdf.setFontSize(10); estimatedBlockHeight += 5; // Display Date
pdf.setFontSize(12); estimatedBlockHeight += (pdf.splitTextToSize(event.title, contentWidth).length * 12 * 0.35) + 3; // Title
pdf.setFontSize(9); // Meta
estimatedBlockHeight += 4; // War/Conflict
if (event.theater) estimatedBlockHeight += 4;
if (event.category) estimatedBlockHeight += 4;
pdf.setFontSize(10); // Description
if (event.description) estimatedBlockHeight += (pdf.splitTextToSize(event.description, contentWidth).length * 10 * 0.35);
estimatedBlockHeight += 10; // Spacing
if (currentY + estimatedBlockHeight > pdf.internal.pageSize.getHeight() - margin) {
pdf.setDrawColor(primaryColor); pdf.setLineWidth(0.6);
if (currentY > pageFirstEventY) pdf.line(margin + 2, pageFirstEventY - 2, margin + 2, currentY - 5); // Timeline bar for current page
pdf.addPage(); currentY = margin; pageFirstEventY = currentY;
pdf.setFillColor(pageBgColor); pdf.rect(0, 0, pdf.internal.pageSize.getWidth(), pdf.internal.pageSize.getHeight(), 'F');
}
const eventDotY = currentY + 2; // Align dot with Display Date
pdf.setFontSize(10); pdf.setTextColor(textColor);
pdf.text(event.displayDate, margin + 7, currentY); currentY += 5;
pdf.setFontSize(12); pdf.setTextColor(primaryColor);
const eventTitleLines = pdf.splitTextToSize(event.title, contentWidth - 7); // Indent for timeline
pdf.text(eventTitleLines, margin + 7, currentY);
currentY += (eventTitleLines.length * 12 * 0.35) + 3;
pdf.setFontSize(9); pdf.setTextColor(textColor);
let metaText = `Conflict: ${event.warConflict}`;
if (event.theater) metaText += ` | Theater: ${event.theater}`;
if (event.category) metaText += ` | Category: ${event.category}`;
const metaLines = pdf.splitTextToSize(metaText, contentWidth - 7);
pdf.text(metaLines, margin + 7, currentY);
currentY += (metaLines.length * 9 * 0.35) + 3;
if (event.description) {
pdf.setFontSize(10);
const descLines = pdf.splitTextToSize(event.description, contentWidth - 7);
pdf.text(descLines, margin + 7, currentY);
currentY += (descLines.length * 10 * 0.35);
}
currentY += 7; // Space after event
// Event Dot
pdf.setFillColor(primaryColor); pdf.setDrawColor(primaryColor);
pdf.circle(margin + 2, eventDotY, 1.5, 'FD');
});
// Final timeline bar segment
pdf.setDrawColor(primaryColor); pdf.setLineWidth(0.6);
if (eventsToExport.length > 0 && currentY > pageFirstEventY) { // Check if currentY moved
pdf.line(margin + 2, pageFirstEventY -2 , margin + 2, currentY - 7);
}
let safePdfTitle = pdfTimelineTitle.replace(/[^a-z0-9]/gi, '_').toLowerCase() || "world_war_timeline";
if (safePdfTitle.length > 50) safePdfTitle = safePdfTitle.substring(0, 50);
pdf.save(safePdfTitle + '.pdf');
}
// Event Listeners
tabs.forEach(tab => {
tab.addEventListener('click', (e) => switchTab(e.currentTarget.dataset.tab));
});
document.querySelectorAll('.wwtc-next-tab, .wwtc-prev-tab').forEach(button => {
button.addEventListener('click', (e) => {
const targetTabId = e.currentTarget.dataset.nexttab || e.currentTarget.dataset.prevtab;
if (targetTabId) switchTab(targetTabId);
});
});
if (addEventForm) addEventForm.addEventListener('submit', handleAddEventFormSubmit);
if (clearFormButton) clearFormButton.addEventListener('click', () => {
addEventForm.reset();
eventYearInput.focus();
});
[timelineTitleInput, primaryColorInput, textColorInput, bgColorInput, eventCardBgColorInput].forEach(input => {
if (input) {
input.addEventListener('input', renderTimelinePreview);
if (input.type === 'color') input.addEventListener('change', renderTimelinePreview);
}
});
if (downloadPdfButton && !downloadPdfButton.disabled) {
downloadPdfButton.addEventListener('click', handlePdfDownload);
}
// Initialization
loadEventsFromLocalStorage();
updateDatalistSuggestions();
renderCurrentEventsList();
switchTab('eventManager'); // Initial active tab
renderTimelinePreview(); // Initial render for preview tab (even if not active, prepares content)
updateCssVariables();
});