<!DOCTYPE html>
<!-- 
  https://m.facebook.com/luberth.dijkman/

  https://codepen.io/ldijkman/pen/NPxPpZE

  -->
<html lang="nl">
  <head>
    <meta charset="utf-8" />

    <meta name="viewport" content="width=device-width,initial-scale=1" />

    <title>24Hr Day Time Circle Schedule</title>

    <style>
      body {
        margin: 0;
        background: #111827;
        color: #eee;
        font-family: sans-serif;
        padding: 20px;
      }

      h1 {
        font-size: 18px;
        margin-bottom: 10px;
      }

      .circlewrap {
        position: relative;
        display: inline-block;
      }

      canvas {
        background: #111;
        border-radius: 50%;
      }

      .time {
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);

        font-size: 20px;
        font-weight: bold;
        color: #06b6d4;
        text-align: center;
      }

      .dateInfo {
        position: absolute;
        top: 60%;
        left: 50%;
        transform: translate(-50%, -50%);

        font-size: 12px;
        color: #fbbf24;
        text-align: center;
        line-height: 1.3;
      }

      .moon {
        position: absolute;
        top: 36%;
        left: 50%;
        transform: translate(-50%, -50%);
        font-size: 26px;
      }

      .moonText {
        position: absolute;
        top: 44%;
        left: 50%;
        transform: translate(-50%, -50%);

        font-size: 12px;
        color: #fbbf24;
      }

      #sunTimes {
        margin-top: 8px;
        text-align: center;
        font-size: 14px;
        color: #fbbf24;
      }

      #geoMsg {
        margin-top: 4px;
        text-align: center;
        font-size: 13px;
        color: #ef4444;
      }

      form {
        margin-top: 15px;
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        justify-content: center;
      }

      input[type='time'] {
        padding: 6px;
        border-radius: 6px;
        border: none;
      }

      button {
        padding: 6px 10px;
        border-radius: 6px;
        border: none;
        cursor: pointer;
      }

      .addBtn {
        flex-basis: 100%;
        max-width: 150px;
        margin-top: 5px;
        background: #06b6d4;
        color: #111;
      }

      ul {
        list-style: none;
        padding: 0;
        margin-top: 15px;
      }

      li {
        display: flex;
        justify-content: space-between;
        align-items: center;

        padding: 6px 8px;
        margin-bottom: 6px;
        background: #1f2937;
        border-radius: 6px;
        flex-wrap: wrap;
        gap: 6px;
      }

      .controls {
        display: flex;
        gap: 6px;
      }

      .btn {
        padding: 4px 8px;
        border-radius: 4px;
        border: none;
        cursor: pointer;
        font-size: 12px;
      }

      .delBtn {
        background: #ef4444;
        color: white;
      }

      .editBtn {
        background: #f59e0b;
        color: white;
      }

      .toggleBtn {
        background: #06b6d4;
        color: #111;
      }
    </style>
  </head>

  <body>
    <h1>24Hr Day Time Circle TimeSlots Timer</h1>

    <div class="circlewrap">
      <canvas id="dayCircle" width="320" height="320"></canvas>

      <div class="moon" id="moonIcon">🌕</div>

      <div class="moonText" id="moonText">Volle Maan</div>

      <div class="time" id="centerTime">--:--</div>

      <div class="dateInfo" id="dateInfo">--</div>
    </div>

    <div id="sunTimes">Zonsopgang: --:-- | Zonsondergang: --:--</div>

    <div id="geoMsg"></div>

    <form id="addForm">
      <input type="time" id="startTime" required />

      <input type="time" id="endTime" required />

      <button type="submit" class="addBtn">Add TimeSlot</button>
    </form>

    <ul id="slotList"></ul>

    <script>
      const canvas = document.getElementById('dayCircle');

      const ctx = canvas.getContext('2d');

      const r = canvas.width / 2 - 30;

      const cx = canvas.width / 2;

      const cy = canvas.height / 2;

      const STORAGE_KEY = 'dagcirkel_slots_v7';

      let slots = [];

      let sunrise = '07:00',
        sunset = '19:00';

      function toMin(t) {
        const [h, m] = t.split(':').map(Number);
        return h * 60 + m;
      }

      function toHHMM(mins) {
        const h = String(Math.floor(mins / 60)).padStart(2, '0');
        const m = String(mins % 60).padStart(2, '0');
        return `${h}:${m}`;
      }

      function isInSlot(mins, slot) {
        const s = toMin(slot.start),
          e = toMin(slot.end);
        return s < e ? mins >= s && mins < e : mins >= s || mins < e;
      }

      function toLocalHHMM(d) {
        return (
          String(d.getHours()).padStart(2, '0') +
          ':' +
          String(d.getMinutes()).padStart(2, '0')
        );
      }

      function getISOWeek(date) {
        const tmp = new Date(date.getTime());

        tmp.setHours(0, 0, 0, 0);

        tmp.setDate(tmp.getDate() + 3 - ((tmp.getDay() + 6) % 7));

        const week1 = new Date(tmp.getFullYear(), 0, 4);

        return (
          1 +
          Math.round(
            ((tmp - week1) / 86400000 - 3 + ((week1.getDay() + 6) % 7)) / 7
          )
        );
      }

      function save() {
        localStorage.setItem(STORAGE_KEY, JSON.stringify(slots));
      }

      function load() {
        const data = localStorage.getItem(STORAGE_KEY);

        if (data) {
          slots = JSON.parse(data);
        } else {
          slots = [
            { id: 1, start: '06:00', end: '08:00', enabled: true },

            { id: 2, start: '12:00', end: '13:30', enabled: true },

            { id: 3, start: '19:00', end: '22:00', enabled: true },
          ];

          save();
        }
      }

      function drawMarkers() {
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';

        for (let hour = 0; hour < 24; hour++) {
          const mins = hour * 60;

          const angle = (mins / 1440) * 2 * Math.PI - Math.PI / 2;

          const inner = hour % 6 === 0 ? r - 14 : r - 8;

          const outer = r + 6;

          const x1 = cx + Math.cos(angle) * inner,
            y1 = cy + Math.sin(angle) * inner;

          const x2 = cx + Math.cos(angle) * outer,
            y2 = cy + Math.sin(angle) * outer;

          ctx.beginPath();
          ctx.moveTo(x1, y1);
          ctx.lineTo(x2, y2);

          ctx.strokeStyle = '#aaa';
          ctx.lineWidth = hour % 6 === 0 ? 2 : 1;
          ctx.stroke();

          if (hour % 6 === 0) {
            ctx.fillStyle = '#ccc';
            ctx.font = '12px sans-serif';

            const labelX = cx + Math.cos(angle) * (r + 20),
              labelY = cy + Math.sin(angle) * (r + 20);

            ctx.fillText(hour.toString(), labelX, labelY);
          }
        }
      }

      function drawDayNight() {
        const srMin = toMin(sunrise),
          ssMin = toMin(sunset);

        const srAngle = (srMin / 1440) * 2 * Math.PI - Math.PI / 2;

        const ssAngle = (ssMin / 1440) * 2 * Math.PI - Math.PI / 2;

        ctx.beginPath();
        ctx.arc(cx, cy, r - 30, 0, 2 * Math.PI);

        ctx.strokeStyle = '#1e3a8a';
        ctx.lineWidth = 12;
        ctx.stroke();

        ctx.beginPath();

        if (srMin < ssMin) {
          ctx.arc(cx, cy, r - 30, srAngle, ssAngle);
        } else {
          ctx.arc(cx, cy, r - 30, srAngle, 1.5 * Math.PI);
          ctx.arc(cx, cy, r - 30, -Math.PI / 2, ssAngle);
        }

        ctx.strokeStyle = '#fbbf24';
        ctx.lineWidth = 12;
        ctx.stroke();
      }

      function drawCircularText(text, radius, centerAngle) {
        ctx.save();
        ctx.translate(cx, cy);
        ctx.rotate(centerAngle);

        ctx.fillStyle = '#ccc';
        ctx.font = '14px sans-serif';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';

        const totalWidth = [...text].reduce(
          (w, ch) => w + ctx.measureText(ch).width,
          0
        );

        let currentAngle = -(totalWidth / radius) / 2;

        [...text].forEach((char) => {
          const w = ctx.measureText(char).width,
            angle = w / radius;

          ctx.rotate(currentAngle + angle / 2);

          ctx.save();
          ctx.translate(0, -radius);
          ctx.fillText(char, 0, 0);
          ctx.restore();

          currentAngle = angle / 2;
        });

        ctx.restore();
      }

      function formatTimeDiff(mins) {
        const h = Math.floor(mins / 60);
        const m = mins % 60;

        return (h > 0 ? h + 'h ' : '') + m + 'm';
      }

      // ✅ Fixed function: now shows ON/OFF and exact time

      function getNextStateChange(now) {
        const minsNow = now.getHours() * 60 + now.getMinutes();

        let nextChange = null;

        slots.forEach((slot) => {
          if (!slot.enabled) return;

          const s = toMin(slot.start),
            e = toMin(slot.end);

          const sDelta = (s - minsNow + 1440) % 1440;

          const eDelta = (e - minsNow + 1440) % 1440;

          if (nextChange === null || sDelta < nextChange.mins) {
            nextChange = { mins: sDelta, type: 'ON', time: slot.start };
          }

          if (nextChange === null || eDelta < nextChange.mins) {
            nextChange = { mins: eDelta, type: 'OFF', time: slot.end };
          }
        });

        return nextChange
          ? `In ${formatTimeDiff(nextChange.mins)} → ${nextChange.type} at ${
              nextChange.time
            }`
          : '--';
      }

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

        ctx.beginPath();
        ctx.arc(cx, cy, r, 0, 2 * Math.PI);

        ctx.strokeStyle = '#e0e0e0';
        ctx.lineWidth = 24;
        ctx.stroke();

        drawDayNight();

        const now = new Date();
        const mins = now.getHours() * 60 + now.getMinutes();

        let stateColor = 'grey';
        let inAnySlot = false;

        slots.forEach((slot) => {
          if (!slot.enabled) return;

          const sMin = toMin(slot.start),
            eMin = toMin(slot.end);

          const active = isInSlot(mins, slot);
          if (active) inAnySlot = true;

          const color = active ? 'limegreen' : 'red';

          const startAngle = (sMin / 1440) * 2 * Math.PI - Math.PI / 2;

          const endAngle = (eMin / 1440) * 2 * Math.PI - Math.PI / 2;

          ctx.beginPath();

          if (sMin < eMin) {
            ctx.arc(cx, cy, r, startAngle, endAngle);
          } else {
            ctx.arc(cx, cy, r, startAngle, 1.5 * Math.PI);
            ctx.arc(cx, cy, r, -Math.PI / 2, endAngle);
          }

          ctx.strokeStyle = color;
          ctx.lineWidth = 24;
          ctx.stroke();
        });

        drawMarkers();

        if (slots.some((s) => s.enabled)) {
          stateColor = inAnySlot ? 'limegreen' : 'red';
        }

        const angle = (mins / 1440) * 2 * Math.PI - Math.PI / 2;

        const innerR = 40;

        ctx.beginPath();
        ctx.moveTo(
          cx + Math.cos(angle) * innerR,
          cy + Math.sin(angle) * innerR
        );

        ctx.lineTo(cx + Math.cos(angle) * r, cy + Math.sin(angle) * r);

        ctx.strokeStyle = stateColor;
        ctx.lineWidth = 4;
        ctx.stroke();

        document.getElementById('centerTime').textContent = toHHMM(mins);

        const days = [
          'Sunday',
          'Monday',
          'Tuesday',
          'Wednesday',
          'Thursday',
          'Friday',
          'Saturday',
        ];

        const dayName = days[now.getDay()];

        const options = { day: 'numeric', month: 'long', year: 'numeric' };

        const dateStr = now.toLocaleDateString('nl-NL', options);

        const weekNum = getISOWeek(now);

        const nextChangeText = getNextStateChange(now);

        document.getElementById(
          'dateInfo'
        ).innerHTML = `${dayName}<br>${dateStr}<br>Week ${weekNum}<br>Next: ${nextChangeText}`;

        document.getElementById(
          'sunTimes'
        ).textContent = `SunRise: ${sunrise} | SunSet: ${sunset}`;

        drawCircularText('Evening', r + 20, -Math.PI / 4);

        drawCircularText('Night', r + 20, Math.PI / 4);

        drawCircularText('Morning', r + 20, (3 * Math.PI) / 4);

        drawCircularText('Afternoon', r + 20, (-3 * Math.PI) / 4);
      }

      function renderList() {
        const ul = document.getElementById('slotList');

        ul.innerHTML = '';

        slots.forEach((slot) => {
          const li = document.createElement('li');

          const span = document.createElement('span');

          span.textContent = `${slot.start} → ${slot.end}`;

          span.style.color = slot.enabled ? '#eee' : '#666';

          li.appendChild(span);

          const ctr = document.createElement('div');
          ctr.className = 'controls';

          const tgl = document.createElement('button');

          tgl.textContent = 'Toggle';
          tgl.className = 'btn toggleBtn';

          tgl.onclick = () => {
            slot.enabled = !slot.enabled;
            save();
            renderList();
            drawCircle();
          };

          const edit = document.createElement('button');

          edit.textContent = 'Edit';
          edit.className = 'btn editBtn';

          edit.onclick = () => {
            li.innerHTML = '';

            const startInput = document.createElement('input');

            startInput.type = 'time';
            startInput.value = slot.start;

            const endInput = document.createElement('input');

            endInput.type = 'time';
            endInput.value = slot.end;

            const saveBtn = document.createElement('button');

            saveBtn.textContent = 'Save';
            saveBtn.className = 'btn toggleBtn';

            saveBtn.onclick = () => {
              slot.start = startInput.value;

              slot.end = endInput.value;

              save();
              renderList();
              drawCircle();
            };

            li.appendChild(startInput);

            li.appendChild(endInput);

            li.appendChild(saveBtn);
          };

          const del = document.createElement('button');

          del.textContent = 'Delete';
          del.className = 'btn delBtn';

          del.onclick = () => {
            slots = slots.filter((s) => s.id !== slot.id);
            save();
            renderList();
            drawCircle();
          };

          ctr.appendChild(tgl);
          ctr.appendChild(edit);
          ctr.appendChild(del);

          li.appendChild(ctr);

          ul.appendChild(li);
        });
      }

      document.getElementById('addForm').addEventListener('submit', (e) => {
        e.preventDefault();

        const st = document.getElementById('startTime').value;

        const ed = document.getElementById('endTime').value;

        if (!st || !ed) return;

        slots.push({ id: Date.now(), start: st, end: ed, enabled: true });

        save();
        renderList();
        drawCircle();
        e.target.reset();
      });

      function fetchSunTimes(lat, lon) {
        fetch(
          `https://api.sunrise-sunset.org/json?lat=${lat}&lng=${lon}&formatted=0`
        )
          .then((res) => res.json())

          .then((data) => {
            if (data.status === 'OK') {
              sunrise = toLocalHHMM(new Date(data.results.sunrise));

              sunset = toLocalHHMM(new Date(data.results.sunset));

              document.getElementById('geoMsg').textContent = '';

              drawCircle();
            }
          })

          .catch(() => {
            document.getElementById('geoMsg').textContent =
              'Kon sunrise/sunset niet ophalen.';
          });
      }

      if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(
          (pos) => {
            fetchSunTimes(pos.coords.latitude, pos.coords.longitude);
          },

          () => {
            document.getElementById('geoMsg').textContent =
              'Geen toegang tot locatie → standaardtijden gebruikt.';
          }
        );
      } else {
        document.getElementById('geoMsg').textContent =
          'Geolocatie niet ondersteund door deze browser.';
      }

      function updateMoonPhase() {
        const phases = [
          '🌑',
          '🌒',
          '🌓',
          '🌔',
          '🌕',
          '🌖',
          '🌗',
          '🌘',
        ];

        const names = [
          'Nieuwe Maan',
          'Wassende Sikkel',
          'Eerste Kwartier',
          'Wassende Maan',

          'Volle Maan',
          'Afnemende Maan',
          'Laatste Kwartier',
          'Afnemende Sikkel',
        ];

        const now = new Date();

        const lp = new Date(Date.UTC(2000, 0, 6, 18, 14));

        const diff = now - lp;

        const days = diff / 1000 / 60 / 60 / 24;

        const lunations = days / 29.53058867;

        const index =
          Math.floor((lunations - Math.floor(lunations)) * 8 + 0.5) % 8;

        document.getElementById('moonIcon').textContent = phases[index];

        document.getElementById('moonText').textContent = names[index];
      }

      load();
      renderList();
      drawCircle();
      updateMoonPhase();

      setInterval(() => {
        drawCircle();
        updateMoonPhase();
      }, 15000);
    </script>
  </body>
</html>
/* Add your styles here */

// Add your code here