`;
if(dpsa_el.resultsContainer) dpsa_el.resultsContainer.innerHTML = resultsHTML;
// Final Summary
let summaryText = "";
if (snowballResult.months !== Infinity && avalancheResult.months !== Infinity) {
const interestDiff = snowballResult.totalInterest - avalancheResult.totalInterest;
const timeDiff = snowballResult.months - avalancheResult.months;
if (Math.abs(interestDiff) < 1 && Math.abs(timeDiff) < 1) {
summaryText = "Both methods result in a similar payoff time and total interest paid with your inputs.";
} else if (avalancheResult.totalInterest < snowballResult.totalInterest) {
summaryText = `The Debt Avalanche method is estimated to save you approximately ${dpsa_formatCurrency(interestDiff)} in interest`;
if (avalancheResult.months < snowballResult.months) {
summaryText += ` and get you debt-free ${dpsa_formatMonthsToYearsMonths(timeDiff)} sooner.`;
} else if (avalancheResult.months > snowballResult.months) {
summaryText += ` but may take ${dpsa_formatMonthsToYearsMonths(Math.abs(timeDiff))} longer.`; // Unlikely but possible with complex min payments
} else {
summaryText += ` in a similar timeframe.`;
}
} else { // Snowball somehow better or equal (less common for interest, could be time if APRs are very close)
summaryText = `The Debt Snowball method is estimated to have you pay ${dpsa_formatCurrency(Math.abs(interestDiff))} more in interest`;
if (snowballResult.months < avalancheResult.months) {
summaryText += ` but could get you debt-free ${dpsa_formatMonthsToYearsMonths(Math.abs(timeDiff))} sooner (often due to quick wins).`;
} else {
summaryText += ` and take a similar amount of time. Consider the psychological benefits of Snowball if motivation is key.`;
}
}
summaryText += "
Avalanche usually saves more money. Snowball can be motivating due to quicker small debt payoffs."; } else { summaryText = "Could not fully compare strategies due to calculation issues (e.g., payments not covering interest). Please review your inputs."; } if(dpsa_el.finalSummaryDiv) dpsa_el.finalSummaryDiv.innerHTML = summaryText; if(dpsa_el.pdfDownloadBtn && dpsa_el.pdfDownloadBtn.style) dpsa_el.pdfDownloadBtn.style.display = 'block'; } function dpsa_resetForm() { if(dpsa_el.debtEntriesContainer) dpsa_el.debtEntriesContainer.innerHTML = ""; dpsa_debtEntryCount = 0; dpsa_addDebtEntry('Credit Card A', 2500, 22, 75); dpsa_addDebtEntry('Student Loan B', 10000, 6.8, 150); dpsa_addDebtEntry('Personal Loan C', 5000, 12, 200); if(dpsa_el.extraMonthlyPayment) dpsa_el.extraMonthlyPayment.value = "200"; dpsa_updateCurrentDebtSummary(); document.querySelectorAll('#debtPayoffCalculator .dpsa-error-message').forEach(el => el.textContent = ''); if(dpsa_el.resultsContainer) dpsa_el.resultsContainer.innerHTML = ""; if(dpsa_el.finalSummaryDiv) dpsa_el.finalSummaryDiv.innerHTML = ""; if(dpsa_el.pdfDownloadBtn && dpsa_el.pdfDownloadBtn.style) dpsa_el.pdfDownloadBtn.style.display = 'none'; if(dpsa_el.resultsTabButton) dpsa_el.resultsTabButton.disabled = true; dpsa_currentTab = 0; dpsa_openTab(null, 'dpsa-tabDebts'); } function dpsa_downloadPDF() { if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF !== 'function' || typeof window.html2canvas !== 'function' || typeof window.jspdf.jsPDF.API.autoTable !== 'function') { alert("PDF generation library not fully loaded. Check CDN links & internet."); return; } const jsPDFConstructor = window.jspdf.jsPDF; const resultsContent = dpsa_el.resultsContainer; const finalSummaryContent = dpsa_el.finalSummaryDiv; const disclaimerContent = document.querySelector('#debtPayoffCalculator .dpsa-disclaimer-note'); if (!resultsContent || !resultsContent.innerHTML.trim() || !finalSummaryContent || !finalSummaryContent.innerHTML.trim()) { alert("No results to download. Please calculate first."); return; } const pdf = new jsPDFConstructor('p', 'pt', 'a4'); const toolTitle = "Debt Snowball vs. Avalanche Payoff Comparison"; const margins = { top: 40, bottom: 40, left: 30, right: 30 }; let yPos = margins.top; pdf.setFontSize(18); pdf.text(toolTitle, pdf.internal.pageSize.getWidth() / 2, yPos, { align: 'center' }); yPos += 30; // Inputs Summary pdf.setFontSize(11); pdf.text("Your Input Summary:", margins.left, yPos); yPos += 15; pdf.setFontSize(9); pdf.text(`- Total Initial Debt: ${dpsa_el.currentTotalDebtDisplay.textContent}`, margins.left + 10, yPos); yPos += 13; pdf.text(`- Total Minimum Payments: ${dpsa_el.currentMinPaymentsDisplay.textContent}`, margins.left + 10, yPos); yPos += 13; pdf.text(`- Extra Monthly Payment: ${dpsa_formatCurrency(parseFloat(dpsa_el.extraMonthlyPayment.value))}`, margins.left + 10, yPos); yPos += 20; // Results (capture as image due to complex layout) html2canvas(resultsContent, {scale: 1.2, backgroundColor: '#ffffff', useCORS: true, windowWidth: resultsContent.scrollWidth}).then(canvasResults => { const imgDataResults = canvasResults.toDataURL('image/png'); const imgPropsResults = pdf.getImageProperties(imgDataResults); const pdfWidth = pdf.internal.pageSize.getWidth() - margins.left - margins.right; let pdfHeightResults = (imgPropsResults.height * pdfWidth) / imgPropsResults.width; if (yPos + pdfHeightResults > pdf.internal.pageSize.getHeight() - margins.bottom - 30) { pdf.addPage(); yPos = margins.top; } pdf.addImage(imgDataResults, 'PNG', margins.left, yPos, pdfWidth, pdfHeightResults); yPos += pdfHeightResults + 15; // Final Summary (text or small canvas) if (finalSummaryContent.innerHTML.trim()) { if (yPos + 60 > pdf.internal.pageSize.getHeight() - margins.bottom) { // Approx height for summary pdf.addPage(); yPos = margins.top; } pdf.setFontSize(10); pdf.setFillColor(231, 243, 255); // Light blue background pdf.rect(margins.left, yPos, pdfWidth, 50, 'F'); // Background rect const summaryLines = pdf.splitTextToSize(finalSummaryContent.innerText.trim(), pdfWidth - 10); pdf.text(summaryLines, margins.left + 5, yPos + 15); yPos += 50 + 15; } if (disclaimerContent) { if (yPos > pdf.internal.pageSize.getHeight() - margins.bottom - 40) { pdf.addPage(); yPos = margins.top; } pdf.setFontSize(8); const disclaimerLines = pdf.splitTextToSize(disclaimerContent.innerText.trim(), pdfWidth); pdf.text(disclaimerLines, margins.left, yPos); } pdf.save('Debt_Payoff_Comparison.pdf'); }).catch(err => { console.error("Error generating PDF results with html2canvas:", err); alert("Error rendering results to PDF. The PDF may be incomplete."); // Fallback or save what's already drawn pdf.save('Debt_Payoff_Comparison_Partial.pdf'); }); }
Avalanche usually saves more money. Snowball can be motivating due to quicker small debt payoffs."; } else { summaryText = "Could not fully compare strategies due to calculation issues (e.g., payments not covering interest). Please review your inputs."; } if(dpsa_el.finalSummaryDiv) dpsa_el.finalSummaryDiv.innerHTML = summaryText; if(dpsa_el.pdfDownloadBtn && dpsa_el.pdfDownloadBtn.style) dpsa_el.pdfDownloadBtn.style.display = 'block'; } function dpsa_resetForm() { if(dpsa_el.debtEntriesContainer) dpsa_el.debtEntriesContainer.innerHTML = ""; dpsa_debtEntryCount = 0; dpsa_addDebtEntry('Credit Card A', 2500, 22, 75); dpsa_addDebtEntry('Student Loan B', 10000, 6.8, 150); dpsa_addDebtEntry('Personal Loan C', 5000, 12, 200); if(dpsa_el.extraMonthlyPayment) dpsa_el.extraMonthlyPayment.value = "200"; dpsa_updateCurrentDebtSummary(); document.querySelectorAll('#debtPayoffCalculator .dpsa-error-message').forEach(el => el.textContent = ''); if(dpsa_el.resultsContainer) dpsa_el.resultsContainer.innerHTML = ""; if(dpsa_el.finalSummaryDiv) dpsa_el.finalSummaryDiv.innerHTML = ""; if(dpsa_el.pdfDownloadBtn && dpsa_el.pdfDownloadBtn.style) dpsa_el.pdfDownloadBtn.style.display = 'none'; if(dpsa_el.resultsTabButton) dpsa_el.resultsTabButton.disabled = true; dpsa_currentTab = 0; dpsa_openTab(null, 'dpsa-tabDebts'); } function dpsa_downloadPDF() { if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF !== 'function' || typeof window.html2canvas !== 'function' || typeof window.jspdf.jsPDF.API.autoTable !== 'function') { alert("PDF generation library not fully loaded. Check CDN links & internet."); return; } const jsPDFConstructor = window.jspdf.jsPDF; const resultsContent = dpsa_el.resultsContainer; const finalSummaryContent = dpsa_el.finalSummaryDiv; const disclaimerContent = document.querySelector('#debtPayoffCalculator .dpsa-disclaimer-note'); if (!resultsContent || !resultsContent.innerHTML.trim() || !finalSummaryContent || !finalSummaryContent.innerHTML.trim()) { alert("No results to download. Please calculate first."); return; } const pdf = new jsPDFConstructor('p', 'pt', 'a4'); const toolTitle = "Debt Snowball vs. Avalanche Payoff Comparison"; const margins = { top: 40, bottom: 40, left: 30, right: 30 }; let yPos = margins.top; pdf.setFontSize(18); pdf.text(toolTitle, pdf.internal.pageSize.getWidth() / 2, yPos, { align: 'center' }); yPos += 30; // Inputs Summary pdf.setFontSize(11); pdf.text("Your Input Summary:", margins.left, yPos); yPos += 15; pdf.setFontSize(9); pdf.text(`- Total Initial Debt: ${dpsa_el.currentTotalDebtDisplay.textContent}`, margins.left + 10, yPos); yPos += 13; pdf.text(`- Total Minimum Payments: ${dpsa_el.currentMinPaymentsDisplay.textContent}`, margins.left + 10, yPos); yPos += 13; pdf.text(`- Extra Monthly Payment: ${dpsa_formatCurrency(parseFloat(dpsa_el.extraMonthlyPayment.value))}`, margins.left + 10, yPos); yPos += 20; // Results (capture as image due to complex layout) html2canvas(resultsContent, {scale: 1.2, backgroundColor: '#ffffff', useCORS: true, windowWidth: resultsContent.scrollWidth}).then(canvasResults => { const imgDataResults = canvasResults.toDataURL('image/png'); const imgPropsResults = pdf.getImageProperties(imgDataResults); const pdfWidth = pdf.internal.pageSize.getWidth() - margins.left - margins.right; let pdfHeightResults = (imgPropsResults.height * pdfWidth) / imgPropsResults.width; if (yPos + pdfHeightResults > pdf.internal.pageSize.getHeight() - margins.bottom - 30) { pdf.addPage(); yPos = margins.top; } pdf.addImage(imgDataResults, 'PNG', margins.left, yPos, pdfWidth, pdfHeightResults); yPos += pdfHeightResults + 15; // Final Summary (text or small canvas) if (finalSummaryContent.innerHTML.trim()) { if (yPos + 60 > pdf.internal.pageSize.getHeight() - margins.bottom) { // Approx height for summary pdf.addPage(); yPos = margins.top; } pdf.setFontSize(10); pdf.setFillColor(231, 243, 255); // Light blue background pdf.rect(margins.left, yPos, pdfWidth, 50, 'F'); // Background rect const summaryLines = pdf.splitTextToSize(finalSummaryContent.innerText.trim(), pdfWidth - 10); pdf.text(summaryLines, margins.left + 5, yPos + 15); yPos += 50 + 15; } if (disclaimerContent) { if (yPos > pdf.internal.pageSize.getHeight() - margins.bottom - 40) { pdf.addPage(); yPos = margins.top; } pdf.setFontSize(8); const disclaimerLines = pdf.splitTextToSize(disclaimerContent.innerText.trim(), pdfWidth); pdf.text(disclaimerLines, margins.left, yPos); } pdf.save('Debt_Payoff_Comparison.pdf'); }).catch(err => { console.error("Error generating PDF results with html2canvas:", err); alert("Error rendering results to PDF. The PDF may be incomplete."); // Fallback or save what's already drawn pdf.save('Debt_Payoff_Comparison_Partial.pdf'); }); }
