{% extends "base.html" %}

{% block title %}Pigeonhole Principle Simulation{% endblock %}

{% block content %}
<div class="max-w-screen grid grid-cols-1 items-center divide-y p-6">
    <div class="flex flex-col justify-center text-center">
        <h1 class="text-3xl font-bold mb-4">Pigeonhole Principle Simulation</h1>
        <p class="text-lg text-gray-700 dark:text-gray-300 mb-2">
            If we place 5 dots in a square of side length $s$, there must be at least two dots whose distance $d$
            satisfies:
            $$ d < \frac{s}{\sqrt{2}} $$ </p>
                <p class="text-md text-gray-600 dark:text-gray-400 mb-6">
                    (The user requested condition: "distance is smaller than square root of square ($s^2$)", which means
                    $d < \sqrt{s^2}=s$. Since $\frac{s}{\sqrt{2}} \approx 0.707 s < s$, the condition is always met if
                        the stronger Pigeonhole Principle holds.) </p>

                        <div class="flex justify-center mb-4">
                            <button onclick="generatePoints()"
                                class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition">
                                Generate New Points
                            </button>
                        </div>
    </div>

    <div class="flex flex-col items-center justify-center pt-6">
        <div class="relative">
            <canvas id="pigeonholeCanvas" width="500" height="500"
                class="border-2 border-gray-800 dark:border-gray-200 bg-white shadow-lg"></canvas>
            <div id="result-overlay"
                class="absolute top-2 left-2 bg-white/90 p-2 rounded shadow text-sm font-mono border hidden"></div>
        </div>
        <div id="stats" class="mt-4 text-center text-lg font-semibold min-h-[100px]"></div>
    </div>
</div>
{% endblock %}

{% block js %}
<script>
    window.MathJax = {
        tex: {
            inlineMath: [['$', '$'], ['\\(', '\\)']]
        }
    };
</script>
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>

<script>
    "use strict";

    const canvas = document.getElementById('pigeonholeCanvas');
    const ctx = canvas.getContext('2d');
    const statsDiv = document.getElementById('stats');
    const overlayDiv = document.getElementById('result-overlay');

    // Square dimensions (leaving some padding)
    const PADDING = 50;
    const SIDE = 400; // side length

    function drawSquare() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);

        // Draw the main square
        ctx.strokeStyle = '#333';
        ctx.lineWidth = 2;
        ctx.strokeRect(PADDING, PADDING, SIDE, SIDE);

        // Draw grid lines to visualize the quadrants (the proof concept)
        ctx.strokeStyle = '#ccc';
        ctx.setLineDash([5, 5]);
        ctx.lineWidth = 1;
        ctx.beginPath();
        ctx.moveTo(PADDING + SIDE / 2, PADDING);
        ctx.lineTo(PADDING + SIDE / 2, PADDING + SIDE);
        ctx.moveTo(PADDING, PADDING + SIDE / 2);
        ctx.lineTo(PADDING + SIDE, PADDING + SIDE / 2);
        ctx.stroke();
        ctx.setLineDash([]);
    }

    function generatePoints() {
        drawSquare();

        const points = [];
        for (let i = 0; i < 5; i++) {
            // Random x, y within the square
            const x = Math.random() * SIDE + PADDING;
            const y = Math.random() * SIDE + PADDING;
            points.push({ x, y, id: i });

            // Draw point
            ctx.fillStyle = '#ef4444'; // red-500
            ctx.beginPath();
            ctx.arc(x, y, 6, 0, Math.PI * 2);
            ctx.fill();

            // Label
            ctx.fillStyle = '#000';
            ctx.font = '12px sans-serif';
            ctx.fillText(i + 1, x + 8, y - 8);
        }

        findClosestPair(points);
    }

    function findClosestPair(points) {
        let minDist = Infinity;
        let p1 = null;
        let p2 = null;

        for (let i = 0; i < points.length; i++) {
            for (let j = i + 1; j < points.length; j++) {
                const dx = points[i].x - points[j].x;
                const dy = points[i].y - points[j].y;
                const dist = Math.sqrt(dx * dx + dy * dy);

                if (dist < minDist) {
                    minDist = dist;
                    p1 = points[i];
                    p2 = points[j];
                }
            }
        }

        // Highlight closest pair
        if (p1 && p2) {
            ctx.strokeStyle = '#2563eb'; // blue-600
            ctx.lineWidth = 3;
            ctx.beginPath();
            ctx.moveTo(p1.x, p1.y);
            ctx.lineTo(p2.x, p2.y);
            ctx.stroke();

            const limit = SIDE / Math.sqrt(2); // ~282.84 for SIDE=400

            // Generate Coordinate List
            let pointsHtml = `<div class="mt-4 text-left inline-block"><h3 class="font-bold text-center mb-2">Point Coordinates (relative to square)</h3><ul class="list-none space-y-1">`;
            points.forEach(p => {
                const isClosest = (p === p1 || p === p2);
                // Calculate relative coordinates
                const relX = (p.x - PADDING).toFixed(1);
                const relY = (p.y - PADDING).toFixed(1);
                const style = isClosest ? "color: #2563eb; font-weight: bold;" : "";
                const mark = isClosest ? "★ " : "&nbsp;&nbsp;";
                pointsHtml += `<li style="${style}" class="font-mono text-sm">${mark}Point ${p.id + 1}: (${relX}, ${relY})</li>`;
            });
            pointsHtml += `</ul></div>`;

            // Using LaTeX for the dynamic output as well
            statsDiv.innerHTML = `
            <div>Closest Pair Distance: $d = ${minDist.toFixed(2)}$ px (between P${p1.id + 1} and P${p2.id + 1})</div>
            <div>Threshold: $\\frac{s}{\\sqrt{2}} \\approx ${limit.toFixed(2)}$ px</div>
            <div>Square Side: $s = ${SIDE}$ px</div>
            ${pointsHtml}
        `;

            if (minDist < SIDE) {
                statsDiv.innerHTML += `<div class="mt-2 text-green-600 font-bold">✔ $d < s$ (Requested Condition Holds)</div>`;
            }

            // Trigger MathJax re-render if available
            if (window.MathJax && window.MathJax.typesetPromise) {
                window.MathJax.typesetPromise([statsDiv]);
            }
        }
    }

    // Initial draw - wait for MathJax to load for the first text, 
    // but we can draw immediately, typesetting stats happens in findClosestPair
    generatePoints();

</script>
{% endblock %}