{% extends "base.html" %}
{% block title %}Development Length - ConcreteDesignPy{% endblock %}
{% block head %}<script src="https://cdn.jsdelivr.net/npm/plotly.js-dist-min/plotly.min.js"></script>{% endblock %}

{% block content %}
<div class="calc-page">
    <a href="/" class="back-link">&larr; All Calculators</a>
    <h1>Development Length &amp; Hook Geometry</h1>
    <p class="ref">NSCP 2015 Section 425 &mdash; Tables 425.3.1 &amp; 425.3.2</p>

    <form id="calc-form" class="calc-form">
        <div class="form-section">
            <div class="form-row">
                <div class="form-group">
                    <label>Bar Type</label>
                    <select name="bar_type">
                        <option value="deformed">Deformed Bars (Table 425.3.1)</option>
                        <option value="stirrup">Stirrups/Ties/Hoops (Table 425.3.2)</option>
                    </select>
                </div>
                <div class="form-group">
                    <label>Bar Size (mm)</label>
                    <input type="number" name="bar_size" value="25" required>
                </div>
                <div class="form-group">
                    <label>Hook Angle</label>
                    <select name="angle">
                        <option value="90">90&deg;</option>
                        <option value="135">135&deg;</option>
                        <option value="180" selected>180&deg;</option>
                    </select>
                </div>
            </div>
        </div>

        <button type="submit" class="btn-primary">Calculate</button>
    </form>

    <div id="results" class="results-panel" style="display:none;">
        <h2>Results</h2>
        <div style="display:flex;flex-wrap:wrap;gap:16px;align-items:flex-start;">
            <div id="chart-hook" style="flex:1;min-width:480px;"></div>
            <div id="results-content" style="flex:0 0 auto;min-width:200px;"></div>
        </div>
        <div id="results-report" class="report-panel"></div>
    </div>
</div>

