<?php
// index.php - simple cable size calculator
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>CableCalc – Cable Size Calculator</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
<style>
    :root {
        --bg: #f4f4f4;
        --card-bg: #ffffff;
        --text: #222;
        --text-muted: #555;
        --border: #ccc;
        --accent: #0078d7;
        --result-bg: #f0f7ff;
        --result-border: #c5ddff;
        --error-bg: #ffecec;
        --error-border: #ffb3b3;
    }

    /* DARK MODE VARIABLES */
    @media (prefers-color-scheme: dark) {
        :root {
            --bg: #111;
            --card-bg: #1b1b1b;
            --text: #eee;
            --text-muted: #bbb;
            --border: #444;
            --accent: #3ea0ff;
            --result-bg: #102233;
            --result-border: #1a3a57;
            --error-bg: #331111;
            --error-border: #883333;
        }
    }

    /* USER OVERRIDE – DARK */
    body.dark {
        --bg: #111;
        --card-bg: #1b1b1b;
        --text: #eee;
        --text-muted: #bbb;
        --border: #444;
        --accent: #3ea0ff;
        --result-bg: #102233;
        --result-border: #1a3a57;
        --error-bg: #331111;
        --error-border: #883333;
    }

    /* USER OVERRIDE – LIGHT */
    body.light {
        --bg: #f4f4f4;
        --card-bg: #ffffff;
        --text: #222;
        --text-muted: #555;
        --border: #ccc;
        --accent: #0078d7;
        --result-bg: #f0f7ff;
        --result-border: #c5ddff;
        --error-bg: #ffecec;
        --error-border: #ffb3b3;
    }

    /* Base styles */
    body {
        font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
        margin: 0;
        padding: 0;
        background: var(--bg);
        color: var(--text);
        transition: background 0.3s, color 0.3s;
    }

    .container {
        max-width: 800px;
        margin: 20px auto 40px;
        background: var(--card-bg);
        padding: 20px 24px 28px;
        border-radius: 12px;
        box-shadow: 0 4px 15px rgba(0,0,0,0.20);
        transition: background 0.3s;
    }

    h1 {
        margin-top: 0;
        font-size: 1.8rem;
    }

    .grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
        gap: 16px 24px;
    }

    .field label {
        font-size: 0.9rem;
        font-weight: 600;
        display: block;
        margin-bottom: 4px;
        color: var(--text);
    }

    .field input,
    .field select {
        width: 100%;
        box-sizing: border-box;
        padding: 6px 8px;
        border-radius: 6px;
        border: 1px solid var(--border);
        background: var(--card-bg);
        color: var(--text);
        transition: background 0.3s, color 0.3s, border 0.3s;
    }

    .inline-options label {
        color: var(--text-muted);
    }

    button {
        margin-top: 12px;
        padding: 8px 16px;
        border-radius: 999px;
        border: none;
        font-size: 0.95rem;
        font-weight: 600;
        cursor: pointer;
        background: var(--accent);
        color: white;
        transition: opacity 0.2s;
    }
    button:hover {
        opacity: 0.85;
    }

    .result {
        margin-top: 20px;
        padding: 12px 16px;
        border-radius: 8px;
        background: var(--result-bg);
        border: 1px solid var(--result-border);
    }

    .error {
        margin-top: 12px;
        padding: 10px 14px;
        border-radius: 8px;
        background: var(--error-bg);
        border: 1px solid var(--error-border);
        color: #ff8080;
    }

    .notes {
        margin-top: 14px;
        font-size: 0.8rem;
        color: var(--text-muted);
    }

    .badge {
        display: inline-block;
        padding: 2px 8px;
        border-radius: 999px;
        font-size: 0.75rem;
        background: var(--border);
        color: var(--text);
    }

    /* Toggle button */
    #modeToggle {
        float: right;
        padding: 4px 12px;
        border-radius: 20px;
        background: var(--border);
        color: var(--text);
        font-size: 0.8rem;
        cursor: pointer;
    }
</style>

