<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>QUASSI P2000 Meldingen</title>
    <!-- Tailwind CSS -->
    <script src="https://cdn.tailwindcss.com"></script>
    <!-- Google Fonts: Fira Code -->
    <link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500;600&display=swap" rel="stylesheet">
    <style>
      /* Voeg Fira Code toe als monospace-font in Tailwind */
      @layer base {
          body {
              font-family: 'Fira Code', monospace;
          }
      }
  </style>
</head>

<body class="bg-gray-900 text-black">
  
  <!-- Header -->
  <header class="fixed top-0 w-full bg-gray-800 text-white shadow-md z-50">
    <div class="flex items-center justify-between px-4 py-3">
      <h1 class="text-lg font-bold">P2000</h1>
      <div id="status" class="text-white self-center text-sm font-semibold whitespace-nowrap dark:text-black">Connecting...</div>
        <div id="count" class="text-white self-center text-sm font-semibold whitespace-nowrap dark:text-black">0</div>
      <div class="flex items-center space-x-4">
        <!--<span class="text-sm bg-green-500 text-white py-1 px-2 rounded">Online</span>-->
        <button 
          id="soundButton" 
          class="text-sm bg-green-500 text-white py-1 px-2 rounded"
          onclick="toggleSound()">
          G
        </button>
        <button id="openSettingsRegios"
         class="text-sm bg-blue-500 text-white py-1 px-2 rounded">
          R
        </button>
        <button id="openSettingsDisciplines"
         class="text-sm bg-blue-500 text-white py-1 px-2 rounded">
          D
        </button>
      </div>
    </div>
  </header>




  <!-- Overlay Discipline -->
  <div id="overlayDisciplines" class="hidden fixed inset-0 bg-gray-900 bg-opacity-75 flex justify-center items-center z-50">
    <div class="bg-white p-4 rounded-lg w-full max-w-md max-h-full overflow-y-auto">
      <h2 class="text-lg font-bold mb-3">Disciplines</h2>
      <div class="space-y-2">
        <!-- Checkbox Settings -->
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="discipline_Brandweer" class="form-checkbox" checked>
          <span>Brandweer</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="discipline_Ambulance" class="form-checkbox" checked>
          <span>Ambulance</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="discipline_Politie" class="form-checkbox" checked>
          <span>Politie</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="discipline_MMT" class="form-checkbox" checked>
          <span>MMT</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="discipline_KNRM" class="form-checkbox" checked>
          <span>KNRM</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="discipline_Bruggen" class="form-checkbox" checked>
          <span>Bruggen</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="discipline_Test" class="form-checkbox" checked>
          <span>Test</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="discipline_Onbekend" class="form-checkbox" checked>
          <span>Onbekend</span>
        </label>
      </div>
      <div class="mt-4 flex justify-end space-x-2">
        <button id="closeOverlayD" class="px-3 py-1 bg-gray-300 rounded text-sm">Annuleren</button>
        <button id="saveSettingsD" class="px-3 py-1 bg-green-500 text-white rounded text-sm">Opslaan</button>
      </div>
    </div>
  </div>





  <!-- Overlay Regio's -->
  <div id="overlayRegios" class="hidden fixed inset-0 bg-gray-900 bg-opacity-75 flex justify-center items-center z-50">
    <div class="bg-white p-4 rounded-lg w-full max-w-lg max-h-full overflow-y-auto">
      <div class="flex justify-end mb-3">
        <button id="selectallOverlayR" class="px-3 py-1 bg-blue-500 text-white rounded text-sm">Alles</button>
      </div>
      <h2 class="text-lg font-bold mb-3">Regio's</h2>
      <div class="grid grid-cols-2 gap-2">
        <!-- Checkbox Settings -->
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Groningen" class="form-checkbox" checked>
          <span>Groningen</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Friesland" class="form-checkbox" checked>
          <span>Friesland</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Drenthe" class="form-checkbox" checked>
          <span>Drenthe</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_IJsselland" class="form-checkbox" checked>
          <span>IJsselland</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Twente" class="form-checkbox" checked>
          <span>Twente</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Noord-_en_Oost-Gelderland" class="form-checkbox" checked>
          <span>Noord- en Oost-Gelderland</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Gelderland-Midden" class="form-checkbox" checked>
          <span>Gelderland-Midden</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Gelderland-Zuid" class="form-checkbox" checked>
          <span>Gelderland-Zuid</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Utrecht" class="form-checkbox" checked>
          <span>Utrecht</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Noord-Holland_Noord" class="form-checkbox" checked>
          <span>Noord-Holland Noord</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Zaanstreek-Waterland" class="form-checkbox" checked>
          <span>Zaanstreek-Waterland</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Kennemerland" class="form-checkbox" checked>
          <span>Kennemerland</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Amsterdam-Amstelland" class="form-checkbox" checked>
          <span>Amsterdam-Amstelland</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Gooi_en_Vechtstreek" class="form-checkbox" checked>
          <span>Gooi en Vechtstreek</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Haaglanden" class="form-checkbox" checked>
          <span>Haaglanden</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Hollands-Midden" class="form-checkbox" checked>
          <span>Hollands-Midden</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Rotterdam-Rijnmond" class="form-checkbox" checked>
          <span>Rotterdam-Rijnmond</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Zuid-Holland_Zuid" class="form-checkbox" checked>
          <span>Zuid-Holland Zuid</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Zeeland" class="form-checkbox" checked>
          <span>Zeeland</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Midden-_en_West-Brabant" class="form-checkbox" checked>
          <span>Midden- en West-Brabant</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Brabant-Noord" class="form-checkbox" checked>
          <span>Brabant-Noord</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Brabant-Zuidoost" class="form-checkbox" checked>
          <span>Brabant-Zuidoost</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Limburg-Noord" class="form-checkbox" checked>
          <span>Limburg-Noord</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Limburg-Zuid" class="form-checkbox" checked>
          <span>Limburg-Zuid</span>
        </label>
        <label class="flex items-center space-x-2">
          <input type="checkbox" id="regio_Flevoland" class="form-checkbox" checked>
          <span>Flevoland</span>
        </label>
      </div>
      <div class="mt-4 flex justify-end space-x-2">
        <button id="closeOverlayR" class="px-3 py-1 bg-gray-300 rounded text-sm">Annuleren</button>
        <button id="saveSettingsR" class="px-3 py-1 bg-green-500 text-white rounded text-sm">Opslaan</button>
      </div>
    </div>
  </div>

  



  <!-- Main Content -->
  <main class="pt-16 pb-16 px-4">
    <div class="max-w-3xl mx-auto space-y-4">
      <div id="messages" class=" z-10">
      </div>
    </div>
  </main>




  <!-- AUDIO -->
  <audio id="p2000Sound">
    <source src="p2000sound.mp3" type="audio/mpeg">
  </audio>


  <!-- SCRIPTS -->
  <script src="https://unpkg.com/mqtt/dist/mqtt.min.js"></script>
  <script>

