<template>
  <img
    id="kein_bild"
    src="./assets/img/weiss_pixel.png"
    style="width: 0px; height: 0px"
  />
  <img
    id="stadtplan"
    src="./assets/img/stadtplan.png"
    style="width: 0px; height: 0px"
  />
  <img
    id="gold_rush"
    src="./assets/img/desert_landscape.png"
    style="width: 0px; height: 0px"
  />

  <h2>
    Finde heraus, wie die Positionen der {{ this.bezeichnung_prototypen }} an
    die {{ this.bezeichnung_datenpunkte }} angepasst werden.
  </h2>
  <br />

  <canvas
    id="c"
    STYLE="border: 1px black solid;"
    height="450"
    width="800"
  ></canvas>
  <br />
  Die <b>Punkte</b> auf der Karte sind die
  <b>{{ this.bezeichnung_datenpunkte }}</b
  >.<br />
  Die <b>x-Markierungen</b> auf der Karte entsprechen den
  <b>{{ this.bezeichnung_prototypen }}</b>
  <br />
  <br />
  <div>
    <button class="btn btn-primary" @click="starte_animation_alle">
      starte Animation für alles
    </button>

    <input
      type="range"
      v-model="animation_speed_range"
      min="0"
      max="2000"
      step="1"
    />

    {{ animation_speed }} ms
  </div>

  <br />
  <div>
    <button class="btn btn-primary" @click="szenario_zuruecksetzen">
      Szenario zurücksetzen
    </button>
  </div>

  <br />

  <div style="width: 800px; margin: auto">
    <button class="btn btn-primary collapsible" style="background: grey">
      Hilfekarte: Animation im Einzelschritt
    </button>
    <div class="content" id="content2">
      <div class="row">
        <div class="column">
          {{ this.bezeichnung_aktueller_datenpunkt }}:
          <button class="btn btn-primary" @click="voriger_datenpunkt">-</button>
          &nbsp;<b style="font-size: x-large">{{ aktueller_datenpunkt + 1 }}</b
          >&nbsp;
          <button class="btn btn-primary" @click="naechster_datenpunkt">
            +
          </button>
        </div>
        <div class="column">
          {{ this.bezeichnung_aktueller_prototyp }}:
          <!-- <button @click="voriger_prototyp">-</button> -->
          <b style="font-size: x-large">{{ aktueller_prototyp + 1 }}</b>
          <!-- <button @click="naechster_prototyp">+</button> -->
        </div>
      </div>

      <button class="btn btn-primary" @click="starte_animation">
        starte Animation nur für {{ this.bezeichnung_aktueller_datenpunkt }}
      </button>
    </div>
  </div>
  <br />
  <div style="width: 800px; margin: auto">
    <button class="btn btn-primary collapsible" style="background: grey">
      Vertiefung: weitere Einstellungsmöglichkeiten
    </button>
    <div class="content" id="content0" style="text-align: center">
      <br />
      Verändere die Zahl der {{ this.bezeichnung_datenpunkte }} und
      {{ this.bezeichnung_prototypen }}.
      <div class="row">
        <div class="column" style="text-align: center">
          <h3>{{ this.bezeichnung_datenpunkte }}</h3>

          <button
            class="btn btn-primary"
            @click="update_anzahl_datenpunkte(--this.anzahl_datenpunkte)"
          >
            -
          </button>
          &nbsp;
          <b style="font-size: xx-large">{{ this.anzahl_datenpunkte }}</b
          >&nbsp;
          <button
            class="btn btn-primary"
            @click="update_anzahl_datenpunkte(++this.anzahl_datenpunkte)"
          >
            +
          </button>

          <br />
          <br />
        </div>

        <div class="column" style="text-align: center">
          <h3>{{ this.bezeichnung_prototypen }}</h3>

          <button
            class="btn btn-primary"
            @click="update_anzahl_prototypen(--this.anzahl_prototypen)"
          >
            -
          </button>
          &nbsp;
          <b style="font-size: xx-large">{{ this.anzahl_prototypen }}</b>
          &nbsp;
          <button
            class="btn btn-primary"
            @click="update_anzahl_prototypen(++this.anzahl_prototypen)"
          >
            +
          </button>
          <br />
          <br />
        </div>
      </div>

      <button class="btn btn-primary collapsible" style="background: grey">
        manuell verändern
      </button>
      <div class="content" id="content1" style="text-align: center">
        In jeder Zeile werden die zugehörigen Werte dargestellt für einen...
        <br />
        <div class="row">
          
          <div class="column" style="text-align: center">
            <b>Datenpunkt</b><br />
            x; y<br>
            <textarea
              v-model="txt_datensatz"
              placeholder="add multiple lines"
              rows="10"
            ></textarea>
            <br />
            <button class="btn btn-primary" @click="textarea_2_datensatz">
              Datenpunkte verändern
            </button>
          </div>
          <div class="column" style="text-align: center">
            <b>Prototyp</b><br />
            x; y<br />
            <textarea
              v-model="txt_prototypensatz"
              placeholder="add multiple lines"
              rows="10"
            ></textarea>
            <br />
            <button class="btn btn-primary" @click="textarea_2_prototypensatz">
              Prototypen verändern
            </button>
          </div>
        </div>
      </div>

      <hr />

      <div style="text-align: center">
        <h3>Szenario auswählen</h3>
        <select v-model="szenario" @change="szenario_aendern">
          <option value="gold_rush">
            Karte Gold Rush (Goldstücke und Ausgrabungsteams)
          </option>
          <option value="stadtplan">
            Stadtplan (Haushalte und U-Bahn-Stationen)
          </option>
          <option value="kein_bild">reine Datenansicht</option>
        </select>
      </div>
      <br />
    </div>
  </div>
  <br />
  <br />
