/* Pielgrzymka Edukacji Domowej — mapa modlitwy i szkół.
   ────────────────────────────────────────────────────────────────────────────
   Skrypt jest dodatkiem, nie warunkiem. Liczby, intencje, wykaz szkół i oba
   formularze są w HTML-u wysłanym z serwera — tutaj dochodzi rysunek mapy,
   podpowiedź diecezji i wysyłka bez przeładowania strony. Gdy skrypt się nie
   wczyta, strona nadal działa.

   Żadnych bibliotek z zewnątrz. Mapa to zwykły SVG budowany z kontury.json.
   ──────────────────────────────────────────────────────────────────────────── */
(function () {
  'use strict';

  var API = (window.PED && PED.rest) || '';
  var NONCE = (window.PED && PED.nonce) || '';
  var NAZWY = (window.PED && PED.diecezje) || {};

  /* ── drobiazgi ──────────────────────────────────────────────────────────── */
  function $(sel, gdzie) { return (gdzie || document).querySelector(sel); }
  function $$(sel, gdzie) { return Array.prototype.slice.call((gdzie || document).querySelectorAll(sel)); }
  function powiedz(el, tekst, rodzaj) {
    if (!el) return;
    el.textContent = tekst;
    el.className = el.className.replace(/\s*(blad|ok)\b/g, '') + (rodzaj ? ' ' + rodzaj : '');
  }
  /* Odmiana liczebników. Polszczyzna ma trzy formy, nie dwie: 1 świeca,
     2–4 świece, 5+ świec — z wyjątkiem 12–14, które idą jak 5. Bez tego
     w dymku wyświetla się „4 szkół” i całość wygląda na maszynową. */
  function odmien(n, formy) {
    if (n === 1) return formy[0];
    var d = n % 10, s = n % 100;
    return (d >= 2 && d <= 4 && (s < 12 || s > 14)) ? formy[1] : formy[2];
  }

  function wyslij(sciezka, dane) {
    return fetch(API + sciezka, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': NONCE },
      body: JSON.stringify(dane)
    }).then(function (o) { return o.json().then(function (j) { return { kod: o.status, tresc: j }; }); });
  }

  /* ── wersja kolorystyczna ───────────────────────────────────────────────── */
  /* Dwie wersje: ciemna (świeca w mroku) i jasna (bliżej strony pielgrzymki).
     Wybór zapamiętujemy w przeglądarce, żeby nie trzeba go było powtarzać przy
     każdym wejściu. Zmienia się tylko atrybut — style same wiedzą, co robić. */
  var KLUCZ_MOTYWU = 'ped-motyw';

  function bloki() { return $$('.ped, .ped-zglos, .ped-wykaz, .ped-piesn'); }

  function ustawMotyw(motyw) {
    bloki().forEach(function (b) {
      // Bloki zagnieżdżone dziedziczą barwy po nadrzędnym — atrybut zakłada
      // się tylko tym, które stoją samodzielnie.
      if (b.parentElement && b.parentElement.closest('.ped')) { return; }
      b.dataset.motyw = motyw;
    });
    $$('.ped-logo').forEach(function (logo) {
      var adres = motyw === 'jasny' ? logo.dataset.logoJasny : logo.dataset.logoCiemny;
      if (adres) logo.src = adres;
    });
    $$('.ped-motyw').forEach(function (p) {
      var znak = $('.ped-motyw-znak', p), napis = $('.ped-motyw-napis', p);
      if (znak) znak.textContent = motyw === 'jasny' ? '☾' : '☀';
      if (napis) napis.textContent = motyw === 'jasny' ? 'Ciemne tło' : 'Jasne tło';
      p.setAttribute('aria-label', motyw === 'jasny'
        ? 'Przełącz na ciemne tło' : 'Przełącz na jasne tło');
    });
    try { localStorage.setItem(KLUCZ_MOTYWU, motyw); } catch (e) { /* prywatne okno */ }
  }

  (function () {
    var zapisany = null;
    try { zapisany = localStorage.getItem(KLUCZ_MOTYWU); } catch (e) { /* prywatne okno */ }
    var pierwszy = $('.ped, .ped-zglos, .ped-wykaz, .ped-piesn');
    var start = zapisany || (pierwszy && pierwszy.dataset.motyw) || 'ciemny';
    ustawMotyw(start);

    $$('.ped-motyw').forEach(function (p) {
      p.addEventListener('click', function () {
        var teraz = (pierwszy && pierwszy.dataset.motyw) === 'jasny' ? 'ciemny' : 'jasny';
        ustawMotyw(teraz);
      });
    });
  })();

  /* ── mapa ───────────────────────────────────────────────────────────────── */
  var konturyObietnica = null;
  function kontury() {
    if (!konturyObietnica) {
      konturyObietnica = fetch(PED.kontury).then(function (o) { return o.json(); });
    }
    return konturyObietnica;
  }

  function zbudujMape(sekcja) {
    var plotno = $('.ped-mapa', sekcja);
    if (!plotno) return Promise.resolve(null);

    return kontury().then(function (k) {
      var svgNS = 'http://www.w3.org/2000/svg';
      var svg = document.createElementNS(svgNS, 'svg');
      svg.setAttribute('viewBox', k.viewBox);
      svg.setAttribute('role', 'img');
      svg.setAttribute('aria-label', 'Mapa diecezji Polski ze światłami modlitwy');

      // Miękka łuna wokół płomyka. Rysujemy ją gradientem, bo cień (drop-shadow)
      // przy tak dużym viewBoksie robi się albo niewidoczny, albo kosztowny.
      var defs = document.createElementNS(svgNS, 'defs');
      defs.innerHTML =
        '<radialGradient id="' + sekcja.id + '-luna">' +
        '<stop offset="0%" stop-color="#ffe08a" stop-opacity=".95"/>' +
        '<stop offset="45%" stop-color="#ffb524" stop-opacity=".45"/>' +
        '<stop offset="100%" stop-color="#ffb524" stop-opacity="0"/>' +
        '</radialGradient>';
      svg.appendChild(defs);

      var grupa = document.createElementNS(svgNS, 'g');
      grupa.setAttribute('transform', k.flip);
      svg.appendChild(grupa);

      var swiece = JSON.parse(sekcja.dataset.swiece || '{}');
      var szkoly = JSON.parse(sekcja.dataset.szkoly || '{}');
      var maks = parseInt(sekcja.dataset.maks, 10) || 0;
      var ksztalty = {};

      k.sciezki.forEach(function (p) {
        var el = document.createElementNS(svgNS, 'path');
        el.setAttribute('d', p.d);
        el.setAttribute('class', 'ped-diec');
        el.dataset.kod = p.kod;
        var ile = swiece[p.kod] || 0;
        if (ile > 0) {
          el.classList.add('pali');
          // Pierwiastek, nie proporcja wprost: gdyby jedna diecezja miała 500
          // świec, a reszta po pięć, przy proporcji wprost cała Polska poza nią
          // byłaby ciemna i mapa kłamałaby o zasięgu modlitwy.
          el.style.setProperty('--blask', maks ? Math.sqrt(ile / maks).toFixed(3) : '1');
        }
        grupa.appendChild(el);
        ksztalty[p.kod] = el;
      });

      plotno.innerHTML = '';
      plotno.appendChild(svg);

      // Środki obszarów liczymy dopiero po wstawieniu do dokumentu — wcześniej
      // getBBox() nie ma czego mierzyć.
      var srodki = {};
      Object.keys(ksztalty).forEach(function (kod) {
        var b = ksztalty[kod].getBBox();
        srodki[kod] = { x: b.x + b.width / 2, y: b.y + b.height / 2 };
      });

      // Znaczniki szkół — romb, którego bok rośnie z liczbą szkół w diecezji.
      Object.keys(szkoly).forEach(function (kod) {
        var s = srodki[kod];
        if (!s || !szkoly[kod]) return;
        // Bok rombu w jednostkach mapy. Przy szerokości viewBox ~37 000 i mapie
        // rysowanej na ~950 px jedna jednostka to ćwierć setnej piksela —
        // stąd wartości w setkach, a nie w dziesiątkach.
        var r = 400 + Math.min(szkoly[kod], 30) * 16;
        // Odsuwamy romb od środka: tam pali się świeca i dwa znaki w jednym
        // punkcie zasłaniałyby się nawzajem.
        var przesun = 560;
        var znak = document.createElementNS(svgNS, 'rect');
        znak.setAttribute('x', s.x + przesun - r / 2);
        znak.setAttribute('y', s.y - przesun - r / 2);
        znak.setAttribute('width', r);
        znak.setAttribute('height', r);
        znak.setAttribute('transform',
          'rotate(45 ' + (s.x + przesun) + ' ' + (s.y - przesun) + ')');
        znak.setAttribute('class', 'ped-szkola-znak');
        znak.dataset.kod = kod;
        znak.dataset.szkol = szkoly[kod];
        grupa.appendChild(znak);
      });

      // Po jednym światełku na świecę, rozsianym po terenie diecezji.
      var plomyki = {};
      Object.keys(ksztalty).forEach(function (kod) {
        if (!swiece[kod]) return;
        var ile = Math.min(swiece[kod], MAKS_PLOMYKOW);
        var moc = maks ? Math.sqrt(swiece[kod] / maks) : 1;
        plomyki[kod] = punktyWDiecezji(svg, ksztalty[kod], ile, kod)
          .map(function (pkt) { return dorysujPlomyk(grupa, pkt, sekcja.id, moc); });
      });

      podepnijDymek(plotno, svg, swiece, szkoly);
      podepnijKlikanie(sekcja, svg, swiece, szkoly);

      return { svg: svg, grupa: grupa, ksztalty: ksztalty, srodki: srodki,
               plomyki: plomyki, affine: k.affine, plotno: plotno };
    }).catch(function () {
      // Brak konturów nie może wywrócić strony — formularz ma dalej działać.
      plotno.hidden = true;
      return null;
    });
  }

  /* Ile świateł najwyżej pokazujemy w jednej diecezji. Powyżej tej liczby
     mapa robi się plamą, a plama nie mówi już nic więcej niż dziesięć punktów. */
  var MAKS_PLOMYKOW = 14;

  /* Prosty generator liczb „losowych” z ziarnem. Bierzemy go zamiast
     Math.random, żeby po odświeżeniu strony świece stały tam, gdzie stały —
     mapa, która przy każdym wejściu układa się inaczej, wygląda na zepsutą. */
  function ziarnistyLos(ziarno) {
    var x = 0;
    for (var i = 0; i < ziarno.length; i++) { x = (x * 31 + ziarno.charCodeAt(i)) | 0; }
    return function () {
      x = (x * 1103515245 + 12345) & 0x7fffffff;
      return x / 0x7fffffff;
    };
  }

  /* Punkty rozsiane po TERENIE diecezji, nie w jej środku. Losujemy w obrębie
     prostokąta opisanego na kształcie i odrzucamy te, które wypadły poza
     obrysem — inaczej świeca zapalałaby się w sąsiedniej diecezji albo w morzu. */
  function punktyWDiecezji(svg, ksztalt, ile, ziarno) {
    var b = ksztalt.getBBox();
    var los = ziarnistyLos(ziarno);
    var punkt = svg.createSVGPoint ? svg.createSVGPoint() : null;
    var wynik = [];
    var proby = 0;

    while (wynik.length < ile && proby < ile * 60) {
      proby++;
      var x = b.x + los() * b.width;
      var y = b.y + los() * b.height;
      if (punkt && ksztalt.isPointInFill) {
        punkt.x = x; punkt.y = y;
        if (!ksztalt.isPointInFill(punkt)) { continue; }
      }
      // Nie stawiamy dwóch świec jedna na drugiej.
      var zaBlisko = wynik.some(function (w) {
        return Math.abs(w.x - x) < b.width / 7 && Math.abs(w.y - y) < b.height / 7;
      });
      if (zaBlisko) { continue; }
      wynik.push({ x: x, y: y });
    }

    // Gdyby obrys okazał się nie do trafienia, zostaje środek — lepiej jedno
    // światło w przybliżonym miejscu niż żadne.
    if (!wynik.length) {
      wynik.push({ x: b.x + b.width / 2, y: b.y + b.height / 2 });
    }
    return wynik;
  }

  /* Płomień świecy na mapie. Sama zmiana barwy diecezji to za mało — człowiek,
     który właśnie zapalił światło, ma je ZOBACZYĆ, a nie domyślać się go
     z odcienia. */
  function dorysujPlomyk(grupa, srodek, idSekcji, moc) {
    var svgNS = 'http://www.w3.org/2000/svg';
    var g = document.createElementNS(svgNS, 'g');
    g.setAttribute('class', 'ped-plomyk');
    g.setAttribute('transform', 'translate(' + srodek.x + ' ' + srodek.y + ')');

    var luna = document.createElementNS(svgNS, 'circle');
    luna.setAttribute('r', 520 + moc * 420);
    luna.setAttribute('fill', 'url(#' + idSekcji + '-luna)');
    luna.setAttribute('class', 'ped-plomyk-luna');

    var punkt = document.createElementNS(svgNS, 'circle');
    punkt.setAttribute('r', 92 + moc * 60);
    punkt.setAttribute('class', 'ped-plomyk-punkt');

    g.appendChild(luna);
    g.appendChild(punkt);
    grupa.appendChild(g);
    return g;
  }

  function podepnijDymek(plotno, svg, swiece, szkoly) {
    var dymek = document.createElement('div');
    dymek.className = 'ped-dymek';
    dymek.hidden = true;
    plotno.appendChild(dymek);

    svg.addEventListener('mousemove', function (e) {
      var cel = e.target.closest('.ped-diec, .ped-szkola-znak');
      if (!cel) { dymek.hidden = true; return; }
      var kod = cel.dataset.kod;
      var s = swiece[kod] || 0, sz = szkoly[kod] || 0;
      dymek.innerHTML = '<b>' + (NAZWY[kod] || kod) + '</b><br>' +
        (s ? s + ' ' + odmien(s, ['zapalona świeca', 'zapalone świece', 'zapalonych świec'])
           : 'jeszcze nikt tu nie zapalił świecy') +
        (sz ? '<br>' + sz + ' ' + odmien(sz, ['szkoła przyjazna', 'szkoły przyjazne', 'szkół przyjaznych'])
              + ' edukacji domowej' : '');
      dymek.hidden = false;
      var pud = plotno.getBoundingClientRect();
      dymek.style.left = Math.min(e.clientX - pud.left + 14, pud.width - 250) + 'px';
      dymek.style.top = (e.clientY - pud.top + 14) + 'px';
    });
    svg.addEventListener('mouseleave', function () { dymek.hidden = true; });
  }

  /* Klik w diecezję robi dwie rzeczy: ustawia ją w formularzu i otwiera panel
     z jej szkołami. Dymek pod kursorem tego nie załatwia — na telefonie nie ma
     czym najechać, a to tam najczęściej otwiera się taką stronę. */
  function podepnijKlikanie(sekcja, svg, swiece, szkoly) {
    var panel = $('.ped-szczegoly', sekcja);

    svg.addEventListener('click', function (e) {
      var cel = e.target.closest('.ped-diec, .ped-szkola-znak');
      if (!cel) return;
      var kod = cel.dataset.kod;

      var wybor = $('.ped-diecezja', sekcja);
      if (wybor) {
        wybor.value = kod;
        powiedz($('.ped-stanlok', sekcja), 'Wybrano: ' + (NAZWY[kod] || kod));
      }
      pokazSzczegoly(panel, kod, swiece[kod] || 0);
    });

    var zamknij = $('.ped-szczegoly-zamknij', sekcja);
    if (zamknij) zamknij.addEventListener('click', function () { panel.hidden = true; });
  }

  function pokazSzczegoly(panel, kod, ileSwiec) {
    if (!panel) return;
    var lista = ((window.PED && PED.szkolyWg) || {})[kod] || [];

    $('.ped-szczegoly-tytul', panel).textContent = NAZWY[kod] || kod;
    var licznik = $('.ped-szczegoly-swiece', panel);
    if (ileSwiec === null) {
      licznik.textContent = 'Twoje światło już się tu pali.';
    } else if (ileSwiec) {
      licznik.textContent = ileSwiec + ' ' +
        odmien(ileSwiec, ['zapalona świeca', 'zapalone świece', 'zapalonych świec']);
    } else {
      licznik.textContent = 'Jeszcze nikt tu nie zapalił świecy — możesz być pierwszy.';
    }

    var gdzie = $('.ped-szczegoly-szkoly', panel);
    if (!lista.length) {
      gdzie.innerHTML = '<p class="ped-szczegoly-pusto">W tej diecezji nie mamy jeszcze '
        + 'żadnej szkoły przyjaznej edukacji domowej. Jeśli jakąś znasz — zgłoś ją '
        + 'formularzem poniżej.</p>';
    } else {
      var naglowek = '<p class="ped-szczegoly-ile">' + lista.length + ' '
        + odmien(lista.length, ['szkoła przyjazna', 'szkoły przyjazne', 'szkół przyjaznych'])
        + ' edukacji domowej</p>';
      gdzie.innerHTML = naglowek + '<ul class="ped-szczegoly-lista">' +
        lista.map(function (s) {
          var kontakt = [];
          if (s.t) kontakt.push(bezpiecznie(s.t));
          if (s.e) kontakt.push('<a href="mailto:' + bezpiecznie(s.e) + '">' + bezpiecznie(s.e) + '</a>');
          if (s.w) kontakt.push('<a href="' + bezpiecznie(s.w) + '" target="_blank" rel="noopener nofollow">strona</a>');
          return '<li' + (s.x ? ' class="niepewna"' : '') + '>'
            + '<span class="ped-szcz-nazwa">' + bezpiecznie(s.n) + '</span>'
            + '<span class="ped-szcz-adres">' + bezpiecznie(s.m || '')
            + (s.a ? ', ' + bezpiecznie(s.a) : '') + '</span>'
            + (kontakt.length ? '<span class="ped-szcz-kontakt">' + kontakt.join(' · ') + '</span>' : '')
            + (s.x ? '<span class="ped-szcz-uwaga">diecezja do potwierdzenia</span>' : '')
            + '</li>';
        }).join('') + '</ul>';
    }

    panel.hidden = false;
  }

  /* Nazwy szkół i adresy pochodzą z bazy, którą uzupełniają ludzie z zewnątrz.
     Wstawiamy je do HTML-u, więc każdy znak specjalny musi zostać znakiem,
     a nie znacznikiem. */
  function bezpiecznie(t) {
    return String(t).replace(/[&<>"']/g, function (z) {
      return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[z];
    });
  }

  /* ── podpowiedź diecezji z położenia ────────────────────────────────────── */
  /* Współrzędne zostają w przeglądarce. Zamieniamy je na punkt mapy odwrotnym
     przekształceniem afinicznym i sprawdzamy, w którym obrysie leży. */
  function podpowiedzDiecezje(mapa, lat, lon) {
    var a = mapa.affine;
    var det = a[0] * a[4] - a[1] * a[3];
    var dl = lon - a[2], ds = lat - a[5];
    var x = (a[4] * dl - a[1] * ds) / det;
    var y = (-a[3] * dl + a[0] * ds) / det;

    var punkt = mapa.svg.createSVGPoint ? mapa.svg.createSVGPoint() : null;
    if (punkt) {
      punkt.x = x; punkt.y = y;
      for (var kod in mapa.ksztalty) {
        var el = mapa.ksztalty[kod];
        if (el.isPointInFill && el.isPointInFill(punkt)) return kod;
      }
    }
    // Nikt nie trafił w obrys (granica, morze, błąd pomiaru) — bierzemy najbliższy środek.
    var naj = null, najD = Infinity;
    Object.keys(mapa.srodki).forEach(function (kod) {
      var s = mapa.srodki[kod];
      var d = (s.x - x) * (s.x - x) + (s.y - y) * (s.y - y);
      if (d < najD) { najD = d; naj = kod; }
    });
    return naj;
  }

  /* ── udostępnianie ──────────────────────────────────────────────────────── */
  function przygotujUdostepnianie(sekcja, dane) {
    var pole = $('.ped-udostepnij', sekcja);
    if (!pole) return;
    pole.hidden = false;

    var adres = window.location.href.split('#')[0];
    var tekst = 'Zapaliłem/am świecę w intencji rodzin na Pielgrzymce Edukacji Domowej' +
      (dane.diecezja ? ' — ' + dane.diecezja : '') + '. ' +
      (dane.fragment ? '„' + dane.fragment.tekst + '” (' + dane.fragment.sigla + ') ' : '') +
      'Dołącz do modlitwy: ' + adres;

    var fb = $('.ped-fb', pole);
    if (fb) fb.href = 'https://www.facebook.com/sharer/sharer.php?u=' + encodeURIComponent(adres);

    var kopiuj = $('.ped-kopiuj', pole);
    if (kopiuj) kopiuj.onclick = function () {
      var gotowe = function () { powiedz($('.ped-udost-info', pole), 'Skopiowane — wklej w Instagramie.', 'ok'); };
      if (navigator.clipboard) { navigator.clipboard.writeText(tekst).then(gotowe, awaryjneKopiowanie); }
      else { awaryjneKopiowanie(); }
      function awaryjneKopiowanie() {
        var p = document.createElement('textarea');
        p.value = tekst; p.style.position = 'fixed'; p.style.opacity = '0';
        document.body.appendChild(p); p.select();
        try { document.execCommand('copy'); gotowe(); }
        catch (e) { powiedz($('.ped-udost-info', pole), 'Zaznacz i skopiuj: ' + tekst); }
        document.body.removeChild(p);
      }
    };

    var obraz = $('.ped-pobierz', pole);
    if (obraz) obraz.onclick = function () { rysujObrazek(dane, $('.ped-udost-info', pole)); };
  }

  /* Kwadrat 1080×1080 — format, który Instagram przyjmuje bez przycinania.
     Znak pielgrzymki wczytujemy najpierw; gdyby się nie wczytał, rysujemy resztę
     bez niego, bo obrazek bez logo jest lepszy niż przycisk, który nic nie robi. */
  function rysujObrazek(dane, info) {
    var znak = new Image();
    znak.onload = function () { maluj(znak); };
    znak.onerror = function () { maluj(null); };
    znak.src = (window.PED && PED.logo) || '';
    if (!znak.src) { maluj(null); }

    function maluj(logo) {
    var b = 1080, p = document.createElement('canvas');
    p.width = b; p.height = b;
    var c = p.getContext('2d');

    var tlo = c.createLinearGradient(0, 0, b, b);
    tlo.addColorStop(0, '#ffffff'); tlo.addColorStop(1, '#e6edf6');
    c.fillStyle = tlo; c.fillRect(0, 0, b, b);

    // Złota poświata za znakiem — ta sama, którą na mapie ma zapalona diecezja.
    var plomien = c.createRadialGradient(b / 2, 300, 10, b / 2, 300, 330);
    plomien.addColorStop(0, 'rgba(253,200,69,.42)');
    plomien.addColorStop(1, 'rgba(253,200,69,0)');
    c.fillStyle = plomien; c.beginPath(); c.arc(b / 2, 300, 330, 0, 6.284); c.fill();

    if (logo) {
      var szer = 430, wys = szer * logo.height / logo.width;
      c.drawImage(logo, (b - szer) / 2, 300 - wys / 2, szer, wys);
    } else {
      c.fillStyle = '#fdc845'; c.beginPath(); c.arc(b / 2, 300, 30, 0, 6.284); c.fill();
      c.textAlign = 'center'; c.fillStyle = '#2b84be';
      c.font = '700 26px system-ui, sans-serif';
      c.fillText('PIELGRZYMKA EDUKACJI DOMOWEJ', b / 2, 400);
    }

    c.textAlign = 'center';
    c.fillStyle = '#093e7a'; c.font = '700 48px Georgia, serif';
    c.fillText('Modlimy się razem', b / 2, 620);

    if (dane.fragment) {
      c.font = 'italic 31px Georgia, serif'; c.fillStyle = '#14508f';
      zawin(c, '„' + dane.fragment.tekst + '”', b / 2, 700, b - 200, 42, 4);
      c.font = '700 25px system-ui, sans-serif'; c.fillStyle = '#2b84be';
      c.fillText(dane.fragment.sigla, b / 2, 900);
    }

    c.fillStyle = '#fdc845'; c.fillRect(b / 2 - 60, 950, 120, 3);
    c.font = '600 28px system-ui, sans-serif'; c.fillStyle = '#093e7a';
    c.fillText((dane.stat ? dane.stat.swiec : '') + ' zapalonych świec · ' +
               (dane.stat ? dane.stat.diecezji : '') + ' diecezji', b / 2, 1010);

    p.toBlob(function (plik) {
      var url = URL.createObjectURL(plik);
      var a = document.createElement('a');
      a.href = url; a.download = 'pielgrzymka-modlitwa.png';
      document.body.appendChild(a); a.click(); document.body.removeChild(a);
      setTimeout(function () { URL.revokeObjectURL(url); }, 4000);
      powiedz(info, 'Obrazek pobrany — gotowy do wstawienia.', 'ok');
    });
    }
  }

  function zawin(c, tekst, x, y, szer, wys, maks) {
    var slowa = tekst.split(' '), linia = '', linie = [];
    slowa.forEach(function (s) {
      var proba = linia ? linia + ' ' + s : s;
      if (c.measureText(proba).width > szer && linia) { linie.push(linia); linia = s; }
      else { linia = proba; }
    });
    linie.push(linia);
    linie.slice(0, maks).forEach(function (l, i) { c.fillText(l, x, y + i * wys); });
  }

  /* ── obsługa sekcji z mapą ──────────────────────────────────────────────── */
  $$('.ped').forEach(function (sekcja) {
    var mapaGotowa = zbudujMape(sekcja);

    var lok = $('.ped-lok', sekcja);
    if (lok) lok.addEventListener('click', function () {
      var stan = $('.ped-stanlok', sekcja);
      if (!navigator.geolocation) { powiedz(stan, 'Przeglądarka nie umie wskazać położenia — wybierz z listy.', 'blad'); return; }
      powiedz(stan, 'Szukam…');
      navigator.geolocation.getCurrentPosition(function (poz) {
        mapaGotowa.then(function (mapa) {
          if (!mapa) { powiedz(stan, 'Wybierz diecezję z listy.', 'blad'); return; }
          var kod = podpowiedzDiecezje(mapa, poz.coords.latitude, poz.coords.longitude);
          var wybor = $('.ped-diecezja', sekcja);
          if (kod && wybor) {
            wybor.value = kod;
            powiedz(stan, 'Podpowiadam: ' + (NAZWY[kod] || kod) + '. Możesz zmienić.', 'ok');
          } else {
            powiedz(stan, 'Nie rozpoznałem okolicy — wybierz z listy.', 'blad');
          }
        });
      }, function (blad) {
        // Rozróżniamy odmowę od awarii — „nie udało się” niczego nie tłumaczy,
        // a człowiek nie wie, czy ma czekać, czy klikać dalej.
        var tresc = 'Nie udało się ustalić okolicy — wybierz swoje strony z listy.';
        if (blad && blad.code === 1) {
          tresc = 'Przeglądarka nie pozwoliła odczytać położenia. '
                + 'Nic nie szkodzi — wybierz swoje strony z listy obok.';
        } else if (blad && blad.code === 3) {
          tresc = 'Ustalanie okolicy trwa zbyt długo — wybierz swoje strony z listy.';
        }
        powiedz(stan, tresc, 'blad');
      }, { timeout: 8000, maximumAge: 600000 });
    });

    var form = $('.ped-form', sekcja);
    if (!form) return;
    /* Podpinamy się i pod kliknięcie przycisku, i pod wysłanie formularza.
       Samo wysłanie formularza nie wystarcza: strona umieszczona w ramce
       o ograniczonych prawach (a tak wyświetla się m.in. podgląd) ma
       wysyłanie formularzy zablokowane i przycisk milczy. Kliknięcia
       zablokować się nie da. */
    var zapal = function (e) {
      if (e) e.preventDefault();
      var info = $('.ped-info', sekcja);
      var przycisk = $('.ped-zapal', sekcja);
      var kod = $('.ped-diecezja', sekcja).value;
      var intencjaTeraz = $('.ped-intencja', sekcja).value.trim();
      if (!kod) { powiedz(info, 'Wybierz diecezję — mapa musi wiedzieć, gdzie zapalić światło.', 'blad'); return; }

      przycisk.disabled = true;
      powiedz(info, 'Zapalam…');

      wyslij('swieca', {
        diecezja: kod,
        imie: $('.ped-imie', sekcja).value,
        intencja: $('.ped-intencja', sekcja).value,
        watek: sekcja.dataset.watek || '',
        poprzedni: sekcja.dataset.ostatniaSigla || ''
      }).then(function (o) {
        przycisk.disabled = false;
        if (!o.tresc || !o.tresc.ok) {
          powiedz(info, (o.tresc && o.tresc.blad) || 'Nie udało się zapalić świecy. Spróbuj za chwilę.', 'blad');
          return;
        }
        powiedz(info, 'Świeca się pali. Dziękujemy za modlitwę.', 'ok');

        if (o.tresc.fragment) { pokazSlowo(sekcja, o.tresc.fragment, intencjaTeraz); }

        dopiszDoPaska(sekcja, intencjaTeraz, $('.ped-imie', sekcja).value.trim(),
                      o.tresc.diecezja);
        var decyzja = $('.ped-decyzja', sekcja);
        if (decyzja) { decyzja.hidden = false; }
        odswiezLiczby(sekcja, o.tresc.stat);
        rozjasnij(sekcja, kod);
        mapaGotowa.then(function (mapa) { zapalPlomyk(mapa, sekcja, kod); });
        przygotujUdostepnianie(sekcja, {
          diecezja: o.tresc.diecezja, fragment: o.tresc.fragment, stat: o.tresc.stat
        });
        $('.ped-intencja', sekcja).value = '';
      }).catch(function () {
        przycisk.disabled = false;
        powiedz(info, 'Brak połączenia. Spróbuj jeszcze raz.', 'blad');
      });
    };

    $('.ped-zapal', sekcja).addEventListener('click', zapal);
    form.addEventListener('submit', zapal);

    // Prośba o słowo dla kogoś konkretnego. Nie zapala drugiej świecy —
    // modlitwa za żonę i za dzieci to nadal jedna obecność przed Bogiem.
    $$('.ped-prosba', sekcja).forEach(function (przycisk) {
      przycisk.addEventListener('click', function () {
        var info = $('.ped-prosby-info', sekcja);
        $$('.ped-prosba', sekcja).forEach(function (b) { b.disabled = true; });
        powiedz(info, 'Szukam słowa…');

        wyslij('slowo', {
          dla: przycisk.dataset.dla,
          watek: sekcja.dataset.watek || '',
          poprzedni: sekcja.dataset.ostatniaSigla || ''
        }).then(function (o) {
          $$('.ped-prosba', sekcja).forEach(function (b) { b.disabled = false; });
          if (!o.tresc || !o.tresc.ok) {
            powiedz(info, (o.tresc && o.tresc.blad) || 'Spróbuj jeszcze raz.', 'blad');
            return;
          }
          powiedz(info, '');
          pokazSlowo(sekcja, o.tresc.fragment);
        }).catch(function () {
          $$('.ped-prosba', sekcja).forEach(function (b) { b.disabled = false; });
          powiedz(info, 'Brak połączenia. Spróbuj jeszcze raz.', 'blad');
        });
      });
    });
  });

  /* Słowo pokazujemy w jednym miejscu — obok mapy. Za każdym razem dajemy mu
     chwilę pulsowania: fragment, który pojawia się bezszelestnie, umyka oku,
     a ten ma zostać przeczytany i zapamiętany. */
  function pokazSlowo(sekcja, fragment, intencja) {
    var slowo = $('.ped-slowo', sekcja);
    if (!slowo || !fragment) return;

    var mojaInt = $('.ped-moja-intencja', slowo);
    if (mojaInt && intencja) {
      mojaInt.innerHTML = '<span>W Twojej intencji:</span> ' + bezpiecznie(intencja);
      mojaInt.hidden = false;
    }
    var zacheta = $('.ped-slowo-zacheta', slowo);
    var tresc = $('.ped-slowo-tresc', slowo);
    if (zacheta) zacheta.hidden = true;

    $('.ped-slowo-tekst', slowo).textContent = '„' + fragment.tekst + '”';
    $('.ped-slowo-sigla', slowo).textContent = fragment.sigla;
    tresc.hidden = false;

    var prosby = $('.ped-prosby', slowo);
    if (prosby) prosby.hidden = false;

    slowo.classList.remove('swieze');
    void slowo.getBoundingClientRect();
    slowo.classList.add('swieze');

    sekcja.dataset.ostatniaSigla = fragment.sigla;
  }

  /* Świeżo dopisana intencja ląduje na początku paska u góry — człowiek ma
     zobaczyć swoją obok cudzych, a nie dopiero po odświeżeniu strony. */
  function dopiszDoPaska(sekcja, intencja, imie, diecezja) {
    if (!intencja) return;
    var lista = $('.ped-pasek-lista', sekcja);
    if (!lista) return;
    var li = document.createElement('li');
    li.className = 'swieza';
    li.innerHTML = '<span class="ped-int-tresc">' + bezpiecznie(intencja) + '</span>'
                 + '<span class="ped-int-kto">' + bezpiecznie(imie ? imie + ' · ' : '')
                 + bezpiecznie(diecezja || '') + '</span>';
    lista.insertBefore(li, lista.firstChild);
    while (lista.children.length > 10) { lista.removeChild(lista.lastChild); }
  }

  function odswiezLiczby(sekcja, stat) {
    if (!stat) return;
    var pola = $$('.ped-liczba strong', sekcja);
    var kolejno = [stat.swiec, stat.dzis, stat.diecezji, stat.zIntencja];
    pola.forEach(function (el, i) {
      if (kolejno[i] !== undefined) el.textContent = kolejno[i].toLocaleString('pl-PL');
    });
  }

  function rozjasnij(sekcja, kod) {
    var el = $('.ped-diec[data-kod="' + kod + '"]', sekcja);
    if (!el) return;
    el.classList.add('pali');
    var teraz = parseFloat(el.style.getPropertyValue('--blask')) || 0;
    // Świeca, która ledwie zmienia barwę, wygląda jak świeca niezapalona.
    // Własne światło ma być widać od razu, niezależnie od tego, ile świec
    // pali się gdzie indziej — stąd dolna granica, a nie sam przyrost.
    el.style.setProperty('--blask', Math.min(1, Math.max(teraz + 0.2, 0.62)).toFixed(3));
  }

  /* Każda nowa świeca zapala się w NOWYM miejscu diecezji. Ziarno bierzemy
     z liczby świateł, które już tam stoją — dzięki temu kolejne trafiają
     gdzie indziej, a nie w to samo miejsce co poprzednie. */
  function zapalPlomyk(mapa, sekcja, kod) {
    if (mapa && mapa.ksztalty[kod]) {
      if (!mapa.plomyki[kod]) { mapa.plomyki[kod] = []; }
      var lista = mapa.plomyki[kod];
      var nowy;

      if (lista.length < MAKS_PLOMYKOW) {
        var pkt = punktyWDiecezji(mapa.svg, mapa.ksztalty[kod], 1, kod + ':' + lista.length)[0];
        nowy = dorysujPlomyk(mapa.grupa, pkt, sekcja.id, 0.62);
        lista.push(nowy);
      } else {
        // Powyżej granicy nie dokładamy kolejnych punktów — rozjaśniamy ten,
        // który pali się najdłużej.
        nowy = lista[lista.length % MAKS_PLOMYKOW];
      }

      nowy.classList.remove('zaplon');
      void nowy.getBoundingClientRect();
      nowy.classList.add('zaplon');
    }
    pokazZapalenie(sekcja, kod);
  }

  /* Mapa bywa daleko nad przyciskiem — na telefonie po naciśnięciu „Zapal
     światło” jest kilka tysięcy pikseli wyżej i nie widać, że cokolwiek się
     stało. Przewijamy więc do mapy i dajemy diecezji wyraźny rozbłysk. */
  function pokazZapalenie(sekcja, kod) {
    var plansza = $('.ped-plansza', sekcja);
    var el = $('.ped-diec[data-kod="' + kod + '"]', sekcja);
    if (!plansza) return;

    var spokoj = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    try {
      plansza.scrollIntoView({ behavior: spokoj ? 'auto' : 'smooth', block: 'center' });
    } catch (e) {
      plansza.scrollIntoView();
    }

    if (el) {
      el.classList.remove('zaplon');
      void el.getBoundingClientRect();   // wymuszamy powtórzenie animacji
      el.classList.add('zaplon');
      setTimeout(function () { el.classList.remove('zaplon'); }, 2800);
    }

    var panel = $('.ped-szczegoly', sekcja);
    if (panel) { pokazSzczegoly(panel, kod, null); }
  }

  /* ── formularz zgłaszania szkół ─────────────────────────────────────────── */
  $$('.ped-zglos').forEach(function (sekcja) {
    var form = $('.ped-zglos-form', sekcja);
    if (!form) return;
    var polePoprawki = $('.ped-tylko-poprawka', sekcja);

    $$('input[type="radio"]', sekcja).forEach(function (r) {
      r.addEventListener('change', function () {
        if (polePoprawki) polePoprawki.hidden = (r.value !== 'poprawka');
      });
    });

    var przeslij = function (e) {
      if (e) e.preventDefault();
      var info = $('.ped-z-info', sekcja);
      var przycisk = $('.ped-wyslij', sekcja);
      if (przycisk.disabled) return;
      var nazwa = $('.ped-z-nazwa', sekcja).value.trim();
      if (nazwa.length < 3) { powiedz(info, 'Podaj nazwę szkoły — reszta może zostać pusta.', 'blad'); return; }

      var zaznaczony = $('input[type="radio"]:checked', sekcja);
      przycisk.disabled = true;
      powiedz(info, 'Wysyłam…');

      wyslij('zglos', {
        rodzaj: zaznaczony ? zaznaczony.value : 'nowa',
        nazwa: nazwa,
        dotyczy: ($('.ped-z-dotyczy', sekcja) || {}).value || '',
        miasto: $('.ped-z-miasto', sekcja).value,
        woj: $('.ped-z-woj', sekcja).value,
        adres: $('.ped-z-adres', sekcja).value,
        diecezja: $('.ped-z-diecezja', sekcja).value,
        telefon: $('.ped-z-telefon', sekcja).value,
        email: $('.ped-z-email', sekcja).value,
        www: $('.ped-z-www', sekcja).value,
        opis: $('.ped-z-opis', sekcja).value,
        zglaszajacy: $('.ped-z-kontakt', sekcja).value
      }).then(function (o) {
        przycisk.disabled = false;
        if (!o.tresc || !o.tresc.ok) {
          powiedz(info, (o.tresc && o.tresc.blad) || 'Nie udało się wysłać. Spróbuj za chwilę.', 'blad');
          return;
        }
        powiedz(info, o.tresc.komunikat, 'ok');
        form.reset();
        if (polePoprawki) polePoprawki.hidden = true;
      }).catch(function () {
        przycisk.disabled = false;
        powiedz(info, 'Brak połączenia. Spróbuj jeszcze raz.', 'blad');
      });
    };

    $('.ped-wyslij', sekcja).addEventListener('click', przeslij);
    form.addEventListener('submit', przeslij);
  });

  /* ── pieśni, obrazy i powiększanie ──────────────────────────────────────── */
  $$('.ped-piesn').forEach(function (sekcja) {
    var obrazy = $$('.ped-obraz', sekcja);
    var podpis = $('.ped-piesn-podpis', sekcja);
    var odtwarzacze = $$('.ped-audio', sekcja);
    var opisy = ((window.PED && PED.obrazyOpisy) || []);
    var teraz = 0;

    // Obrazy zmieniają się same, także przy wyłączonej pieśni — to tło modlitwy.
    // Przy włączonym ograniczeniu ruchu zostaje pierwszy obraz i nic nie miga.
    var spokoj = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    if (obrazy.length > 1 && !spokoj) {
      setInterval(function () {
        obrazy[teraz].classList.remove('widoczny');
        teraz = (teraz + 1) % obrazy.length;
        obrazy[teraz].classList.add('widoczny');
        if (podpis && opisy[teraz]) podpis.textContent = opisy[teraz];
      }, 7000);
    }

    // Dwie melodie naraz to nie modlitwa, tylko hałas — włączenie jednej
    // pieśni zatrzymuje pozostałe.
    odtwarzacze.forEach(function (a) {
      a.addEventListener('play', function () {
        odtwarzacze.forEach(function (b) { if (b !== a) b.pause(); });
      });
    });

    // Powiększenie na cały ekran. Gdzie pełny ekran jest niedostępny (bywa tak
    // na iPhonie i w oknach o ograniczonych prawach), rozsuwamy obraz na całą
    // szerokość strony — żeby przycisk zawsze coś robił.
    var ramka = $('.ped-obrazy', sekcja);
    var przycisk = $('.ped-powieksz', sekcja);
    if (!przycisk || !ramka) return;

    przycisk.addEventListener('click', function () {
      var pelny = document.fullscreenElement || document.webkitFullscreenElement;
      if (pelny) {
        (document.exitFullscreen || document.webkitExitFullscreen).call(document);
        return;
      }
      var wejdz = ramka.requestFullscreen || ramka.webkitRequestFullscreen;
      if (wejdz) {
        var obietnica = wejdz.call(ramka);
        if (obietnica && obietnica.catch) obietnica.catch(function () { przelacz(); });
      } else {
        przelacz();
      }
    });

    function przelacz() {
      var duzy = sekcja.classList.toggle('ped-rozsuniete');
      przycisk.setAttribute('aria-label', duzy ? 'Zmniejsz obraz' : 'Pokaż obraz na całym ekranie');
      przycisk.textContent = duzy ? '⤡' : '⤢';
    }
  });

  /* ── wyszukiwarka w wykazie szkół ───────────────────────────────────────── */
  $$('.ped-wykaz').forEach(function (wykaz) {
    var pole = $('.ped-szukajka', wykaz);
    if (!pole) return;
    var nic = $('.ped-nic', wykaz);

    pole.addEventListener('input', function () {
      var fraza = pole.value.trim().toLowerCase();
      var widocznych = 0;
      $$('.ped-woj-grupa', wykaz).forEach(function (grupa) {
        var wGrupie = 0;
        $$('.ped-szkola', grupa).forEach(function (li) {
          // Małe litery robimy tutaj, a nie w PHP: toLowerCase() przeglądarki
          // radzi sobie z Ł, Ó i Ż bez rozszerzenia mbstring na serwerze.
          var pasuje = !fraza || li.dataset.szukaj.toLowerCase().indexOf(fraza) !== -1;
          li.hidden = !pasuje;
          if (pasuje) { wGrupie++; widocznych++; }
        });
        grupa.hidden = (wGrupie === 0);
      });
      if (nic) nic.hidden = (widocznych > 0);
    });
  });
})();