const messages = []; // Array om berichten op te slaan

// DOM element to display messages
const messageContainer = document.getElementById('messages');

var brokerUrl;
var options;

  // MQTT Broker details
  // https://github.com/mqttjs/MQTT.js
  
  //brokerUrl = "ws://62.131.237.150:19001"; // WebSocket URL for Mosquitto
  //brokerUrl = "ws://mqtt.p2000.quassi.nl:19001"; // WebSocket URL for Mosquitto
  
  //brokerUrl = "wss://62.131.237.150:19002"; // WebSocket URL for Mosquitto
  brokerUrl = "wss://mqtt.p2000.quassi.nl:19002"; // WebSocket URL for Mosquitto

  options = {
      username: "p2000",         // MQTT username
      password: "p2000",         // MQTT password
      keepalive: 60,             // Keep alive interval in seconds
      reconnectPeriod: 1000,     // Reconnection interval in ms
      rejectUnauthorized: false, // Alleen voor tests; schakel dit uit in productie
      clientId: `mqtt_${Math.random().toString(16).substr(2, 8)}` // Unique client ID
  };

// Create MQTT client and connect
const client = mqtt.connect(brokerUrl, options);


// --------------------------------
// ---- Event: Successful connection
// --------------------------------
client.on('connect', () => {
    document.getElementById('status').textContent = "C";
    console.log("Connected to MQTT broker");

    // Subscribe to the Server topic
    //const topic = "P2000/+/#";
    //const topics = ['P2000/Server', 'P2000/+/Brandweer', 'P2000/+/Ambulance', 'P2000/+/Politie', 'P2000/+/Test', 'P2000/+/Onbekend'];
    const topics = ['P2000/Server/#'];
    topics.forEach(topic => {
      client.subscribe(topic, (err) => {
          if (err) {
              console.error(`Failed to subscribe to topic: ${topic}`, err);
          } else {
              console.log(`Subscribed to topic: ${topic}`);
          }
      });
    });

    // Subscribe to the default topics
    DisciplineSubscribeUnsubscribe();

    // Publish a message to the topic
    /*const message = "Hello from MQTT!";
    const topictest = "P2000/Server";
    client.publish(topictest, message, (err) => {
        if (!err) {
            console.log(`Message sent: ${message}`);
        } else {
            console.error("Failed to publish message:", err);
        }
    });*/
    
});