<script>
function renderHookChart(r) {
    var D = r.bend_diameter;
    var R = D / 2;
    var lext = r.lext;
    var ldh = r.ldh;
    var db = r.bar_size;
    var angle = r.angle;
    var hw = db / 2;

    var traces = [];
    var annotations = [];

    var barFill = 'rgba(212,212,216,0.55)';
    var barLine = '#374151';
    var arcColor = '#3b82f6';
    var dimColor = '#6b7280';

    // Generate arc points array [[x,y], ...]
    function arc(cx, cy, radius, startDeg, endDeg, n) {
        var pts = [];
        for (var i = 0; i <= n; i++) {
            var a = (startDeg + i * (endDeg - startDeg) / n) * Math.PI / 180;
            pts.push([cx + radius * Math.cos(a), cy + radius * Math.sin(a)]);
        }
        return pts;
    }

    // Push array of [x,y] points into separate x/y arrays
    function pushPts(xArr, yArr, pts) {
        for (var i = 0; i < pts.length; i++) {
            xArr.push(pts[i][0]);
            yArr.push(pts[i][1]);
        }
    }

    // Build single continuous bar polygon and centerline per angle
    var polyX = [], polyY = [];
    // Bend center for all angles: (ldh, -R)
    var cx = ldh, cy = -R;
    var nArc = 40;

    if (angle === 90) {
        // Outer path (clockwise): top of horiz → outer bend → right of vert → bottom cap
        polyX.push(0); polyY.push(hw);
        polyX.push(ldh); polyY.push(hw);
        pushPts(polyX, polyY, arc(cx, cy, R + hw, 90, 0, nArc));
        polyX.push(cx + R + hw); polyY.push(cy);
        polyX.push(cx + R + hw); polyY.push(cy - lext);
        // Bottom cap of vertical bar
        polyX.push(cx + R - hw); polyY.push(cy - lext);
        // Inner path (counter-clockwise): left of vert → inner bend → bottom of horiz
        polyX.push(cx + R - hw); polyY.push(cy);
        pushPts(polyX, polyY, arc(cx, cy, Math.max(R - hw, 1), 0, 90, nArc));
        polyX.push(ldh); polyY.push(-hw);
        polyX.push(0); polyY.push(-hw);
        // Close
        polyX.push(0); polyY.push(hw);

        // Centerline arc
        var cl = arc(cx, cy, R, 90, 0, nArc);
        traces.push({
            x: cl.map(function(p){return p[0]}), y: cl.map(function(p){return p[1]}),
            mode: 'lines', line: { color: arcColor, width: 1.5, dash: 'dash' },
            hoverinfo: 'skip', showlegend: false,
        });

        // Reference circle (dotted)
        var ref = arc(cx, cy, R, 0, 360, 80);
        traces.push({
            x: ref.map(function(p){return p[0]}), y: ref.map(function(p){return p[1]}),
            mode: 'lines', line: { color: arcColor, width: 0.8, dash: 'dot' },
            hoverinfo: 'skip', showlegend: false,
        });

        // Dimensions
        // ldh
        traces.push({ x: [0, 0, ldh, ldh], y: [hw + D*0.25, hw + D*0.18, hw + D*0.18, hw + D*0.25], mode: 'lines', line: { color: dimColor, width: 1 }, hoverinfo: 'skip', showlegend: false });
        annotations.push({ x: ldh/2, y: hw + D*0.18, text: 'l<sub>dh</sub> = ' + ldh + ' mm', showarrow: false, font: { size: 11, color: dimColor }, yshift: 14, bgcolor: 'rgba(255,255,255,0.9)' });
        // lext
        var vr = cx + R + hw + D*0.15;
        traces.push({ x: [vr, vr], y: [cy, cy - lext], mode: 'lines', line: { color: dimColor, width: 1 }, hoverinfo: 'skip', showlegend: false });
        traces.push({ x: [cx+R+hw, vr+D*0.05], y: [cy, cy], mode: 'lines', line: { color: dimColor, width: 0.7 }, hoverinfo: 'skip', showlegend: false });
        traces.push({ x: [cx+R+hw, vr+D*0.05], y: [cy-lext, cy-lext], mode: 'lines', line: { color: dimColor, width: 0.7 }, hoverinfo: 'skip', showlegend: false });
        annotations.push({ x: vr, y: cy - lext/2, text: 'l<sub>ext</sub> = ' + lext + ' mm', showarrow: false, font: { size: 11, color: dimColor }, xshift: 16, bgcolor: 'rgba(255,255,255,0.9)' });
        // D
        annotations.push({ x: cx, y: cy, text: 'D = ' + D + ' mm', showarrow: true, arrowhead: 0, ax: -60, ay: 25, font: { size: 11, color: arcColor }, arrowcolor: arcColor });

    } else if (angle === 180) {
        // Outer path: top of horiz → outer semicircle → bottom of return → left cap
        polyX.push(0); polyY.push(hw);
        polyX.push(ldh); polyY.push(hw);
        pushPts(polyX, polyY, arc(cx, cy, R + hw, 90, -90, nArc));
        // Bottom of return bar going left
        polyX.push(ldh); polyY.push(-2*R - hw);
        polyX.push(ldh - lext); polyY.push(-2*R - hw);
        // Left cap of return bar
        polyX.push(ldh - lext); polyY.push(-2*R + hw);
        // Top of return bar going right
        polyX.push(ldh); polyY.push(-2*R + hw);
        // Inner semicircle going back up
        pushPts(polyX, polyY, arc(cx, cy, Math.max(R - hw, 1), -90, 90, nArc));
        // Bottom of horizontal bar going left
        polyX.push(ldh); polyY.push(-hw);
        polyX.push(0); polyY.push(-hw);
        // Close
        polyX.push(0); polyY.push(hw);

        // Centerline arc
        var cl = arc(cx, cy, R, 90, -90, nArc);
        traces.push({
            x: cl.map(function(p){return p[0]}), y: cl.map(function(p){return p[1]}),
            mode: 'lines', line: { color: arcColor, width: 1.5, dash: 'dash' },
            hoverinfo: 'skip', showlegend: false,
        });

        // Dimensions
        // ldh
        traces.push({ x: [0, 0, ldh, ldh], y: [hw + D*0.25, hw + D*0.18, hw + D*0.18, hw + D*0.25], mode: 'lines', line: { color: dimColor, width: 1 }, hoverinfo: 'skip', showlegend: false });
        annotations.push({ x: ldh/2, y: hw + D*0.18, text: 'l<sub>dh</sub> = ' + ldh + ' mm', showarrow: false, font: { size: 11, color: dimColor }, yshift: 14, bgcolor: 'rgba(255,255,255,0.9)' });
        // D (right side)
        var dr = ldh + R + hw + D*0.15;
        traces.push({ x: [dr, dr], y: [0, -2*R], mode: 'lines', line: { color: dimColor, width: 1 }, hoverinfo: 'skip', showlegend: false });
        traces.push({ x: [ldh + R + hw, dr + D*0.05], y: [0, 0], mode: 'lines', line: { color: dimColor, width: 0.7 }, hoverinfo: 'skip', showlegend: false });
        traces.push({ x: [ldh + R + hw, dr + D*0.05], y: [-2*R, -2*R], mode: 'lines', line: { color: dimColor, width: 0.7 }, hoverinfo: 'skip', showlegend: false });
        annotations.push({ x: dr, y: -R, text: 'D = ' + D + ' mm', showarrow: false, font: { size: 11, color: arcColor }, xshift: 16, bgcolor: 'rgba(255,255,255,0.9)' });
        // lext
        var lb = -2*R - hw - D*0.15;
        traces.push({ x: [ldh - lext, ldh - lext, ldh, ldh], y: [lb - D*0.07, lb, lb, lb - D*0.07], mode: 'lines', line: { color: dimColor, width: 1 }, hoverinfo: 'skip', showlegend: false });
        annotations.push({ x: ldh - lext/2, y: lb, text: 'l<sub>ext</sub> = ' + lext + ' mm', showarrow: false, font: { size: 11, color: dimColor }, yshift: -14, bgcolor: 'rgba(255,255,255,0.9)' });

    } else {
        // 135° hook
        // Bend goes from 90° to -45° (total 135° of bend)
        // Extension direction: tangent at -45° on the clockwise arc = angle -135° from +x
        var tailAng = -135 * Math.PI / 180;
        var tailStartX = cx + R * Math.cos(-45 * Math.PI / 180);
        var tailStartY = cy + R * Math.sin(-45 * Math.PI / 180);
        var tailEndX = tailStartX + lext * Math.cos(tailAng);
        var tailEndY = tailStartY + lext * Math.sin(tailAng);

        // Perpendicular to tail direction for bar width offset
        var perpAng = tailAng + Math.PI / 2;
        var px = hw * Math.cos(perpAng);
        var py = hw * Math.sin(perpAng);

        // Outer path: top of horiz → outer bend → outer side of tail → end cap
        polyX.push(0); polyY.push(hw);
        polyX.push(ldh); polyY.push(hw);
        pushPts(polyX, polyY, arc(cx, cy, R + hw, 90, -45, nArc));
        // Outer side of tail (offset by +perp)
        polyX.push(tailStartX + px); polyY.push(tailStartY + py);
        polyX.push(tailEndX + px); polyY.push(tailEndY + py);
        // End cap
        polyX.push(tailEndX - px); polyY.push(tailEndY - py);
        // Inner side of tail
        polyX.push(tailStartX - px); polyY.push(tailStartY - py);
        // Inner bend
        pushPts(polyX, polyY, arc(cx, cy, Math.max(R - hw, 1), -45, 90, nArc));
        // Bottom of horiz bar
        polyX.push(ldh); polyY.push(-hw);
        polyX.push(0); polyY.push(-hw);
        // Close
        polyX.push(0); polyY.push(hw);

        // Centerline arc
        var cl = arc(cx, cy, R, 90, -45, nArc);
        traces.push({
            x: cl.map(function(p){return p[0]}), y: cl.map(function(p){return p[1]}),
            mode: 'lines', line: { color: arcColor, width: 1.5, dash: 'dash' },
            hoverinfo: 'skip', showlegend: false,
        });

        // Reference circle (dotted)
        var ref = arc(cx, cy, R, 0, 360, 80);
        traces.push({
            x: ref.map(function(p){return p[0]}), y: ref.map(function(p){return p[1]}),
            mode: 'lines', line: { color: arcColor, width: 0.8, dash: 'dot' },
            hoverinfo: 'skip', showlegend: false,
        });

        // Dimensions
        // ldh
        traces.push({ x: [0, 0, ldh, ldh], y: [hw + D*0.25, hw + D*0.18, hw + D*0.18, hw + D*0.25], mode: 'lines', line: { color: dimColor, width: 1 }, hoverinfo: 'skip', showlegend: false });
        annotations.push({ x: ldh/2, y: hw + D*0.18, text: 'l<sub>dh</sub> = ' + ldh + ' mm', showarrow: false, font: { size: 11, color: dimColor }, yshift: 14, bgcolor: 'rgba(255,255,255,0.9)' });
        // D
        annotations.push({ x: cx, y: cy, text: 'D = ' + D + ' mm', showarrow: true, arrowhead: 0, ax: -60, ay: 25, font: { size: 11, color: arcColor }, arrowcolor: arcColor });
        // lext along tail
        var midTX = (tailStartX + tailEndX) / 2;
        var midTY = (tailStartY + tailEndY) / 2;
        annotations.push({ x: midTX, y: midTY, text: 'l<sub>ext</sub> = ' + lext + ' mm', showarrow: true, arrowhead: 0, ax: 45, ay: -25, font: { size: 11, color: dimColor }, arrowcolor: dimColor, bgcolor: 'rgba(255,255,255,0.9)' });
    }

    // Add bar polygon as first trace (drawn behind everything)
    traces.unshift({
        x: polyX, y: polyY, fill: 'toself',
        fillcolor: barFill,
        line: { color: barLine, width: 1.5 },
        mode: 'lines', hoverinfo: 'skip', showlegend: false,
    });

    var layout = {
        title: { text: angle + '\u00b0 Hook \u2014 \u2300' + db + ' mm', font: { size: 14 } },
        xaxis: {
            scaleanchor: 'y', scaleratio: 1,
            showgrid: false, zeroline: false, showticklabels: false,
        },
        yaxis: {
            showgrid: false, zeroline: false, showticklabels: false,
        },
        annotations: annotations,
        height: 450,
        margin: { t: 45, r: 40, b: 30, l: 40 },
        plot_bgcolor: '#fff', paper_bgcolor: '#fff',
        hovermode: false,
        dragmode: 'pan',
    };

    var config = { responsive: true, displayModeBar: true, modeBarButtonsToRemove: ['lasso2d','select2d','autoScale2d'], displaylogo: false, scrollZoom: true };
    Plotly.newPlot('chart-hook', traces, layout, config);
}