</head>
<body>
<div class="container">
    <h1>CableCalc <span class="badge">beta</span></h1>
    <p style="font-size:0.9rem; color:#555;">
        Enter your data – the calculator suggests the smallest copper cable size that keeps current
        within a basic ampacity and voltage drop limit.
    </p>

    <div class="grid">
        <!-- AC / DC -->
        <div class="field">
            <label for="acdc">AC / DC</label>
            <select id="acdc">
                <option value="AC">AC</option>
                <option value="DC">DC</option>
            </select>
            <small>AC/DC is currently only shown for reference; calculation uses the same resistive model.</small>
        </div>

        <!-- Voltage -->
        <div class="field">
            <label for="voltage">Voltage [V]</label>
            <input type="number" id="voltage" min="0" step="0.1" value="230">
        </div>

        <!-- Current / Power selector -->
        <div class="field">
            <label>What is known?</label>
            <div class="inline-options">
                <label>
                    <input type="radio" name="loadType" value="current" checked>
                    Current (A) known
                </label>
                <label>
                    <input type="radio" name="loadType" value="power">
                    Power (W) known
                </label>
            </div>
        </div>

        <!-- Current input -->
        <div class="field" id="field-current">
            <label for="current">Current [A]</label>
            <input type="number" id="current" min="0" step="0.01">
        </div>

        <!-- Power input -->
        <div class="field" id="field-power" style="display:none;">
            <label for="power">Power [W]</label>
            <input type="number" id="power" min="0" step="1">
            <small>Assumes cos φ / power factor = 1.0 for simplicity.</small>
        </div>

        <!-- Length -->
        <div class="field">
            <label for="length">Cable length (one way)</label>
            <input type="number" id="length" min="0" step="0.1" value="10">
        </div>

        <!-- Length unit -->
        <div class="field">
            <label for="lengthUnit">Length unit</label>
            <select id="lengthUnit">
                <option value="m">Meters</option>
                <option value="ft">Feet</option>
            </select>
            <small>Voltage drop is calculated over the round-trip (out &amp; back).</small>
        </div>

        <!-- Max voltage drop -->
        <div class="field">
            <label for="maxDrop">Max voltage drop [%]</label>
            <input type="number" id="maxDrop" min="0.5" step="0.1" value="3.0">
        </div>

        <!-- Output units -->
        <div class="field">
            <label for="unitSystem">Preferred output</label>
            <select id="unitSystem">
                <option value="mixed">AWG + mm²</option>
                <option value="awg">AWG only</option>
                <option value="mm2">mm² only</option>
            </select>
        </div>
    </div>

    <button type="button" onclick="calculateCable()">Calculate cable size</button>

    <div id="error" class="error" style="display:none;"></div>
    <div id="result" class="result" style="display:none;"></div>

    <div id="modeToggle" onclick="toggleMode()">🌓</div>

    <div class="notes">
        <strong>Notes &amp; limitations:</strong>
        <ul>
            <li>Assumes copper conductors, single circuit, free air / light installation.</li>
            <li>Uses generic ampacity values (conservative but not a substitute for local electrical codes).</li>
            <li>For mains or critical installations always have a qualified electrician verify the result.</li>
        </ul>
    </div>
</div>

<script>
// Cable data: copper, approx. resistance at 20°C and conservative ampacity in A.
// Values are generic and simplified – not a substitute for national standards.
const cableSizes = [
    //  AWG,   mm²,    diameter(mm, bare conductor approx),  R[ohm/km], ampacity[A]
    { awg: 18, mm2: 0.82, diameter: 1.02, r_km: 21.0, amp: 14 },
    { awg: 16, mm2: 1.31, diameter: 1.29, r_km: 13.3, amp: 18 },
    { awg: 14, mm2: 2.08, diameter: 1.63, r_km: 8.4,  amp: 24 },
    { awg: 12, mm2: 3.31, diameter: 2.05, r_km: 5.3,  amp: 32 },
    { awg: 10, mm2: 5.26, diameter: 2.59, r_km: 3.3,  amp: 45 },
    { awg: 8,  mm2: 8.37, diameter: 3.26, r_km: 2.1,  amp: 60 },
    { awg: 6,  mm2: 13.3, diameter: 4.11, r_km: 1.3,  amp: 80 },
    { awg: 4,  mm2: 21.1, diameter: 5.19, r_km: 0.8,  amp: 105 },
    { awg: 2,  mm2: 33.6, diameter: 6.54, r_km: 0.51, amp: 140 },
    { awg: 1,  mm2: 42.4, diameter: 7.35, r_km: 0.40, amp: 165 },
    { awg: 0,  mm2: 53.5, diameter: 8.25, r_km: 0.32, amp: 195 }
];

// Toggle current / power fields
document.querySelectorAll('input[name="loadType"]').forEach(r => {
    r.addEventListener('change', function () {
        const type = this.value;
        document.getElementById('field-current').style.display = (type === 'current') ? 'block' : 'none';
        document.getElementById('field-power').style.display = (type === 'power') ? 'block' : 'none';
    });
});

function showError(msg) {
    const err = document.getElementById('error');
    err.textContent = msg;
    err.style.display = 'block';
    document.getElementById('result').style.display = 'none';
}

function clearError() {
    const err = document.getElementById('error');
    err.style.display = 'none';
    err.textContent = '';
}

function toggleMode() {
    if (document.body.classList.contains("dark")) {
        document.body.classList.remove("dark");
        document.body.classList.add("light");
        localStorage.setItem("cablecalc-theme", "light");
    } else if (document.body.classList.contains("light")) {
        document.body.classList.remove("light");
        document.body.classList.add("dark");
        localStorage.setItem("cablecalc-theme", "dark");
    } else {
        // No override yet → force dark
        document.body.classList.add("dark");
        localStorage.setItem("cablecalc-theme", "dark");
    }
}