// --------------------------------
// ---- Event: Receive message
// --------------------------------
client.on('message', (topic, message) => {
  //console.log(`Message received on topic ${topic}: ${message.toString()}`);  
 
  if (message.length > 0 )
  {

    if (sound)
    {
      var x = document.getElementById("p2000Sound"); 
      x.play();
    }

    var json;

    try {
      json = JSON.parse(message.toString());
      
      // Voeg bericht toe aan de array
      messages.push(json);
      
      // Sorteer de berichten op basis van datum en tijd
      messages.sort((a, b) => {
          const dateA = new Date(`${formatDate(a.Date, a.Time)}`);
          const dateB = new Date(`${formatDate(b.Date, b.Time)}`);
          return dateB - dateA; // Aflopende volgorde
      });
      //document.getElementById('count').textContent = messages.length + ` (${messages[0].Time.split(":").slice(0, 2).join(":")} - ${messages[messages.length-1].Time.split(":").slice(0, 2).join(":")})`;
      document.getElementById('count').textContent = messages.length;
      
      // Leeg de container
      messageContainer.innerHTML = '';
      
      // Voeg gesorteerde berichten toe aan de UI
      messages.slice(0, 20).forEach(msg => {
      //messages.forEach(msg => {
          const msgDiv = document.createElement('div');
          msgDiv.classList.add('message');
          msgDiv.innerHTML = `
          <!-- Card -->
          <div class="space-y-4 py-1">
            <div class="bg-gray-700 shadow border border-gray-600 rounded-lg overflow-hidden">
              
              <div class="flex justify-between items-center p-2">
                <div class="text-xs bg-${msg.Colour}-500 text-black py-0.5 px-2 rounded self-start">${msg.Time.split(":").slice(0,2).join(":")}</div>
                <div class="text-sm font-semibold text-gray-100 px-2 flex-1">
                  <h5>${msg.MessageText}</h5>
                </div>
                <span class="text-xs text-gray-300 self-start">${formatDateString(msg.Date)}</span>
              </div>
              
              <div class="p-2 space-y-2 border-t border-gray-600">
                ${msg.Capcodes.map(capcode => `
                <div class="text-xs text-gray-300 flex justify-between items-start">
                  <span class="flex items-center text-gray-400">
                    <span class="w-2 h-2 bg-${capcode.Colour}-500 inline-block mr-2"></span>
                    ${capcode.CapcodeNr}
                  </span>
                  <span class="flex-1 text-left px-2">
                  ${capcode.Omschrijving} ${capcode.Plaats ? `(<i>${capcode.Plaats}</i>)` : ""}
                  </span>
                </div>
                `).join('')}
              </div>

              <div class="flex justify-between items-center p-2 text-[0.5rem] text-gray-400 border-t border-gray-600">
                <div></div>
                <div class="text-xs bg-gray-600 text-gray-400 py-0.5 px-2 rounded">
                  ${msg.Topic.split("/").slice(1,2).join(" / ")}
                </div>
              </div>
            </div>
          </div>
          `;
          messageContainer.appendChild(msgDiv); // Voeg gesorteerde berichten toe
      });
      
      //const msgDiv = document.createElement('div');
      //msgDiv.classList.add('message');
      //
      //msgDiv.innerHTML = `
      //  <div class="relative mx-auto my-6 bg-gray-700 shadow-sm border border-slate-200 rounded-lg">
      //    <div class="flex justify-between items-center text-gray-700 p-2">
      //      <!--<div class="pl-2 w-20 h-4 bg-${json.Colour}-500 rounded-sm"></div>-->
      //      <div class="pl-2 w-20 h-6 bg-${json.Colour}-500 rounded-sm flex items-center justify-center text-white text-sm">${json.Time.split(":").slice(0, 2).join(":")}</div>
      //      <span class="text-sm text-slate-100">${json.Date}</span>
      //    </div>
      //    <div class="mx-3 mb-0 border-b border-slate-200 pt-3 pb-2 px-1">
      //      <h5 class="mb-2 text-slate-200 text-xl font-semibold">
      //        ${json.MessageText}
      //      </h5>
      //    </div>
      //    <div class="p-4">
      //      ${json.Capcodes.map(capcode => `
      //        <p class="text-slate-300 leading-normal font-light">
      //          <span class="inline-block w-2 h-2 bg-${capcode.Colour}-500 mr-2"></span>  
      //          ${capcode.CapcodeNr} - ${capcode.Omschrijving} ${capcode.Plaats ? `(<i>${capcode.Plaats}</i>)` : ""}
      //        </p>
      //      `).join('')}
      //    </div>
      //  </div>
      //`;
      //
      //messageContainer.prepend(msgDiv); // Add new messages at the top

    } catch (error) {
      console.error("Fout bij het parsen van JSON:", error.message);
      console.error("Foutieve JSON-string:", message.toString());
    }
  }
  else
  {
    // Dit zijn de clean-up berichten 0 byte
    //console.error(`Message received on topic ${topic}; Length = : ${message.length}`);  
  }

  
});