</template>

<script>
// Import the generateDifferentColors function from generateColors.js
import { generateDifferentColors } from "./generateColors.js";

export default {
  name: "App",
  components: {
    // Zeichnung,
    //HelloWorld
  },
  data() {
    return {
      datenpunkte_zufall: false,
      txt_datensatz: null,
      txt_prototypensatz: null,

      anzahl_datenpunkte: 8,
      anzahl_prototypen: 3,
      szenario: "gold_rush",

      gold_rush_datenpunkte: [
        { x: 2, y: 3, color: "black" },
        { x: 3, y: 6, color: "black" },
        { x: 4, y: 7, color: "black" },
        { x: 300, y: 300, color: "black" },
        { x: 300, y: 300, color: "black" },
        { x: 300, y: 300, color: "black" },
        { x: 300, y: 300, color: "black" },
        { x: 300, y: 300, color: "black" },
        { x: 300, y: 300, color: "black" },
        { x: 300, y: 300, color: "black" },
        { x: 300, y: 300, color: "black" },
        { x: 300, y: 300, color: "black" },
        { x: 300, y: 300, color: "black" },
        { x: 300, y: 300, color: "black" },
        { x: 300, y: 300, color: "black" },
        { x: 300, y: 300, color: "black" },
        { x: 300, y: 300, color: "black" },
        { x: 300, y: 300, color: "black" },
        { x: 300, y: 300, color: "black" },
        { x: 300, y: 300, color: "black" },
      ],

      datenpunkte: [
        { x: 300, y: 300, color: "black" },
        { x: 202, y: 70, color: "black" },
        { x: 162, y: 250, color: "black" },
        { x: 82, y: 20, color: "black" },
        { x: 500, y: 350, color: "black" },
        { x: 630, y: 170, color: "black" },
        { x: 430, y: 270, color: "black" },
        { x: 570, y: 30, color: "black" },
      ],

      prototypen: [
        { x: 540, y: 50, color: "blue" },
        { x: 380, y: 370, color: "blue" },
        { x: 120, y: 150, color: "blue" },
      ],

      prototypen_original: [
        { x: 540, y: 50, color: "blue" },
        { x: 380, y: 370, color: "blue" },
        { x: 120, y: 150, color: "blue" },
      ],

      canvas: null,
      vueCanvas: null,
      aktueller_datenpunkt: 0,
      aktueller_prototyp: 0,
      animation_speed_range: 750,
      paused: false,
      animationsphase: null,
      naechstgelegener_prototyp: null,
      letzte_prototyp: null,
      naechstgelegener_prototyp_distanz: null,
    };
  },

  computed: {
    aktuelles_hintergrundbild: function () {
      return this.szenario;
    },
    bezeichnung_datenpunkte: function () {
      switch (this.szenario) {
        case "gold_rush":
          return "Goldstücke";
        case "stadtplan":
          return "Haushalte";
      }
      return "Datenpunkte";
    },
    bezeichnung_prototypen: function () {
      switch (this.szenario) {
        case "gold_rush":
          return "Grabungsteams";
        case "stadtplan":
          return "U-Bahn-Stationen";
      }
      return "Prototypen";
    },

    bezeichnung_aktueller_datenpunkt: function () {
      switch (this.szenario) {
        case "gold_rush":
          return "aktuelles Goldstück";
        case "stadtplan":
          return "aktueller Haushalt";
      }
      return "aktueller Datenpunkt";
    },
    bezeichnung_aktueller_prototyp: function () {
      switch (this.szenario) {
        case "gold_rush":
          return "aktuelles Grabungsteam";
        case "stadtplan":
          return "aktuelle U-Bahn-Station";
      }
      return "aktueller Prototyp";
    },

    animation_speed: function () {
      return this.animation_speed_range * 1;
    },
    akt_datenpunkt: function () {
      if (this.aktueller_datenpunkt < this.datenpunkte.length) {
        return this.datenpunkte[this.aktueller_datenpunkt];
      } else {
        return null;
      }
    },

    akt_prototyp: function () {
      if (this.aktueller_prototyp < this.prototypen.length) {
        return this.prototypen[this.aktueller_prototyp];
      } else {
        return null;
      }
    },
  },

  methods: {
    lade() {
      this.datensatz_2_textarea();
      this.prototypensatz_2_textarea();
    },

    datensatz_2_textarea() {
      let text_ausgabe = "";

      for (let i = 0; i < this.datenpunkte.length; i++) {
        text_ausgabe +=
          this.datenpunkte[i].x + "; " + this.datenpunkte[i].y + "\n";
      }

      this.txt_datensatz = text_ausgabe;
    },

    textarea_2_datensatz() {
      let text = this.txt_datensatz.replaceAll(" ", "");
      text = text.replaceAll("\n", "#");
      while (text.includes("##")) {
        text = text.replaceAll("##", "#");
      }

      console.log(text);
      let regex_korrekt = text.match("^((\\d)*;(\\d)*(#))*((\\d)*;(\\d)*)?$");

      if (!regex_korrekt) {
        console.log("DATENSATZ nicht korrekt!");
      } else {
        console.log("DATENSATZ korrekt!");
        let zeilen = text.split("#");
        let neuer_ds = [];

        for (let i = 0; i < zeilen.length; i++) {
          if (zeilen[i].includes(";")) {
            let zeile = zeilen[i].split(";");
            let ds = {
              x: parseInt(zeile[0]),
              y: parseInt(zeile[1]),
              color: "black",
            };

            neuer_ds.push(ds);
          }
        }
        this.datenpunkte = neuer_ds;
        this.anzahl_datenpunkte = this.datenpunkte.length;
        this.update_anzahl_datenpunkte(this.anzahl_datenpunkte);
      }
    },

    prototypensatz_2_textarea() {
      let text_ausgabe = "";

      for (let i = 0; i < this.prototypen.length; i++) {
        text_ausgabe +=
          this.prototypen[i].x + "; " + this.prototypen[i].y + "\n";
      }

      this.txt_prototypensatz = text_ausgabe;
    },

    textarea_2_prototypensatz() {
      let text = this.txt_prototypensatz.replaceAll(" ", "");
      text = text.replaceAll("\n", "#");
      while (text.includes("##")) {
        text = text.replaceAll("##", "#");
      }

      console.log(text);
      let regex_korrekt = text.match("^((\\d)*;(\\d)*(#))*((\\d)*;(\\d)*)?$");

      if (!regex_korrekt) {
        console.log("PROTOTYPENSATZ nicht korrekt!");
      } else {
        console.log("PROTOTYPENSATZ korrekt!");
        let zeilen = text.split("#");
        let neuer_ps = [];

        for (let i = 0; i < zeilen.length; i++) {
          if (zeilen[i].includes(";")) {
            let zeile = zeilen[i].split(";");
            let ps = {
              x: parseInt(zeile[0]),
              y: parseInt(zeile[1]),
              color: "blue",
            };

            neuer_ps.push(ps);
          }
        }
        this.prototypen = neuer_ps;
        this.prototypen_original = neuer_ps;
        this.anzahl_prototypen = this.prototypen.length;
        this.update_anzahl_prototypen(this.anzahl_prototypen);
      }
    },

    szenario_aendern() {
      this.loesche_zeichenflaeche();
      this.refresh();
    },

    update_anzahl_datenpunkte(new_value) {
      if (new_value >= 0) {
        console.log("angekommen." + new_value);
        this.anzahl_datenpunkte = new_value;

        while (this.datenpunkte.length > this.anzahl_datenpunkte) {
          this.datenpunkte.pop();
        }

        while (this.datenpunkte.length < this.anzahl_datenpunkte) {
          let neuer_datenpunkt = this.generiere_datenpunkt_zufaellig();
          this.datenpunkte.push(neuer_datenpunkt);
        }
        //this.update_zeichnung_child_component();
        this.datensatz_2_textarea();
        this.refresh();
      } else {
        this.anzahl_datenpunkte = 0;
      }
    },
    update_anzahl_prototypen(new_value) {
      // Original Prototypen laden
      console.log(this.prototypen_original);
      console.log(this.prototypen);
      this.prototypen = JSON.parse(JSON.stringify(this.prototypen_original));
      if (new_value >= 0) {
        console.log("angekommen." + new_value);
        this.anzahl_prototypen = new_value;

        while (this.prototypen.length > this.anzahl_prototypen) {
          this.prototypen.pop();
        }

        while (this.prototypen.length < this.anzahl_prototypen) {
          let neuer_prototyp = this.generiere_prototyp_zufaellig();
          this.prototypen.push(neuer_prototyp);
        }
        //this.update_zeichnung_child_component();
        this.prototypensatz_2_textarea();
        this.refresh();
      } else {
        this.anzahl_prototypen = 0;
        while (this.prototypen.length > this.anzahl_prototypen) {
          this.prototypen.pop();
        }
      }
      // Original Prototypen merken
      this.prototypen_original = JSON.parse(JSON.stringify(this.prototypen));
    },
    /*
    update_zeichnung_child_component() {
      //this.$refs.component_zeichnung.update_anzahlen(this.datenpunkte, this.prototypen)
      this.$refs.component_zeichnung.refresh();
      console.log("update child sent" + this.datenpunkte.length);
    },
    */
    generiere_datenpunkt_zufaellig() {
      let max_x = 800;
      let max_y = 450;
      let datenpunkt = {};

      datenpunkt.x = Math.floor(Math.random() * max_x);
      datenpunkt.y = Math.floor(Math.random() * max_y);
      datenpunkt.color = "black";

      console.log(datenpunkt);
      return datenpunkt;
    },
    generiere_prototyp_zufaellig() {
      let max_x = 800;
      let max_y = 450;
      let prototyp = {};

      prototyp.x = Math.floor(Math.random() * max_x);
      prototyp.y = Math.floor(Math.random() * max_y);
      prototyp.color = "blue";

      console.log(prototyp);
      return prototyp;
    },

    zeichne_hintergrund() {
      const bild = document.getElementById(this.aktuelles_hintergrundbild);
      console.log("background image: " + this.aktuelles_hintergrundbild);

      let bildX = 0;
      let bildY = 0;
      let breite = 800;
      let hoehe = 450;
      this.vueCanvas.drawImage(bild, bildX, bildY, breite, hoehe);
    },

    faerbe_prototypen() {
      let anzahl = this.prototypen.length;
      let farben = generateDifferentColors(anzahl);
      //colors_generation;
      console.log(anzahl + farben);

      for (let i = 0; i < this.prototypen.length; i++) {
        this.prototypen[i].color = farben[i];
        console.log(this.prototypen[i].color);
      }
    },

    faerbe_datenpunkte(alle) {
      for (let i = 0; i < this.datenpunkte.length; i++) {
        if (alle || i < this.aktueller_datenpunkt) {
          let next_prototyp = this.gib_naechstgelegener_prototyp(
            this.datenpunkte[i]
          );
          let farbe = next_prototyp.color;
          this.datenpunkte[i].color = farbe;
          console.log(farbe);
        }
      }
    },

    async refresh() {
      return new Promise((resolve) => {
        this.faerbe_prototypen();
        this.loesche_zeichenflaeche();
        this.zeichne_hintergrund();
        this.zeichne_datenpunkte(false, true);
        this.zeichne_prototypen(false);

        setTimeout(() => {
          resolve(); // Resolve the promise when the animation is done
        }, this.animation_speed); // 1-second delay
      });
    },

    loesche_zeichenflaeche() {
      this.vueCanvas.clearRect(0, 0, this.canvas.width, this.canvas.height);
    },
    zeichne_kreis(x, y, radius, fuellFarbe, randFarbe) {
      let randDicke;

      //randFarbe = 'black'
      randDicke = Math.ceil(radius / 3);

      this.vueCanvas.strokeStyle = randFarbe;
      this.vueCanvas.beginPath();
      this.vueCanvas.lineWidth = randDicke;
      this.vueCanvas.arc(x, y, radius, 0, 2 * Math.PI);
      this.vueCanvas.fillStyle = fuellFarbe;
      this.vueCanvas.fill();
      this.vueCanvas.stroke();
    },
    zeichne_x(x, y, color) {
      let staerke = 4;
      let groesse = 6;

      //ctxBaum.fillStyle = color
      this.vueCanvas.beginPath();

      this.vueCanvas.moveTo(x + groesse, y + groesse);
      this.vueCanvas.lineWidth = staerke;
      // set line color
      this.vueCanvas.strokeStyle = color;
      this.vueCanvas.lineTo(x - groesse, y - groesse);

      this.vueCanvas.moveTo(x - groesse, y + groesse);
      this.vueCanvas.lineWidth = staerke;
      // set line color
      this.vueCanvas.strokeStyle = color;
      this.vueCanvas.lineTo(x + groesse, y - groesse);

      this.vueCanvas.stroke();
    },

    zeichne_linie(x1, y1, x2, y2, farbe, staerke) {
      //ctxBaum.fillStyle = color
      this.vueCanvas.beginPath();

      this.vueCanvas.moveTo(x1, y1);
      this.vueCanvas.lineWidth = staerke;
      // set line color
      this.vueCanvas.strokeStyle = farbe;
      this.vueCanvas.lineTo(x2, y2);

      this.vueCanvas.stroke();
    },

    zeichne_linie_datenpunkt_naechstgelegener_prototyp(datenpunkt) {
      let farbe = "red";
      let staerke = 2;
      let prototyp = this.gib_naechstgelegener_prototyp(datenpunkt);

      if (datenpunkt != null && prototyp != null) {
        this.zeichne_linie(
          datenpunkt.x,
          datenpunkt.y,
          prototyp.x,
          prototyp.y,
          farbe,
          staerke
        );
      }
    },

    zeichne_linie_datenpunkt_prototyp(datenpunkt, prototyp, farbe, staerke) {
      if (datenpunkt != null && prototyp != null) {
        this.zeichne_linie(
          datenpunkt.x,
          datenpunkt.y,
          prototyp.x,
          prototyp.y,
          farbe,
          staerke
        );
      }
    },

    zeige_line_an() {
      this.zeichne_linie_datenpunkt_prototyp(
        this.datenpunkte[this.aktueller_datenpunkt],
        this.prototypen[this.aktueller_prototyp]
      );
    },

    zeichne_datenpunkte(markierung, zeichne_alle) {
      let radius = 8;
      let i = 0;
      let hightlight_farbe = "lightgreen";

      this.datenpunkte.forEach((element) => {
        if (markierung && i == this.aktueller_datenpunkt) {
          this.zeichne_kreis(
            element.x,
            element.y,
            radius * 1.5,
            hightlight_farbe,
            hightlight_farbe
          );
        }

        let kreis_farbe = element.color; //"black";
        /*
        if (i < this.aktueller_datenpunkt) {
          kreis_farbe = element.color;
        }
        */

        if (zeichne_alle || i < this.aktueller_datenpunkt) {
          this.zeichne_kreis(
            element.x,
            element.y,
            radius,
            kreis_farbe,
            "white"
          );
        }

        i++;
      });
    },

    zeichne_prototypen(markierung) {
      let i = 0;
      let hightlight_farbe;
      let radius;

      this.prototypen.forEach((element) => {
        hightlight_farbe = "white";
        radius = 14;

        if (markierung && i == this.aktueller_prototyp) {
          hightlight_farbe = "lightgreen";
          let radius_markierung = radius + 5;
          this.zeichne_kreis(
            element.x,
            element.y,
            radius_markierung,
            "white",
            hightlight_farbe
          );
        }

        this.zeichne_kreis(
          element.x,
          element.y,
          radius,
          "white",
          element.color
        );

        this.zeichne_x(element.x, element.y, element.color);
        console.log(element.color);

        i++;
      });
    },
    naechster_datenpunkt() {
      if (this.aktueller_datenpunkt < this.datenpunkte.length - 1) {
        this.aktueller_datenpunkt++;
        this.refresh();
        this.zeichne_datenpunkte(true, true);
      }
    },
    voriger_datenpunkt() {
      if (this.aktueller_datenpunkt > 0) {
        this.aktueller_datenpunkt--;
        this.refresh();
        this.zeichne_datenpunkte(true, true);
      }
    },
    naechster_prototyp() {
      this.aktueller_prototyp++;
      this.refresh();
      this.zeichne_prototypen(true);
    },
    voriger_prototyp() {
      this.aktueller_prototyp--;
      this.refresh();
      this.zeichne_prototypen(true);
    },
    gib_distanz(datenpunkt, prototyp) {
      let x1 = datenpunkt.x;
      let y1 = datenpunkt.y;
      let x2 = prototyp.x;
      let y2 = prototyp.y;
      return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2));
    },
    gib_naechstgelegener_prototyp(datenpunkt) {
      if (datenpunkt == null) {
        return null;
      }
      let naechstgelegener_prototyp = null;
      let min_distanz = null;
      // pruefe alle prototypen und merke die naechste
      for (let i = 0; i < this.prototypen.length; i++) {
        let akt_prototyp = this.prototypen[i];
        let akt_distanz = this.gib_distanz(datenpunkt, akt_prototyp);
        if (naechstgelegener_prototyp == null || akt_distanz < min_distanz) {
          naechstgelegener_prototyp = akt_prototyp;
          min_distanz = akt_distanz;
        }
      }
      return naechstgelegener_prototyp;
    },

    berechne_neue_pos_haelfte(x1, y1, x2, y2) {
      let neue_pos = {
        x: (x1 + x2) / 2,
        y: (y1 + y2) / 2,
      };
      return neue_pos;
    },

    //////////////////////////////////////////
    pausiere_animation() {
      this.paused = true;
    },
    kurz_zeichne_linie_datenpunkt_prototyp() {
      // pruefe_aktuelle
      this.zeichne_linie_datenpunkt_prototyp(
        this.akt_datenpunkt,
        this.akt_prototyp,
        "lightgreen",
        4
      );
    },

    existiert_kuerzere_Distanz() {
      // bisher naechstgelegener Prototyp
      let akt_distanz = this.gib_distanz(
        this.akt_datenpunkt,
        this.akt_prototyp
      );

      // naechsten aktualisieren
      if (
        this.naechstgelegener_prototyp == null ||
        akt_distanz < this.naechstgelegener_prototyp_distanz
      ) {
        this.naechstgelegener_prototyp = this.akt_prototyp;
        this.naechstgelegener_prototyp_distanz = akt_distanz;
        return true;
      } else {
        return false;
      }
    },

    verarbeite_kuerzere_distanz() {
      if (this.existiert_kuerzere_Distanz()) {
        this.zeichne_kuerzeste_Distanz();
      }
    },

    kurz_zeichne_linie_datenpunkt_naechstgelegener_prototyp() {
      this.zeichne_linie_datenpunkt_prototyp(
        this.akt_datenpunkt,
        this.naechstgelegener_prototyp,
        "red",
        3
      );
    },
    async starte_animation_alle() {
      this.loesche_zeichenflaeche();
      this.aktueller_datenpunkt = 0;

      for (let i = 0; i < this.datenpunkte.length; i++) {
        this.aktueller_datenpunkt = i;
        await this.starte_animation();
      }

      this.faerbe_datenpunkte(true);

      this.loesche_zeichenflaeche();
      this.zeichne_hintergrund();
      this.zeichne_datenpunkte(false, true);
      this.zeichne_prototypen(false);

      //this.zeige_naechsten_bekannten_prototyp();
    },

    async starte_animation() {
      this.aktueller_prototyp = 0;
      this.naechstgelegener_prototyp = null;
      this.naechstgelegener_prototyp_distanz = null;
      this.paused = false;

      await this.mainAnimationLoop();
    },

    async mainAnimationLoop() {
      // Call the first animation and wait for it to finish

      let alle_prototypen_verarbeitet = false;
      while (!alle_prototypen_verarbeitet) {
        this.zeichne_hintergrund();
        this.faerbe_datenpunkte(false);

        if (this.aktueller_prototyp == 0) {
          this.zeichne_datenpunkte(false, true);
          await this.zeichne_prototypen(false);
        }

        await this.zeige_prototyp();
        await this.zeige_naechsten_bekannten_prototyp();

        if (this.existiert_kuerzere_Distanz()) {
          this.loesche_zeichenflaeche();
          this.zeichne_hintergrund();
          this.zeichne_datenpunkte(false, true);
          this.zeichne_prototypen(false);
          await this.zeige_naechsten_bekannten_prototyp();
        }

        if (this.aktueller_prototyp < this.prototypen.length) {
          if (this.aktueller_prototyp == this.prototypen.length - 1) {
            alle_prototypen_verarbeitet = true;
          } else {
            this.aktueller_prototyp++;
          }
        }
      }

      // Schlussbild
      this.loesche_zeichenflaeche();
      this.faerbe_datenpunkte(false);
      this.zeichne_datenpunkte(false, true);
      this.zeichne_prototypen(false);

      this.zeige_naechsten_bekannten_prototyp();

      // prototyp verschieben
      await this.aktualisiere_pos_prototyp();
    },

    async pausiere(zeitspanne) {
      return new Promise((resolve) => {
        // nichts tun

        // Simulate some delay (you can replace this with actual animation code)
        setTimeout(() => {
          resolve(); // Resolve the promise when the animation is done
        }, zeitspanne); // delay for zeitspanne
      });
    },

    zeige_prototyp() {
      return new Promise((resolve) => {
        // Your animation code here
        //this.loesche_zeichenflaeche();

        this.kurz_zeichne_linie_datenpunkt_prototyp();
        this.zeige_naechsten_bekannten_prototyp();
        this.zeichne_datenpunkte(true, true);
        this.zeichne_prototypen(true);

        // Simulate some delay (you can replace this with actual animation code)
        setTimeout(() => {
          resolve(); // Resolve the promise when the animation is done
        }, this.animation_speed); // 1-second delay
      });
    },

    zeige_naechsten_bekannten_prototyp() {
      return new Promise((resolve) => {
        // Your animation code here
        if (
          this.naechstgelegener_prototyp != null &&
          this.akt_datenpunkt != null
        ) {
          this.kurz_zeichne_linie_datenpunkt_naechstgelegener_prototyp();
          this.zeichne_datenpunkte(true, true);
          this.zeichne_prototypen(true);
        }

        // Simulate some delay (you can replace this with actual animation code)
        setTimeout(() => {
          resolve(); // Resolve the promise when the animation is done
        }, this.animation_speed); // 1-second delay
      });
    },

    aktualisiere_pos_prototyp() {
      return new Promise((resolve) => {
        this.faerbe_datenpunkte(false);
        this.animieren();

        setTimeout(() => {
          resolve(); // Resolve the promise when the animation is done
        }, this.animation_speed * 2);
      });
    },
    async animieren() {
      this.letzte_prototyp = this.naechstgelegener_prototyp;
      let schritte = 50;
      if (this.animation_speed < 10) {
        schritte = 1;
      }
      let i = 0;

      let x_neu =
        (this.akt_datenpunkt.x + this.naechstgelegener_prototyp.x) / 2;
      let y_neu =
        (this.akt_datenpunkt.y + this.naechstgelegener_prototyp.y) / 2;

      let delta_x =
        (this.akt_datenpunkt.x - this.naechstgelegener_prototyp.x) /
        2 /
        schritte;
      let delta_y =
        (this.akt_datenpunkt.y - this.naechstgelegener_prototyp.y) /
        2 /
        schritte;

      // zeichnen definieren
      var draw = () => {
        try {
          this.naechstgelegener_prototyp.x += delta_x;
          this.naechstgelegener_prototyp.y += delta_y;

          this.loesche_zeichenflaeche();
          this.zeichne_hintergrund();

          this.kurz_zeichne_linie_datenpunkt_naechstgelegener_prototyp();

          this.zeichne_datenpunkte(true, true);
          this.zeichne_prototypen(true);

          i++;

          if (i < schritte) {
            //timestamp = Date.now();
            requestAnimationFrame(draw);
          } else {
            this.naechstgelegener_prototyp.x = x_neu;
            this.naechstgelegener_prototyp.y = y_neu;
            this.refresh();
          }
        } catch (error) {
          //console.error("Caught custom exception:", error.message);
          this.letzte_prototyp.x = x_neu;
          this.letzte_prototyp.y = y_neu;
          this.refresh();
        }
      };
      // Zeichnen aufrufen
      draw();
    },

    szenario_zuruecksetzen() {
      this.update_anzahl_datenpunkte(this.anzahl_datenpunkte);
      this.update_anzahl_prototypen(this.anzahl_prototypen);

      this.aktueller_datenpunkt = 0;

      for (let i = 0; i < this.datenpunkte.length; i++) {
        let next_prototyp = this.gib_naechstgelegener_prototyp(
          this.datenpunkte[i]
        );
        this.datenpunkte[i].color = "#000000";
      }

      this.loesche_zeichenflaeche();
      this.refresh();
      this.zeichne_hintergrund();
      this.zeichne_prototypen(false);
      this.zeichne_datenpunkte(false, true);
      console.log("Page completed with image and files!");
    },
  },

  mounted() {
    var c = document.getElementById("c");
    var ctx = c.getContext("2d");
    this.canvas = c;
    this.vueCanvas = ctx;
    this.aktueller_prototyp = 0;

    this.lade();
    this.update_anzahl_datenpunkte(this.anzahl_datenpunkte);
    this.update_anzahl_prototypen(this.anzahl_prototypen);

    document.onreadystatechange = () => {
      if (document.readyState == "complete") {
        this.refresh();
        this.zeichne_hintergrund();
        this.zeichne_prototypen(false);
        this.zeichne_datenpunkte(false, true);
        console.log("Page completed with image and files!");
        // fetch to next page or some code

        var coll = document.getElementsByClassName("collapsible");
        var i;

        for (i = 0; i < coll.length; i++) {
          coll[i].addEventListener("click", function () {
            this.classList.toggle("active");
            var content = this.nextElementSibling;

            if (content.style.maxHeight) {
              content.style.maxHeight = null;
            } else {
              content.style.maxHeight = content.scrollHeight + "px";
              let content0 = document.getElementById("content0");
              let content1 = document.getElementById("content1");
              if (content == content1) {
                console.log("gefunden");
                content0.style.maxHeight =
                  content0.scrollHeight + content.scrollHeight + "px";
              }
            }
          });
        }
      }
    };
  },
};