// Load saved preference
(function() {
    const saved = localStorage.getItem("cablecalc-theme");
    if (saved === "dark") document.body.classList.add("dark");
    if (saved === "light") document.body.classList.add("light");
})();

function calculateCable() {
    clearError();
    const voltage = parseFloat(document.getElementById('voltage').value);
    const lengthOneWay = parseFloat(document.getElementById('length').value);
    const lengthUnit = document.getElementById('lengthUnit').value;
    const maxDropPct = parseFloat(document.getElementById('maxDrop').value);
    const unitSystem = document.getElementById('unitSystem').value;
    const loadType = document.querySelector('input[name="loadType"]:checked').value;

    if (isNaN(voltage) || voltage <= 0) {
        showError('Please enter a valid voltage.');
        return;
    }
    if (isNaN(lengthOneWay) || lengthOneWay <= 0) {
        showError('Please enter a valid cable length.');
        return;
    }
    if (isNaN(maxDropPct) || maxDropPct <= 0) {
        showError('Please enter a valid maximum voltage drop percentage.');
        return;
    }

    let current;
    if (loadType === 'current') {
        current = parseFloat(document.getElementById('current').value);
        if (isNaN(current) || current <= 0) {
            showError('Please enter a valid current.');
            return;
        }
    } else {
        const power = parseFloat(document.getElementById('power').value);
        if (isNaN(power) || power <= 0) {
            showError('Please enter a valid power.');
            return;
        }
        // Power factor assumed 1.0
        current = power / voltage;
    }

    // Convert length to meters (one way)
    let length_m = lengthOneWay;
    if (lengthUnit === 'ft') {
        length_m = lengthOneWay * 0.3048;
    }

    // Total circuit length = out + back
    const totalLength_m = length_m * 2;

    const maxDrop_V = voltage * (maxDropPct / 100.0);

    let chosen = null;
    let worstCase = null; // largest size if nothing meets both criteria

    for (let i = 0; i < cableSizes.length; i++) {
        const c = cableSizes[i];

        const rPerMeter = c.r_km / 1000.0; // ohm/m
        const rTotal = rPerMeter * totalLength_m; // ohm
        const vDrop = current * rTotal; // V
        const vDropPct = (vDrop / voltage) * 100;

        const okAmpacity = current <= c.amp;
        const okDrop = vDrop <= maxDrop_V;

        // Remember largest size for fallback
        worstCase = {
            cable: c,
            vDrop: vDrop,
            vDropPct: vDropPct,
            okAmpacity: okAmpacity,
            okDrop: okDrop
        };

        if (okAmpacity && okDrop) {
            chosen = {
                cable: c,
                vDrop: vDrop,
                vDropPct: vDropPct
            };
            break; // smallest that satisfies
        }
    }

    const res = document.getElementById('result');
    res.style.display = 'block';

    if (!chosen && worstCase) {
        const c = worstCase.cable;
        const vDrop = worstCase.vDrop;
        const vDropPct = worstCase.vDropPct;

        res.innerHTML = `
            <strong>No cable size in the built-in table fully meets the limits.</strong><br><br>
            Suggested <em>minimum</em> size (table maximum):<br>
            AWG ${c.awg}, approx. ${c.mm2.toFixed(1)} mm², conductor diameter ≈ ${c.diameter.toFixed(2)} mm<br>
            Ampacity (approx.): ${c.amp} A<br>
            Estimated voltage drop: ${vDrop.toFixed(2)} V (${vDropPct.toFixed(2)} %)<br><br>
            <span style="color:#a40000;">Warning:</span> Either the desired voltage drop or ampacity is exceeded.
            Consider using a larger cable than listed here or shortening the run.
        `;
        return;
    }

    if (!chosen) {
        showError('No valid cable size found. Please check inputs.');
        return;
    }

    const c = chosen.cable;
    const vDrop = chosen.vDrop;
    const vDropPct = chosen.vDropPct;

    let mainLine = '';
    if (unitSystem === 'awg') {
        mainLine = `Recommended cable size: <strong>AWG ${c.awg}</strong>`;
    } else if (unitSystem === 'mm2') {
        mainLine = `Recommended cable size: <strong>${c.mm2.toFixed(1)} mm²</strong>`;
    } else {
        mainLine = `Recommended cable size: <strong>AWG ${c.awg} (~${c.mm2.toFixed(1)} mm²)</strong>`;
    }

    res.innerHTML = `
        ${mainLine}<br>
        Conductor diameter (approx.): <strong>${c.diameter.toFixed(2)} mm</strong><br>
        Ampacity (approx.): <strong>${c.amp} A</strong><br>
        Estimated voltage drop over ${length_m.toFixed(1)} m one-way (round-trip ${totalLength_m.toFixed(1)} m):<br>
        <strong>${vDrop.toFixed(2)} V (${vDropPct.toFixed(2)} %)</strong>
    `;
}
</script>
</body>
</html>