// --------------------------------
// ---- Event: Connection error
// --------------------------------
client.on('error', (err) => {
    document.getElementById('status').textContent = "Connection Error!";
    console.error("Connection error:", err);
});


// --------------------------------
// ---- Event: Disconnected
// --------------------------------
client.on('close', () => {
    document.getElementById('status').textContent = "-";
    console.log("Disconnected from MQTT broker");
});


// ---- Function: Format P2000 date and time
function formatDate(dateString, timeString) {
  const [day, month, year] = dateString.split('-');
  
  // Maak een string voor de volledige datetime in ISO-formaat
  //const isoString = `20${year}-${month}-${day}T${timeString}:00`;
  //console.log(isoString);
  // Maak een Date object van de ISO-string
  //return new Date(isoString);
  return new Date(`20${year}-${month}-${day}T${timeString}`);
}

// ---- Function: Leest de waarde van de Discipline checkboxs en een MQTT subscribe/unsubscribe aanroep doet
function DisciplineSubscribeUnsubscribe() {
  messages.length = 0;
  messageContainer.innerHTML = '';

  const regios = ['Groningen', 'Friesland', 'Drenthe', 'IJsselland', 'Twente', 'Noord- en Oost-Gelderland', 'Gelderland-Midden', 'Gelderland-Zuid', 'Utrecht', 'Noord-Holland Noord', 'Zaanstreek-Waterland', 'Kennemerland', 'Amsterdam-Amstelland', 'Gooi en Vechtstreek', 'Haaglanden', 'Hollands-Midden', 'Rotterdam-Rijnmond', 'Zuid-Holland Zuid', 'Zeeland', 'Midden- en West-Brabant', 'Brabant-Noord', 'Brabant-Zuidoost', 'Limburg-Noord', 'Limburg-Zuid', 'Flevoland'];
  const disc = ['Brandweer', 'Ambulance', 'Politie', 'MMT', 'KNRM', 'Bruggen', 'Test', 'Onbekend'];

  // Unsubscribe all disciplines
  regios.forEach(r => {
    disc.forEach(d => {
      const topic = "P2000/"+ r + "/" + d + "/#";

      // MQTT unsubscribe
      client.unsubscribe(topic, (err) => {
        if (err) {
          console.error(`Failed to unsubscribe to topic: ${topic}`, err);
        } else {
          //console.log(`Unsubscribed to topic: ${topic}`);
        }
      });
    });
  });

  // Subscribe only selected disciplines
  regios.forEach(r => {
    var regioID = 'regio_' + r.replace(/ /g, '_');
    //console.log(regioID);
    const isCheckedR = document.getElementById(regioID).checked;
    

    disc.forEach(d => {
      var discID = 'discipline_' + d;
    //console.log(discID);
      const isCheckedD = document.getElementById(discID).checked;
      const topic = "P2000/"+ r + "/" + d + "/#";

      if (isCheckedD && isCheckedR) {
        // MQTT subscribe
        client.subscribe(topic, (err) => {
          if (err) {
            console.error(`Failed to subscribe to topic: ${topic}`, err);
          } else {
            //console.log(`Subscribed to topic: ${topic}`);
          }
        });
      } else {
        // MQTT unsubscribe
        /*client.unsubscribe(topic, (err) => {
          if (err) {
            console.error(`Failed to unsubscribe to topic: ${topic}`, err);
          } else {
            console.log(`Unsubscribed to topic: ${topic}`);
          }
        });*/
      }
    });
  });
}

  // Functie om de datum om te zetten naar het gewenste formaat
  function formatDateString(dateString) {
    const months = ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"];
    
    // Split de string in dag, maand en jaar
    const parts = dateString.split('-');
    const day = parts[0];  // Dag
    const month = parts[1];  // Maand (nummer)
    const year = parts[2];  // Jaar (afgekort)

    // Haal de maand afkorting op
    const monthName = months[parseInt(month) - 1];
  
    // Maak de nieuwe string
    return `${day}${monthName}${year}`;
  }

  
  </script>
  
    <script>
      // Initial status of the sound
      let sound = false;

      // Function to toggle the sound variable and update the button's style
      function toggleSound() {
          sound = !sound;
          updateButtonStyles();
      }

    </script>
    



    
  <script>

    // Function to update the button's style based on the sound variable
    function updateButtonStyles() {
      console.log(sound);
      
      const buttonS = document.getElementById('soundButton');
      if (sound) {
          buttonS.classList.remove('bg-gray-500');
          buttonS.classList.add('bg-green-500');
      } else {
          buttonS.classList.remove('bg-green-500');
          buttonS.classList.add('bg-gray-500');
      }


    }

    // Ensure the buttons have the correct style on page load
    window.onload = updateButtonStyles;
  </script>




  <script>
    // Discipline: JavaScript om de overlay in te schakelen en instellingen op te slaan
    const openSettingsButtonD = document.getElementById('openSettingsDisciplines');
    const overlayD = document.getElementById('overlayDisciplines');
    const closeOverlayButtonD = document.getElementById('closeOverlayD');
    const saveSettingsButtonD = document.getElementById('saveSettingsD');

    openSettingsButtonD.addEventListener('click', () => {
      overlayD.classList.remove('hidden');
    });

    closeOverlayButtonD.addEventListener('click', () => {
      overlayD.classList.add('hidden');
    });

    saveSettingsButtonD.addEventListener('click', () => {
      DisciplineSubscribeUnsubscribe();

      // Voorbeeld: log de instellingen naar de console
      console.log("Instellingen opgeslagen");
      
      // Sluit de overlayD na het opslaan
      overlayD.classList.add('hidden');
    });


    // Regios: JavaScript om de overlay in te schakelen en instellingen op te slaan
    const openSettingsButtonR = document.getElementById('openSettingsRegios');
    const overlayR = document.getElementById('overlayRegios');
    const closeOverlayButtonR = document.getElementById('closeOverlayR');
    const saveSettingsButtonR = document.getElementById('saveSettingsR');
    const selectallOverlayButtonR = document.getElementById('selectallOverlayR');

    openSettingsButtonR.addEventListener('click', () => {
      overlayR.classList.remove('hidden');
    });

    closeOverlayButtonR.addEventListener('click', () => {
      overlayR.classList.add('hidden');
    });

    selectallOverlayButtonR.addEventListener('click', () => {
      const regios = ['Groningen', 'Friesland', 'Drenthe', 'IJsselland', 'Twente', 'Noord- en Oost-Gelderland', 'Gelderland-Midden', 'Gelderland-Zuid', 'Utrecht', 'Noord-Holland Noord', 'Zaanstreek-Waterland', 'Kennemerland', 'Amsterdam-Amstelland', 'Gooi en Vechtstreek', 'Haaglanden', 'Hollands-Midden', 'Rotterdam-Rijnmond', 'Zuid-Holland Zuid', 'Zeeland', 'Midden- en West-Brabant', 'Brabant-Noord', 'Brabant-Zuidoost', 'Limburg-Noord', 'Limburg-Zuid', 'Flevoland'];
      regios.forEach(regio => {
        var regioID = 'regio_' + regio.replace(/ /g, '_');
        const checkbox = document.getElementById(regioID);
        checkbox.checked = !checkbox.checked;
      });
    });

    saveSettingsButtonR.addEventListener('click', () => {
      DisciplineSubscribeUnsubscribe();

      // Voorbeeld: log de instellingen naar de console
      console.log("Instellingen opgeslagen");
      
      // Sluit de overlayR na het opslaan
      overlayR.classList.add('hidden');
    });

  </script>




  <!-- Footer -->
  <footer class="bg-gray-800 text-gray-400 text-center py-3">
    <p>&copy; 1975-2025 QUASSI. All rights reserved.</p>
  </footer>
</body>
</html>