document.getElementById('calc-form').addEventListener('submit', function(e) {
    e.preventDefault();
    var payload = {
        bar_type: this.bar_type.value,
        bar_size: parseFloat(this.bar_size.value),
        angle: parseInt(this.angle.value),
    };
    submitCalc('/api/section/development-length', payload, function(result) {
        renderHookChart(result);

        var r = result;
        var tex = '<h3>Calculation Report</h3><div class="mathjax-report">';
        tex += '<p><b>Reference:</b> NSCP 2015 Section 425</p>';
        tex += '<p><b>Bar:</b> \\( \\varnothing ' + r.bar_size + ' \\text{ mm} \\), Hook angle: \\( ' + r.angle + '^\\circ \\)</p>';
        tex += '<p>\\[ D_{bend} = ' + r.bend_diameter + ' \\text{ mm} \\]</p>';
        tex += '<p>\\[ l_{ext} = ' + r.lext + ' \\text{ mm} \\]</p>';
        tex += '<p>\\[ l_{dh} = D_{bend} + l_{ext} = ' + r.bend_diameter + ' + ' + r.lext + ' = ' + r.ldh + ' \\text{ mm} \\]</p>';
        tex += '</div>';
        document.getElementById('results-report').innerHTML = tex;
        if (window.MathJax) MathJax.typeset();
    });
});
</script>
{% endblock %}
