Streaming Services vs. Cable TV Cost Comparison
Streaming Services Costs
Your Streaming Subscriptions:
Other Streaming-Related Costs:
Cable TV Costs
Comparison Summary
Please fill in your costs on the previous tabs. The summary will be calculated here.
Error: Tool UI elements missing.
"; return; } sccAddStreamingService("Netflix", 15.49); // Add some default services sccAddStreamingService("Hulu", 7.99); sccAddStreamingService("Disney+", 7.99); sccOpenTab(null, sccTabContents[0].id); sccUpdateNavButtons(); }); // Debounce function to limit recalculation frequency let sccRecalcTimeout; function sccDebouncedRecalculate() { clearTimeout(sccRecalcTimeout); sccRecalcTimeout = setTimeout(() => { if (sccTabContents[sccCurrentTabIndex] && sccTabContents[sccCurrentTabIndex].id === 'sccTabSummary') { sccCalculateAndDisplay(); } }, 300); // 300ms delay } function sccOpenTab(event, tabId) { let targetButton = null; sccTabContents.forEach(tc => { tc.style.display = "none"; tc.classList.remove('scc-active'); }); sccTabButtons.forEach((btn, index) => { btn.classList.remove('scc-active'); if (btn.getAttribute('onclick').includes(tabId)) { targetButton = btn; sccCurrentTabIndex = index;} }); const targetTab = document.getElementById(tabId); if (targetTab) { targetTab.style.display = "block"; targetTab.classList.add('scc-active');} if (event && event.currentTarget) event.currentTarget.classList.add('scc-active'); else if (targetButton) targetButton.classList.add('scc-active'); sccUpdateNavButtons(); if (tabId === 'sccTabSummary' && typeof sccCalculateAndDisplay === 'function') sccCalculateAndDisplay(); } function sccNavigateTab(direction) { let newIdx = sccCurrentTabIndex; if (direction === 'next') newIdx = (sccCurrentTabIndex + 1) % sccTabButtons.length; else if (direction === 'prev') newIdx = (sccCurrentTabIndex - 1 + sccTabButtons.length) % sccTabButtons.length; const targetTabId = sccTabContents[newIdx].id; sccOpenTab({currentTarget: sccTabButtons[newIdx]}, targetTabId); } function sccUpdateNavButtons() { if (!sccPrevButton || !sccNextButton || sccTabButtons.length === 0) return; sccPrevButton.disabled = (sccCurrentTabIndex === 0); sccNextButton.disabled = (sccCurrentTabIndex === sccTabButtons.length - 1); } function sccAddStreamingService(name = "", cost = "") { if (!sccStreamingServicesListDiv) return; sccServiceCounter++; const serviceId = `sccService${sccServiceCounter}`; const row = document.createElement('div'); row.className = 'scc-streaming-service-row'; row.id = `row-${serviceId}`; row.innerHTML = ` `; sccStreamingServicesListDiv.appendChild(row); // Add event listeners to newly added dynamic fields document.getElementById(`${serviceId}_name`).addEventListener('input', sccDebouncedRecalculate); document.getElementById(`${serviceId}_cost`).addEventListener('input', sccDebouncedRecalculate); } function sccRemoveStreamingService(rowId) { const rowToRemove = document.getElementById(rowId); if (rowToRemove) { rowToRemove.remove(); sccDebouncedRecalculate(); // Recalculate after removing } } function sccGetNum(id, isAnnual = false) { const el = sccAllInputElements[id] || document.getElementById(id); // Check both static and dynamic if (!el) return 0; const val = parseFloat(el.value); if (isNaN(val) || val < 0) return 0; return isAnnual ? val / 12 : val; // Convert annual to monthly if specified } function sccFormat(value) { return `$${value.toLocaleString(undefined, {minimumFractionDigits: 2, maximumFractionDigits: 2})}`; } function sccCalculateAndDisplay() { if (!sccComparisonOutputDiv || !sccDownloadPdfButtonElem) return; // Streaming Costs let totalStreamingMonthlyCost = 0; const serviceRows = sccStreamingServicesListDiv.querySelectorAll('.scc-streaming-service-row'); serviceRows.forEach(row => { const costInput = row.querySelector('input[type="number"]'); if (costInput && costInput.value) { totalStreamingMonthlyCost += parseFloat(costInput.value) || 0; } }); totalStreamingMonthlyCost += sccGetNum('sccStreamingInternet'); totalStreamingMonthlyCost += sccGetNum('sccStreamingDevicesAnnual', true); // annual converted to monthly totalStreamingMonthlyCost += sccGetNum('sccStreamingOtherMonthly'); const totalStreamingAnnualCost = totalStreamingMonthlyCost * 12; // Cable TV Costs let totalCableMonthlyCost = 0; totalCableMonthlyCost += sccGetNum('sccCablePackageMonthly'); totalCableMonthlyCost += sccGetNum('sccCableAddonsMonthly'); totalCableMonthlyCost += sccGetNum('sccCableInternetMonthly'); totalCableMonthlyCost += sccGetNum('sccCableBoxRentalMonthly'); totalCableMonthlyCost += sccGetNum('sccCableSetupAnnualized', true); // annual converted to monthly totalCableMonthlyCost += sccGetNum('sccCableOtherFeesMonthly'); const totalCableAnnualCost = totalCableMonthlyCost * 12; const monthlyDifference = totalStreamingMonthlyCost - totalCableMonthlyCost; // Positive if streaming is more const annualDifference = totalStreamingAnnualCost - totalCableAnnualCost; let comparisonText = ""; if (monthlyDifference < 0) { // Streaming is cheaper comparisonText = `Streaming is ${sccFormat(Math.abs(monthlyDifference))} cheaper per month (${sccFormat(Math.abs(annualDifference))} per year).
`; } else if (monthlyDifference > 0) { // Cable is cheaper comparisonText = `Cable TV is ${sccFormat(monthlyDifference)} cheaper per month (${sccFormat(annualDifference)} per year).
`; } else { comparisonText = "Both options have similar costs.
"; } sccComparisonOutputDiv.innerHTML = `Cost Comparison
Streaming Services
Total Monthly Cost: ${sccFormat(totalStreamingMonthlyCost)}
Total Annual Cost: ${sccFormat(totalStreamingAnnualCost)}
Cable TV
Total Monthly Cost: ${sccFormat(totalCableMonthlyCost)}
Total Annual Cost: ${sccFormat(totalCableAnnualCost)}
${comparisonText}
`;
sccDownloadPdfButtonElem.style.display = 'inline-block';
}
async function sccDownloadPDF() {
const { jsPDF } = window.jspdf;
if (typeof html2canvas === 'undefined' || typeof jsPDF === 'undefined') {
alert('Error: PDF generation libraries not loaded.'); return;
}
// Recalculate all costs to ensure fresh data for PDF
let streamingMonthlyBreakdown = [];
let totalStreamingMonthlyForPDF = 0;
const serviceRows = sccStreamingServicesListDiv.querySelectorAll('.scc-streaming-service-row');
serviceRows.forEach(row => {
const nameInput = row.querySelector('input[type="text"]');
const costInput = row.querySelector('input[type="number"]');
const name = nameInput ? nameInput.value : "Unknown Service";
const cost = (costInput && costInput.value) ? (parseFloat(costInput.value) || 0) : 0;
streamingMonthlyBreakdown.push({name: name, cost: cost});
totalStreamingMonthlyForPDF += cost;
});
const streamingInternetPDF = sccGetNum('sccStreamingInternet');
const streamingDevicesAnnualPDF = sccGetNum('sccStreamingDevicesAnnual', true); // Monthly
const streamingOtherMonthlyPDF = sccGetNum('sccStreamingOtherMonthly');
totalStreamingMonthlyForPDF += streamingInternetPDF + streamingDevicesAnnualPDF + streamingOtherMonthlyPDF;
const totalStreamingAnnualForPDF = totalStreamingMonthlyForPDF * 12;
let cableMonthlyBreakdown = [];
const cablePackagePDF = sccGetNum('sccCablePackageMonthly');
const cableAddonsPDF = sccGetNum('sccCableAddonsMonthly');
const cableInternetPDF = sccGetNum('sccCableInternetMonthly');
const cableBoxRentalPDF = sccGetNum('sccCableBoxRentalMonthly');
const cableSetupAnnualPDF = sccGetNum('sccCableSetupAnnualized', true); // Monthly
const cableOtherFeesPDF = sccGetNum('sccCableOtherFeesMonthly');
let totalCableMonthlyForPDF = cablePackagePDF + cableAddonsPDF + cableInternetPDF + cableBoxRentalPDF + cableSetupAnnualPDF + cableOtherFeesPDF;
const totalCableAnnualForPDF = totalCableMonthlyForPDF * 12;
cableMonthlyBreakdown.push({name: "Base Package", cost: cablePackagePDF});
if(cableAddonsPDF > 0) cableMonthlyBreakdown.push({name: "Add-on Packages", cost: cableAddonsPDF});
cableMonthlyBreakdown.push({name: "Internet", cost: cableInternetPDF});
cableMonthlyBreakdown.push({name: "Equipment Rental", cost: cableBoxRentalPDF});
if(cableSetupAnnualPDF > 0) cableMonthlyBreakdown.push({name: "Annualized Setup (monthly)", cost: cableSetupAnnualPDF});
if(cableOtherFeesPDF > 0) cableMonthlyBreakdown.push({name: "Other Monthly Fees", cost: cableOtherFeesPDF});
const monthlyDifferencePDF = totalStreamingMonthlyForPDF - totalCableMonthlyForPDF;
let comparisonTextPDF = "";
if (monthlyDifferencePDF < 0) comparisonTextPDF = `Streaming is ${sccFormat(Math.abs(monthlyDifferencePDF))} cheaper per month.`;
else if (monthlyDifferencePDF > 0) comparisonTextPDF = `Cable TV is ${sccFormat(monthlyDifferencePDF)} cheaper per month.`;
else comparisonTextPDF = "Both options have similar monthly costs.";
const pdfContentWrapper = document.createElement('div');
pdfContentWrapper.className = 'scc-pdf-content-wrapper';
let streamingHTML = `Streaming Services Monthly Costs:
`; streamingMonthlyBreakdown.forEach(s => streamingHTML += `${s.name}: ${sccFormat(s.cost)}
`);
streamingHTML += `Internet (Streaming): ${sccFormat(streamingInternetPDF)}
`;
streamingHTML += `Annualized Devices (monthly): ${sccFormat(streamingDevicesAnnualPDF)}
`;
if(streamingOtherMonthlyPDF > 0) streamingHTML += `Other Monthly: ${sccFormat(streamingOtherMonthlyPDF)}
`;
streamingHTML += `Total Streaming Monthly: ${sccFormat(totalStreamingMonthlyForPDF)}
`;
streamingHTML += `Total Streaming Annual: ${sccFormat(totalStreamingAnnualForPDF)}
`;
let cableHTML = `Cable TV Monthly Costs:
`; cableMonthlyBreakdown.forEach(c => cableHTML += `${c.name}: ${sccFormat(c.cost)}
`);
cableHTML += `Total Cable TV Monthly: ${sccFormat(totalCableMonthlyForPDF)}
`;
cableHTML += `Total Cable TV Annual: ${sccFormat(totalCableAnnualForPDF)}
`;
pdfContentWrapper.innerHTML = `
Streaming vs. Cable TV Cost Analysis
${streamingHTML}
${cableHTML}
Overall Comparison
${comparisonTextPDF}
Annual Difference: ${sccFormat(totalStreamingAnnualForPDF - totalCableAnnualForPDF)} (Streaming - Cable)
Report generated on: ${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()}
`; document.body.appendChild(pdfContentWrapper); try { const canvas = await html2canvas(pdfContentWrapper, { scale: 2, useCORS: true, backgroundColor: '#ffffff' }); const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'p', unit: 'pt', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const pdfHeight = pdf.internal.pageSize.getHeight(); const imgProps = pdf.getImageProperties(imgData); const ratio = Math.min((pdfWidth - 40) / imgProps.width, (pdfHeight - 40) / imgProps.height); pdf.addImage(imgData, 'PNG', (pdfWidth - imgProps.width * ratio) / 2, 20, imgProps.width * ratio, imgProps.height * ratio); pdf.save('Streaming_vs_Cable_Cost_Comparison.pdf'); } catch (error) { console.error("Error during PDF generation:", error); alert("An error occurred while generating the PDF."); } finally { document.body.removeChild(pdfContentWrapper); } }