//------------------------------------------------------------
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

* {
  box-sizing: border-box;
}

.row {
  display: flex;
}

/* Create two equal columns that sits next to each other */
.column {
  flex: 50%;
  padding: 10px;
 /*border: solid black 1px;
  /*height: 300px; /* Should be removed. Only for demonstration */
}

.collapsible {
  background-color: #777;
  color: white;
  cursor: pointer;
  padding: 18px;
  width: 100%;
  border: none;
  text-align: left;
  outline: none;
  font-size: 15px;
}

.active,
.collapsible:hover {
  background-color: #555;
}

.collapsible:after {
  content: "\002B";
  color: white;
  font-weight: bold;
  float: right;
  margin-left: 5px;
}

.active:after {
  content: "\2212";
}

.content {
  padding: 0 18px;
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.2s ease-out;
  background-color: #f1f1f1;
}

.btn {
  display: inline-block;
  font-weight: 400;
  color: #212529;
  text-align: center;
  vertical-align: middle;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
  background-color: transparent;
  border: 1px solid transparent;
  padding: 0.375rem 0.75rem;
  font-size: 1rem;
  line-height: 1.5;
  border-radius: 0.25rem;
  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out,
    border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
}

.btn:not(:disabled):not(.disabled) {
  cursor: pointer;
}

.btn-primary {
  color: #fff;
  background-color: #007bff;
  border-color: #007bff;
}
</style>
