function TeilnehmerPflicht(pName) {
    var self = this;
    self.name = ko.observable(pName);
    self.vorname = ko.observable();
    self.email = ko.observable();
    self.istkind = ko.observable(false);
    self.gebdat = ko.observable();
    self.geschlecht = ko.observable();
    self.nurplz = ko.observable();
    self.nurort = ko.observable();
    self.nurstrasse = ko.observable();
    self.nurhausnr = ko.observable();
    self.zahlmethode = ko.observable();
    self.arykennzeichenJS = ko.observableArray();
    self.spendenbetrag = ko.observable();
	//self.alterskl = ko.observableArray();
}

//datestr = Geburtsdatum des Teilnehmers als Observable, atdate = '' wenn aktuelles Datum gewünscht oder Kursbeginndatum (als String) wenn Alter zu Kursbeginn ermittelt werden soll
function calculateAge(gebdat, atdate) {
    if(typeof(gebdat) == 'undefined' || gebdat == undefined) {
      return 0;
    }

    if(typeof(gebdat) == 'function') {
      gebdat = gebdat(); //weil es ein Observable ist
    }
    
    //Tag, Monat und Jahr aus dem Geburtsdatum des Teilnehmers extrahieren
    var dateary = gebdat.split(".");
    var gebdatYear = parseInt(dateary[2]);
    var gebdatMonth = parseInt(dateary[1]);
    var gebdatDay = parseInt(dateary[0]);
    
    //übergebenes Geburtsdatum fehlerhaft
    if( gebdatYear == '' || gebdatMonth == '' || gebdatDay == '' ) {
      return 0;
    }
    
    var toYear = 1;
    var toMonth = 1;
    var toDay = 1;
    var futureDate = undefined;
    //Das Datum, an dem das Alter des Teilnehmers gefragt ist
    if(typeof(atdate) != 'undefined') { //als Datumsobjekt
      var splittedDate = atdate.split(".");
      toDay = splittedDate[0];
      toMonth = splittedDate[1]-1;
      toYear = splittedDate[2];
      futureDate = new Date(toYear, toMonth, toDay, '0', '0', '00');
    }
    
    if( futureDate != undefined && typeof(futureDate) != 'undefined' && futureDate instanceof Date ) { //Tag, Monat und Jahr des Datums, an dem das Alter des Teilnehmers gefragt ist
      toYear = futureDate.getFullYear();
      toMonth = futureDate.getMonth() + 1;
      toDay = futureDate.getDate();
    }
    else { //Das Alter des Teilnehmers am heutigen Tag ist gefragt
      var currentDate = new Date();
      toYear = currentDate.getFullYear();
      toMonth = currentDate.getMonth() + 1;
      toDay = currentDate.getDate();
    }
    
    //Alter berechnen
    var age = toYear - gebdatYear;
    if (toMonth > gebdatMonth) {
        return age;
    } else {
        if (toDay >= gebdatDay && toMonth == gebdatMonth) { //Wenn ich im gleichen Monat geboren bin, dann bin ich schon alt genug, wenn der Kurs später als mein Tag startet
            return age;
        } else { //Wenn ich in einem späteren Monat geboren bin
            age--;
            return age;
        }
    }
}

function Kurs(pKnr, pBeginn, pGebuehr, pSettings) {
    var self = this;
    self.knr = pKnr;
    self.gebuehrGeparsed = pGebuehr;
    self.beginn_dat = pBeginn;
    
    self.weitereTeilnehmer = ko.observableArray();
    if (typeof(pSettings) === 'undefined' || pSettings.zahlerInitialInKursen) {
      self.hauptTnAuch = ko.observable(1);
    }
    else {
      self.hauptTnAuch = ko.observable(0);
    }
    self.beleghistorie1 = ko.observable(); //Für FBS Bonn standardmäßig auf 0,00 setzen!
    self.beleghistorie2 = ko.observable();
    self.beleghistorie3 = ko.observable();
    self.beleghistorie4 = ko.observable();
    self.beleghistorie5 = ko.observable();
    self.beleghistorie6 = ko.observable();
    self.zahlplan = ko.observable(); //Vom Teilnehmer konkret ausgewählter Zahlplan
    self.zahlplaene = ko.observableArray(); //Alle Zahlpläne, die beim Kurs in KuferSQL hinterlegt wurden
    
    self.addWeiteren = function(pTeilnehmer) {
      self.weitereTeilnehmer.push(pTeilnehmer);
    };
    self.removeWeiteren = function(pTn) {
      self.weitereTeilnehmer.remove(pTn);
      /*if(self.weitereTeilnehmer.length < 1 && self.hauptTn.geschlecht() != 'F') {
          self.hauptTnAuch(1);
      }*/
    };
    
    self.hasKennzeichen = function(zuPruefendesKennzeichen) {
      if( self.kennzeichen == undefined ) {
        return false;
      }
      for (var j = 0; j < self.kennzeichen.length; j++ ) {
        if( self.kennzeichen[j] == zuPruefendesKennzeichen ) {
          return true;
        }
      }
	  return false;
    };
    
    //Für FBS Bonn
    //Gibt zurück, wie viel die Schwellengebühr multipliziert mit der Anzahl der Teilnehmer beträgt.
    //Der Funktion muss die Nummer der Schwellengebühr übergeben werden, d.h. ob es sich um self.geb_schw1 (1 übergeben) oder self.geb_schw2 (2 übergeben) handelt.
    self.schwelleAnzahlTeilnehmerProdukt = function(schwellengebNr) {
      var schwellengeb = (schwellengebNr == 1) ? self.geb_schw1 : (schwellengebNr == 2) ? self.geb_schw2 : 0;
      schwellengeb = schwellengeb.replace(',', '.');
      var anzHauptTn = (self.hauptTnAuch() > 0)? 1 : 0;
      var weitereTeilnehmerLength = self.weitereTeilnehmer().length;
      if( weitereTeilnehmerLength > 0 && self.weitereTeilnehmer()[0].istkind() ) {
        weitereTeilnehmerLength = weitereTeilnehmerLength - 1; //Das erste Kind soll kostenlos sein. Weitere Kinder kosten die volle Gebuehr.
      }
      var rueckgabe = schwellengeb * (weitereTeilnehmerLength + anzHauptTn);
      return rueckgabe;
    };
    
    self.showSchwelleAnzahlTeilnehmerProdukt = function(schwellengebNr) {
      var rueckgabe = self.schwelleAnzahlTeilnehmerProdukt(schwellengebNr);
      rueckgabe = rueckgabe.toFixed(2).toString();
      rueckgabe = rueckgabe.replace('.', ',');
      return rueckgabe;
    };
}


function KwAnmeldeViewModel() {//So ähnlich wie ein Konstruktor einer Klasse. Hier wird alles initialisiert.
    var self = this;
    self.hauptTn = ko.observable(new TeilnehmerPflicht());
    self.kurse = ko.observableArray();
    self.einstellungen = ko.observable("");

    self.sichtSettings = { weiterePflicht: "name, vorname, email", kinderPflicht: "vorname", zahlerInitialInKursen : 1};
    if (typeof(kw_anmSettings) !== 'undefined') {
      self.sichtSettings = jQuery.extend(self.sichtSettings, kw_anmSettings);
    }
    self.weiterePflichtfelder = self.sichtSettings.weiterePflicht.replace(/\s/g,'').split(",");
    self.kinderPflichtfelder  = self.sichtSettings.kinderPflicht.replace(/\s/g,'').split(",");
	
    //DemoDaten
    /*self.kurse.push(new Kurs("161-3207", "02.10.2016", 10.00));
    self.kurse.push(new Kurs("152-3104", "15.07.2016", 25.00));
    var tn = new TeilnehmerPflicht();
    tn.name('aaname');
    tn.vorname('aavorname');
    self.kurse()[0].addWeiteren(tn);
    tn = new TeilnehmerPflicht();
    tn.name('bbname');
    tn.vorname('bbvorname');
    self.kurse()[0].addWeiteren(tn);
    tn = new TeilnehmerPflicht();
    tn.name('ccname');
    tn.vorname('ccvorname');
    self.kurse()[1].addWeiteren(tn);
    */
    
    self.removeHauptTn = function(pKurs) {
      pKurs.hauptTnAuch(0);
      pKurs.weitereTeilnehmer()[0].email(self.hauptTn().email());
    };
    
    self.setHauptTn = function(pKurs) {
      pKurs.hauptTnAuch(1);
      pKurs.weitereTeilnehmer()[0].email("");
    };
        
    self.firmaBehandlung = function() {
      for (var i = 0; i < self.kurse().length ; i++) {
        var kurs = self.kurse()[i];
        kurs.hauptTnAuch(0);       
      }
      return true;
    };
    
    self.menschBehandlung = function() {
      for (var i = 0; i < self.kurse().length ; i++) {
        var kurs = self.kurse()[i];
        kurs.hauptTnAuch(1);
      }
      return true;
    };
    
    self.disableAddWeiteren = function(kurs) { //Button weiterer Teilnehmer ausgrauen? true = Ja, ausgrauen! 
      var einstellungen = self.einstellungen;
      if( einstellungen().paypalisexpressco ) {
        return true;
      }
      if(einstellungen().nurnormaleanmeldearten) {
        return true;
      }
      if( !einstellungen().nurerlaubteanmeldearten ) {
        return false;
      }
      /*if( kurs.webflags == 4 && kurs.weitereTeilnehmer().length > 0) { //speziell für Friedrichshafen
        return true;
      }*/
      
      //Paaranmeldungen dürfen nicht mehr als 2 Teilnehmer haben. Das wird erst einmal für Kurse gemacht, die NUR die Paaranmeldung freigegeben haben und sonst nichts - z.B. Tanzkurse.
      //Mischung mit z.B. Paar- und Firmen- oder Paar- und Eltern-Kind-Anmeldungen werden noch nicht abgefangen. Dazu wäre das Geschlecht des Hauptteilnehmers und der Haken "Kind"
      //beim ersten weiteren TN zu untersuchen.
      //Außerdem sollte es, wenn man den Zahler aus dem Kurs streicht, später möglich sein, dass man dann zwei weitere Teilnehmer hinzufügt.
      if( (kurs.webflags == 32) && (typeof(kurs) != 'undefined' && typeof(kurs.weitereTeilnehmer()) != 'undefined' && kurs.weitereTeilnehmer().length > 0) ) {
        return true;
      }
      var vergleichAlleFlags = (kurs.webflags & 63);
      return (vergleichAlleFlags <= 2); //Für Kurse, bei denen nur normale Anmeldung (webflag 2 oder 0) oder keine Anmeldung (webflag 1) erlaubt sind, muss der weitere-Teilnehmer-Button deaktiviert werden.
    };
    
    self.isKursMitKennzeichenXimWK = function(zuPruefendesKennzeichen) {
      for (var i = 0; i < self.kurse().length ; i++) {
        var kurs = self.kurse()[i];
        if( kurs.hasKennzeichen(zuPruefendesKennzeichen) ) {
          return true;
        }
      }
      return false;
    };
    
    self.isHauptTnFirma = function()
    {
      if( self.hauptTn().geschlecht == undefined ) {
        return false;
      }
      if( self.hauptTn().geschlecht() == "F") {
        self.hauptTn().vorname("");
        return true;
      }
      return false;
    };
    
    /*self.isHauptTnAusgefuelltOeffneWeiteren = function()
    {
      return true;
      if( self.hauptTn().name != undefined && self.hauptTn().name() != '') {
        if( self.hauptTn().vorname != undefined && self.hauptTn().vorname() != '') {
          if( self.kurse != undefined && self.kurse().length > 0 && self.kurse()[0].weitereTeilnehmer != undefined && self.kurse()[0].weitereTeilnehmer().length < 1 ) {
            self.addWeiteren(self.kurse()[0]);
            return true;
          }
        }
      }
      return false;
    }*/
    
    self.nurKinderKurs = function() { //Beim Kurs in KuferSQL wurde nur genau Eltern-Kind-Anmeldung angehakt.
      var einstellungen = self.einstellungen;
      if(einstellungen().nurnormaleanmeldearten || !einstellungen().nurerlaubteanmeldearten) { //Die Einstellungen im Webadmin übersteuern die Hinterlegung in KuferSQL.
        return false;
      }
      kurs = self.geradeEditierterKurs();
      var nurKinderFlag = (kurs.webflags & 63);
      
      return (nurKinderFlag == 4); //Ist es nur ein Kinderkurs? Ja, wenn es 4 ist.
    };
    
    self.auchKinderKurs = function() { //Z.B. sind in KuferSQL Mehrfach- und Eltern-Kind-Anmeldung ausgewählt. Dann darf man zu dem Kurs AUCH Kinder anmelden, wenn man möchte.
      if( self.geradeEditierterKurs() == false ) {
        return false;
      }
      var einstellungen = self.einstellungen;
      if(einstellungen().nurnormaleanmeldearten) {
        return false;
      }
      
      if( !einstellungen().nurerlaubteanmeldearten ) {
        return true;
      }
      kurs = self.geradeEditierterKurs();
      if( ((kurs.webflags & 4) > 0) ) {
        return true;
      }
      
      return false;
    }

        
//Wenn beim ersten weiteren TN die Kindercheckbox angehakt ist, dann soll das auch für den zweiten und alle weiteren Teilnehmer gelten. Dort ist dann die Checkbox ausgegraut. 
//Man kann immer nur beim ersten Teilnehmer entscheiden, ob es (und damit alle weiteren Teilnehmer des Kurses) ein Kind ist oder nicht.
    self.checkKind = function(checked)
	{
      var einstellungen = self.einstellungen;
      //Wenn nur normale Anmeldungen zulässig sind, sollte er hier gar nicht vorbei kommen, zur Sicherheit wird die Kinder-Checkbox trotzdem nicht angehakt
      if( einstellungen().nurnormaleanmeldearten ) {
        return false;
      }

      if( self.geradeEditierterKurs() == false ) {
        return false;
      }
      
      //Wenn sowieso nur Eltern-Kind-Anmeldung (Webflag 4) (und normale Anmeldungen (Webflag 6)) zulässig sind, dann auch den ersten weiteren TN direkt anhaken
      if( (self.geradeEditierterKurs().webflags == 4 || self.geradeEditierterKurs().webflags == 6) && (einstellungen().nurerlaubteanmeldearten) ) {
        self.geradeEditierterWeitererTn().istkind(true);
        return true;
      }
	  // Erster weiterer TN wird bearbeitet
      
      var ersterWeiterer = self.geradeEditierterKurs().weitereTeilnehmer()[0];
	  if(!ersterWeiterer) {
		self.geradeEditierterWeitererTn().istkind(checked);
		return checked;
	  }
	  
	  // Weiterer-TN-Formular wird gerade geöffnet: Gespeicherten Wert zurückgeben und nicht ändern.
	  if(!self.wirdGeradeEinWeitererEditiert()) {
		return self.geradeEditierterWeitererTn().istkind();
	  }
	  
	  // Erster weiterer TN wird bearbeitet
	  if(self.geradeEditierterWeitererTn() == ersterWeiterer) {
		self.geradeEditierterWeitererTn().istkind(checked);
        if(checked) { //Wenn Haken gesetzt wird, dann muss der Hauptteilnehmer am Kurs teilnehmen
          self.geradeEditierterKurs().hauptTnAuch(1);
        }
		return checked;
	  }
	  
	  // 2. oder höherer TN wird bearbeitet
      var rueckgabe = ersterWeiterer.istkind();
	  self.geradeEditierterWeitererTn().istkind(rueckgabe);
      return rueckgabe;
    }
    
    self.istErsterKind = function(kurs) {
      if( typeof(kurs.weitereTeilnehmer) != 'undefined' && kurs.weitereTeilnehmer().length > 0 && kurs.weitereTeilnehmer()[0].istkind() ) {
          return true;
      }
      return false;
	}
    
    self.disableKind = function() {
      if( self.geradeEditierterKurs() == false ) {
        return false;
      }
      
      var weitereTn = self.geradeEditierterKurs().weitereTeilnehmer();
      var einstellungen = self.einstellungen;
      if( einstellungen().nurnormaleanmeldearten ) {
        return true;
      }
      //Wenn nur Eltern-Kind-Anmeldung oder nur Eltern-Kind+Normal, dann ist der weitere TN immer ein Kind
      if( (self.geradeEditierterKurs().webflags == 4 || self.geradeEditierterKurs().webflags == 6) && (einstellungen().nurerlaubteanmeldearten) ) {
        return true; //Man darf also nicht entscheiden, ob es ein Kind ist, sondern es muss definitiv ein Kind sein.
      }
      if (weitereTn.length == 0) {
        return false;
      }
      return (self.geradeEditierterWeitererTn() != weitereTn[0]);
    }
    
    self.kinderErlaubt = function() { //Scheint so ziemlich das Gleiche zu machen wie auchKinderKurs. Kann theoretisch weggelassen werden, wird aber aktuell in den Sichten schon benutzt.
      var einstellungen = self.einstellungen;
      if( einstellungen().nurnormaleanmeldearten ) {
        return false;
      }
      if( !einstellungen().nurerlaubteanmeldearten ) {
        return true;
      }
      return ((self.geradeEditierterKurs().webflags & 4) > 0);
    }
    
    //speziell für Friedrichshafen VHS
    self.veranstaltungsArtDreiImWK = function(kurse) {
      //Ja, den 0. Kurs zu prüfen reicht, weil bei Friedrichshafen ein Mischen der Veranstaltungsart 3 mit anderen nicht möglich ist.
      if( typeof(kurse) != 'undefined' && typeof(kurse) == 'function' && kurse().length > 0 && kurse()[0].kart_key == '03' ) {
        return true;
      }
      else {
        return false;
      }
	}
    
    self.checkKurseAbsendbar = function() { //Müssen weitere Teilnehmer angegeben werden? Sind diese bei allen Kursen angegeben, bei denen dies nötig ist?
      if( self.isHauptTnFirma() ) {
        //Zur Sicherheit noch mal triggern, damit folgender Fall nicht auftreten kann:
        //Ein Kurs mit weiterem Teilnehmer bereits im Warenkorb und Geschlecht Firma wurde in Anminfo gespeichert (durch Klick auf "Weiter")
        //Weiterer Kurs wird in Warenkorb gelebt
        //In der Anmeldung ist der HauptTN mit Geschlecht Firma nicht aus dem Kurs gestrichen und der Weiter-Button nicht ausgegraut.
        self.firmaBehandlung();
      }
      var einstellungen = self.einstellungen;
      if(einstellungen().nurerlaubteanmeldearten) {
        for (var i = 0; i < self.kurse().length ; i++) {
          var kurs = self.kurse()[i];
          //Bei Mehrfachanmeldung, Eltern-Kind-Anmeldung, Paar-Anmeldung und Firmenanmeldung muss ein weiterer Teilnehmer hinzugefügt werden
          if( ((kurs.webflags & 2) !== 2) && (kurs.webflags != 0) && (kurs.weitereTeilnehmer().length < 1) ) {
            return false;
          }
          /*if( kurs.hauptTnAuch() == 0 ) {
            if( kurs.weitereTeilnehmer().length < 1 ) {
              return false;
            }
          }*/
        }
      }
      //Folgender Block: Es nimmt bisher niemand am Kurs teil, also Weiter-Button nicht freigeben
      if( (typeof(self.hauptTn().geschlecht) == "function") ) {
        for (var i = 0; i < self.kurse().length ; i++) {
          var kurs = self.kurse()[i];
          if( (!kurs.hauptTnAuch() || kurs.hauptTnAuch() == 0) && (kurs.weitereTeilnehmer().length < 1) ) {
            return false;
          }
        }
      }
      
      return self.isEPayHauptTnAuch(); //Das E-Payment ist nur okay, wenn der Zahler an allen Kursen teilnimmt.
    }
    
    self.isEPayHauptTnAuch = function() { //Kann z.B. auch in Sicht 504 benutzt werden, um eine Hinweismeldung anzuzeigen.
      if( typeof(self.hauptTn().zahlmethode()) != "undefined" && self.hauptTn().zahlmethode() != '' ) {
        if( self.hauptTn().geschlecht != "undefined" && self.hauptTn().geschlecht() == 'F' ) {
          return true;
        }
        for (var i = 0; i < self.kurse().length ; i++) {
          var kurs = self.kurse()[i];
          if( (!kurs.hauptTnAuch() || kurs.hauptTnAuch() == 0) ) {
            return false;
          }
        }
      }
      return true;
    }
    
    //Für Bonn FBS
    //Schaut, ob die vom Nutzer gewählte Wunschgebühr zwischen der minimal und maximal zulässigen Gebühr liegt.
    //Dient zum Deaktivieren des Weiter-Buttons.
    self.checkKurseAbsendbarBeleghistorie1ZwischenSchwellengebuehren = function() {
      for (var i = 0; i < self.kurse().length ; i++) {
        var kurs = self.kurse()[i];
        if(kurs.geb_schw1 === "0,00" && kurs.geb_schw2 === "0,00") {
          kurs.beleghistorie1("0,00");
        }
        if( typeof(kurs.beleghistorie1) == 'undefined' || typeof(kurs.beleghistorie1()) == 'undefined' || kurs.beleghistorie1() == '' ) {
          return false;
        }
        else {
          var schwellenAnzahlTeilnehmerProdukt1 = kurs.schwelleAnzahlTeilnehmerProdukt(1);
          var schwellenAnzahlTeilnehmerProdukt2 = kurs.schwelleAnzahlTeilnehmerProdukt(2);
          
          if( kurs.beleghistorie1().replace(/,/g, '.') < schwellenAnzahlTeilnehmerProdukt1
                  || kurs.beleghistorie1().replace(/,/g, '.') > schwellenAnzahlTeilnehmerProdukt2 ) {
            return false;
          }
        }
      }
      return true;
    }
    
    self.checkKurseAbsendbarAlterHauptTn = function() {
      var einstellungen = self.einstellungen;
      var alterHauptTn = 0;
      for (var i = 0; i < self.kurse().length ; i++) {
        var kurs = self.kurse()[i];
        alterHauptTn = 0;
        if( typeof( self.hauptTn().gebdat() ) !== "undefined" ) {
          alterHauptTn = calculateAge(self.hauptTn().gebdat(),kurs.beginn_dat);
        }
        if( alterHauptTn == 0 ) {
          return true; //Geburtsdatum wurde noch nicht ausgefüllt. Dann kommt man sowieso nicht auf die Kontrollseite, wenn das Geburtsdatum ein Pflichtfeld ist
        }
        if( kurs.empfohlenesalterpflicht && (!(einstellungen.nurerlaubteanmeldearten && kurs.webflags == 4) || einstellungen.nurnormaleanmeldearten) ) {
          if( kurs.hauptTnAuch() == 1 && (kurs.altervon > alterHauptTn || kurs.alterbis < alterHauptTn) && kurs.alterbis != 0 ) {
            return false; //Es gibt also mindestens einen Kurs, für den der Weiter-Button ausgegraut werden muss!
          }
        }
      }
      return true; //keinen Kurs gefunden, der den Weiter-Button verbieten würde
    }
    
    self.submitInfo = function(element) { //Wenn man die Maus über den Weiter-Button hält, dann erscheint eine Erklärung, warum er ausgegraut ist.
      if( !self.checkKurseAbsendbar() ) {
        element.title = "Es sind nicht bei allen Kursen Teilnehmer angegeben.";
      }
      else if( self.weitererTnWirdEditiert() ) {
        element.title = "Es wird noch ein weiterer Teilnehmer bearbeitet.";
      }
      else {
         element.title = "Weiter im Anmeldevorgang";
      }
    }
    
    self.removeKurs = function(pKurs) { //Mülltonnen sind sowieso nicht mehr in der Sicht, also ist diese Funktion egal.
      if (self.kurse().length > 1) {
        self.kurse.remove(pKurs);
      }
      else
      { 
        alert ("Um den letzten Kurs zu entfernen, verlassen Sie die Anmeldung und tun Sie dies im Warenkorb.");
      }
    };
    
    //"Hilfsvariablen" zum Einfügen/Editieren eines weiteren Tns
    self.geradeEditierterWeitererTn = ko.observable(new TeilnehmerPflicht());
    self.wirdGeradeEinWeitererEditiert = ko.observable(false);
    self.geradeEditierterKurs = ko.observable(false);
    self.geradeWirdEinNeuerTeilnehmerEditiert = false;
    
    self.addWeiteren = function(pKurs) {
      var newTn = new TeilnehmerPflicht();
      //newTn = self.tnToObservable(self.tnStruktur, newTn);
      self.editWeiteren(pKurs, newTn);
      self.geradeWirdEinNeuerTeilnehmerEditiert = true;
    };
    
    //einmal direkt (click: $root.editWeiteren.bind($data, $parent)//Reihenfolge STIMMT, whyever) und einmal über addWeiteren aufgerufen 
    self.editWeiteren = function(pKurs, pTeilnehmer) {
      self.geradeEditierterWeitererTn(pTeilnehmer);
      self.geradeEditierterKurs(pKurs);//muss vor self.wirdGeradeEinWeitererEditiert(true); stehen!! da in weitererTnZumAktuellenKursWirdEditiert auf den Kurs zugegriffen wird!
      self.wirdGeradeEinWeitererEditiert(true);
      //EditierDialog an der richtigen Stelle einhängen
      var curr = $('div.eingabeWeiterer');
      curr.detach();
      if(pKurs.weitereTeilnehmer().indexOf(pTeilnehmer) == -1) {
        $(".kw-kurs-tnadd" + self.geradeEditierterKurs().knr.replace(/[\.\s]/g,'_')).append(curr);
      }
      else {
        $(".wtn" + self.geradeEditierterKurs().knr.replace(/[\.\s]/g,'_') + '_' + pKurs.weitereTeilnehmer().indexOf(pTeilnehmer)).append(curr);
      }
    };
    
    self.weitererTnWirdEditiert = function() {
      return self.wirdGeradeEinWeitererEditiert();
    };
    self.weitererTnZumAktuellenKursWirdEditiert = function(pKurs) {
      return self.wirdGeradeEinWeitererEditiert() && self.geradeEditierterKurs() !== false && self.geradeEditierterKurs().knr.replace(/[\.\s]/g,'_') === pKurs.knr.replace(/[\.\s]/g,'_');
    };

    self.isWeitererUngueltig = function() {
      var pflichtfelder = '';
      //Kinder als weitere Teilnehmer können andere Pflichtfelder als Erwachsene haben
		if( self.geradeEditierterWeitererTn().istkind() ) { //weiterer Teilnehmer ist ein Kind
		  pflichtfelder = self.kinderPflichtfelder;
		}
	    else { //weiterer Teilnehmer ist ein Erwachsener
          pflichtfelder = self.weiterePflichtfelder;
        }
        for( var i=0; i < pflichtfelder.length; i++ ) {
          var varname = pflichtfelder[i];
          if( typeof(self.geradeEditierterWeitererTn()[varname]) == 'function' ) {
            if( typeof(self.geradeEditierterWeitererTn()[varname]()) === 'undefined' || self.geradeEditierterWeitererTn()[varname]() === '' ) {
              return true;
            }
          }
          else {
            if( typeof(self.geradeEditierterWeitererTn()[varname]) === 'undefined' || self.geradeEditierterWeitererTn()[varname] === '' ) {
              return true;
            }
          }
        }
        return false; //beim weiteren Teilnehmer wurden also alle Pflichtfelder ausgefüllt
    };
    
    self.isGebdatFalschesFormat = function() {
      return ( 
              typeof(self.geradeEditierterWeitererTn().gebdat() ) !== "undefined" 
              && self.geradeEditierterWeitererTn().gebdat() != '' 
              && !( /(0[1-9]|[12][0-9]|3[01])\.(0[1-9]|1[012])\.(19|20)\d\d/.test(self.geradeEditierterWeitererTn().gebdat()) )
              );
    }
    
    self.isEmailFalschesFormat = function () {
      return ( 
        typeof(self.geradeEditierterWeitererTn().email() ) !== "undefined" 
        && self.geradeEditierterWeitererTn().email() != '' 
        && !( /.*@.*\..*/.test(self.geradeEditierterWeitererTn().email()) )
        );
    }
    
    self.submitWeiteren = function() { //Hinweismeldung ausgeben, warum man den weiteren Teilnehmer nicht hinzufügen darf.
      if ( self.isWeitererUngueltig() ) {
        alert('Bitte tragen Sie erst Werte in die Pflichtfelder ein.');
        return false;
      }
      else if (self.isGebdatFalschesFormat()) {
        alert('Das Geburtsdatum muss das Format TT.MM.YYYY haben.');
        return false;
      }
      else if (self.isEmailFalschesFormat()) {
        alert('Es handelt sich nicht um eine korrekte E-Mailadresse.');
        return false;
      }
      else if (!self.checkSubmitWeiteren()) {
        if( self.geradeEditierterKurs().altervon == 0 && self.geradeEditierterKurs().alterbis == 0 ) {
          alert('Es handelt sich nicht um ein korrektes Geburtsdatum.');
        }
        else if( self.geradeEditierterKurs().alterbis == 0 ) {
          alert('Der Teilnehmer muss mindestens '+self.geradeEditierterKurs().altervon+' Jahre alt sein.');
        }
        else {
          alert('Das Alter des Teilnehmers muss zwischen '+self.geradeEditierterKurs().altervon+' und '+self.geradeEditierterKurs().alterbis+' Jahren liegen.');
        }
        return false;
      }
      if (self.geradeWirdEinNeuerTeilnehmerEditiert) {
        self.geradeEditierterKurs().addWeiteren(self.geradeEditierterWeitererTn());
      }
      self.geradeEditierterWeitererTn(new TeilnehmerPflicht());
      self.wirdGeradeEinWeitererEditiert(false);
      self.geradeEditierterKurs(false);
      self.geradeWirdEinNeuerTeilnehmerEditiert = false;
    };
    
    self.isWeitererGebdatPflicht = function() {
      return (self.weiterePflichtfelder.indexOf('gebdat') > -1);
    }
    
    self.isKindGebdatPflicht = function() {
      return (self.kinderPflichtfelder.indexOf('gebdat') > -1);
    }
        
    self.checkSubmitWeiteren = function() { //Überprüfen, ob man den weiteren Teilnehmer hinzufügen darf.
      var kurs = self.geradeEditierterKurs();
      var einstellungen = self.einstellungen;
      /*var einstellungen = self.einstellungen; //spezieller Block für Ottobrunn, nicht allgemein übernehmen!
      if( kurs.webflags == 4 && !einstellungen().nurnormaleanmeldearten && einstellungen().nurerlaubteanmeldearten ) {
        return true;
      }*/ //Ende spezieller Block für Ottobrunn
      var weiterer = self.geradeEditierterWeitererTn();
      if( (weiterer.istkind() && !self.isKindGebdatPflicht()) || (!weiterer.istkind() && !self.isWeitererGebdatPflicht()) ) {
        return true;
      }

      if( weiterer.gebdat() == undefined || weiterer.gebdat() == "" ) {
        return false;
      }
      
      if (weiterer.istkind() || einstellungen().anmErwachsenerTnGeburtsdatumKursEntsprechen) {
        //weiterer Teilnehmer ist zu jung
        if( kurs.altervon > calculateAge(weiterer.gebdat(), kurs.beginn_dat) ) {
          return false;
        }
        //weiterer Teilnehmer ist zu alt
        if( kurs.alterbis > 0 && kurs.alterbis < calculateAge(weiterer.gebdat(),kurs.beginn_dat) ) {
          return false;
        }
      }
      return true;
    };
    
    self.abortWeiteren = function() {
      self.geradeEditierterWeitererTn(new TeilnehmerPflicht());
      self.wirdGeradeEinWeitererEditiert(false);
      self.geradeEditierterKurs(false);
      self.geradeWirdEinNeuerTeilnehmerEditiert = false;
    };
  
    //Wie viel Prozent der Kursgebühr darf ermäßigt werden? Dabei wird beachtet, was der Teilnehmer ausgewählt hat.
    self.ermaessigungsProzente = function() {
      var einstellungen = self.einstellungen;
      var prozente = 0;
      if( typeof(self.hauptTn()) != 'undefined' && typeof(self.hauptTn().erm_grund) != 'undefined' && typeof(einstellungen().ermaessigungen) != 'undefined' && typeof(einstellungen().ermaessigungen[self.hauptTn().erm_grund()]) != 'undefined' && typeof(einstellungen().ermaessigungen[self.hauptTn().erm_grund()].prozente) != 'undefined' ) {
        prozente = einstellungen().ermaessigungen[self.hauptTn().erm_grund()].prozente;
      }
      return prozente;
    };
  
    //zuErmKennzAry dient dazu, bei Kursen mit diesen Kennzeichen eine Ermäßigung zu berücksichtigen. Wird nichts übergeben, so gilt die Ermäßigung für alle Kurse.
    self.gebuehrenSumme = function(zuErmKennzAry) {
      var einstellungen = self.einstellungen;
      var total = 0;
      //Alle Kurse durchlaufen und den korrekten Preis zur Gesamtsumme addieren
        ko.utils.arrayForEach(self.kurse(), function(kurs) {
          
          var value = parseFloat(kurs.gebuehrProPersonOhneErm().replace(',', '.'));
          
          //Hat der Kurs eines der Kennzeichen, das als Array an diese Funktion übergeben wurde?
          var kennzGefunden = false;
          if( typeof(zuErmKennzAry) != 'undefined' && zuErmKennzAry != '' ) {
            for( i=0; i < zuErmKennzAry.length; i++ ) {
              if( kurs.hasKennzeichen(zuErmKennzAry[i]) ) {
                kennzGefunden = true;
              }
            }
          }
          
          var prozente = 0;
          //Entweder hat der Kurs eines der zu ermäßigenden Kennzeichen oder es wurden gar keine zu ermäßigenden Kennzeichen übergeben
          //und somit wird die Ermäßigung ganz normal auf alle Kurse angerechnet
          //Die Ermäßigung ändert sich nur live auf der Eingabeseite, wenn auch die Einstellung "Dynamische Anzeige der Ermäßigung" im Webadmin aktiviert wurde.
          if( (kennzGefunden || typeof(zuErmKennzAry) == 'undefined' || zuErmKennzAry == '') && einstellungen().neueanmdynamischegebuehr ) { 
            prozente = self.ermaessigungsProzente();
          }
          if (!isNaN(value)) {
            //Kinder anders berechnen als erwachsene weitere Teilnehmer
            if( kurs.weitereTeilnehmer().length > 0 && kurs.weitereTeilnehmer()[0].istkind() ) {
              //Wenn der Hauptteilnehmer bzw. das Elternteil auch mit zum Kinderkurs geht, dann gilt zumindest für ihn auch die Ermäßigung
              if( kurs.hauptTnAuch() > 0 ) {
                total += (value - (value * prozente) / 100)
              }
              //Jetzt noch addieren, wie viel für die Kinder bezahlt werden muss
              var geb_kind = kurs.geb_kind;
              var geb_zuskind = kurs.geb_zuskind;
              if( geb_kind == undefined ) {
                geb_kind = 0;
              }
              total += parseFloat(geb_kind) + parseFloat(geb_zuskind) * (kurs.weitereTeilnehmer().length-1); //Die Länge ist größer als 0, wird vom if oben sichergestellt. Erstes Kind kostet ja u.U. einen anderen Preis als weitere Kinder.
            }
            else {
              // Keine Eltern-Kind-Anmeldung, also Ermäßigung für alle Teilnehmer verwenden (in Zukunft dann evtl. noch Splitanmeldung beachten)
              var anzTn = kurs.weitereTeilnehmer().length;
              if( kurs.hauptTnAuch() > 0 ) {
                anzTn++;
              }
              total += (value - (value * prozente) / 100) * anzTn; 
            }
          }
        });
        
      return total.toFixed(2);
    };
    //interessantes Schnippsel
      /*var x = ko.utils.arrayFirst(self.kurse(), function(item) {
          return ko.utils.stringStartsWith(item.knr.toLowerCase(), pKurs.knr);
      });*/
    
    //Für Bonn FBS
    //Äquivalent zur Gesamtsumme der Kursgebühren, nur dass eben die Wunschgebühr aus den beleghistorie1-Feldern aller Kurse summiert wird und nicht die eigentliche Kursgebühr.
    self.beleghistorie1Summe = function() {
      var gesamt = 0;
      for (var i = 0; i < self.kurse().length ; i++) {
        var kurs = self.kurse()[i];
        if( typeof(kurs.beleghistorie1) == 'undefined' || typeof(kurs.beleghistorie1()) == 'undefined' || kurs.beleghistorie1() == '' ) {
          return gesamt;
        }
        else {
          gesamt = gesamt + parseFloat(kurs.beleghistorie1().replace(/,/g, '.'));
        }
      }
      return gesamt.toFixed(2).toString().replace('.', ',');
    }
    
    self.tnToObservable = function(pTnStruktur, pTn, pEinstellungen) {
        var result = new TeilnehmerPflicht(pTn.name);
        //Observables erzeugen
        for (var field in pTnStruktur) {
            if (pTnStruktur.hasOwnProperty(field) && 
                (typeof(pTnStruktur[field]) != 'object' || typeof(pTnStruktur[field].length) == 'undefined')) {//kein Array
                result[field] = ko.observable();    
            }
        }
        for (var field in pTn) {
            if (pTn.hasOwnProperty(field) && 
                (typeof(pTn[field]) != 'object' || typeof(pTn[field].length) == 'undefined') && field != 'ibanxxx' ) {//kein Array
                result[field](pTn[field]); 
            }
            //alert (field + ': ' + typeof(kurs[field]) + ' : ' + typeof(kurs[field].length));
        }
        
        result['ibanxxx'] = ko.computed(function() {
          if (typeof result.iban() !== 'undefined') {
            var ibanLength = result.iban().length;
            if (ibanLength>3) {
              var xs = '';
              for (var i = 3; i<ibanLength; i++) {
                xs += "x";
              }
              return xs+result.iban().substring(ibanLength-3);
            }
            else { return result.iban();}
          } 
          else { 
            return '';
          }
        }, this);
          return result;
   };
      
    self.fromJson = function(pJson) { //Erzeugt aus dem von PHP erhaltenen JSON-Objekt mehrere KnockoutJS-Objekte, die dann in anmeldung.js und in den Sichten benutzt werden können.
      var data = ko.utils.parseJson(pJson);
      var tnStruktur = data.strukturTn;//leere TeilnehmerPflicht Struktur, um die Observables korrekt erzeugen zu können
      //self.tnStruktur = tnStruktur;
      //hier Ausnahmen für Felder einfügen, die von KnockoutJS dynamisch geändert werden können sollen!
      var kursObservableVars = ['hauptTnAuch', 'zahlplan', 'beleghistorie1', 'beleghistorie2', 'beleghistorie3', 'beleghistorie4', 'beleghistorie5', 'beleghistorie6'];
      var messages = data.messages;
      if (data.hauptTn) {
        if( typeof(data.einstellungen) != 'undefined' && data.einstellungen.spendenbetrag != '' && data.hauptTn.spendenbetrag == '') {
          //alert(pEinstellungen.spendenbetrag);
          data.hauptTn.spendenbetrag = data.einstellungen.spendenbetrag;
          data.hauptTn.spendencheck = true;
        }
        var hauptTnObservable = self.tnToObservable(tnStruktur, data.hauptTn, data.einstellungen);
        hauptTnObservable.arykennzeichenJS = ko.observableArray(data.hauptTn.arykennzeichenJS);
        self.hauptTn(hauptTnObservable);
      }
      for (var i = 0; i < data.kurse.length ; i++) {
        var kurs = data.kurse[i];
        var gebuehrGeparsed = parseFloat(kurs.gebuehr.replace(',', '.')); 
        var kursOut = new Kurs(kurs.id, kurs.beginn_dat, gebuehrGeparsed, self.sichtSettings);
        for (var field in kurs) {
          if (kurs.hasOwnProperty(field) && 
            (typeof(kurs[field]) != 'object' || typeof(kurs[field].length) == 'undefined')) {//kein Array
              kursOut[field] = kurs[field]; 
            }
          if(field == "kennzeichen") {
              kursOut[field] = kurs[field];
          }
          if(field == "zahlplaene") {
            if( kurs[field].length > 0 ) {
              var nameStandardZahlplan = 'Normal';
              if (kurs.gebuehr_name != "") {
                nameStandardZahlplan = kurs.gebuehr_name;
              }
              zahlplaeneAry = ko.observableArray([{ titel: nameStandardZahlplan, wert: '-1'}]);
              for(var j = 0; j < kurs[field].length; j++) {
                var kursgebuehren = ko.observableArray();
                for(var k = 0; k < kurs[field][j].kursgebuehren.length; k++) {
                  kursgebuehren.push(kurs[field][j].kursgebuehren[0]);
                }
                zahlplaeneAry.push({ titel: kurs[field][j].beschreibung, wert: kurs[field][j].id, kursgebuehren: kursgebuehren , gebuehrengesamt: kurs[field][j].gebuehrengesamt , gebuehrengesamtermbar: kurs[field][j].gebuehrengesamtermbar});
              }
              kursOut["zahlplaene"] = zahlplaeneAry;
            }
          }
          //Felder auch nach dem ersten Absenden wieder zu Observables machen
          if( kursObservableVars.indexOf(field) > -1 ) {
            kursOut[field] = ko.observable(kurs[field]);
          }
        }
        
        //ja, das steht absichtlich hier, im Kurs hat es nicht funktioniert
        kursOut['gebuehrProPersonOhneErm'] = ko.computed(function() {
            var curZahlplan = null;
            if( this.zahlplan() !== "-1" && typeof(this.zahlplaene) === "function" ) {
              for( var i = 0; i < this.zahlplaene().length; i++ ) {
                if( this.zahlplan() === this.zahlplaene()[i].wert ) {
                  curZahlplan = this.zahlplaene()[i];
                }
              }
            }

            var value = NaN;
            if( curZahlplan !== null && self.einstellungen().neueanmdynamischegebuehr ) {
                value = parseFloat(curZahlplan.gebuehrengesamt).toFixed(2).toString().replace('.', ',');
            }
            else {
              value = this.gebuehr;
            }
            return value;
        }, kursOut);//somit wird kursOut als this an die function übergeben
        
        //weitere Teilnehmer
        if (kurs.weitereTeilnehmer) {
            for (var j = 0; j < kurs.weitereTeilnehmer.length ; j++) {
                var tn = kurs.weitereTeilnehmer[j];
                kursOut.addWeiteren(self.tnToObservable(tnStruktur, tn));
            }
        }
        self.kurse.push(kursOut);
      }
      self.einstellungen(data.einstellungen);
    };  
    /*
var anminfo = 
{
  "hauptTn": {},
  "kurse": [
    {
      "knr": "161-3207",
      "gebuehr": 10,
      "beginn_dat": "02.10.2016",
      "weitereTeilnehmer": [
        {
          "name": "aa1name",
          "vorname": "aavorname"
        },
*/ 
}


//var dataFromServer = ko.utils.parseJson(anminfoString);


jQuery(function ($) {
  if (typeof(anminfoString) !== 'undefined') {
    var myViewModel = new KwAnmeldeViewModel();
    ko.bindingHandlers.confirmClick = { //Für Fenster, in denen gefragt wird "Wollen Sie wirklich abbrechen? Ja/Nein".
    init: function(element, valueAccessor, allBindings, viewModel) {
        var value = valueAccessor();
        var message = ko.unwrap(value.message);
        var click = value.click;
        ko.applyBindingsToNode(element, { click: function () {
            if (confirm(message))
                return click.apply(this, Array.prototype.slice.apply(arguments));
        }}, viewModel);
      }
    }
    ko.applyBindings(myViewModel);
    var datastring = base64.decode(anminfoString);
    myViewModel.fromJson(datastring);
  }
    // Umschalten zwischen Überweisung/Lastschrift
    // Verstecken beim Seitenaufruf
    if ($('#bedit_zahlartueberid').is(':checked')) {
        $("#bankdaten").hide();
        $(".hasDataCheck").hide();
        $("#payment").hide();
    }
    if ($('#bedit_zahlartonlineid').is(':checked')) {
        $("#bankdaten").hide();
        $(".hasDataCheck").hide();
        $("#payment").fadeIn();
    }
    if ($('#bedit_zahlartlastid').is(':checked')) {
        $("#bankdaten").fadeIn();
        $("#payment").hide();
    }
    if ($('#tedit_keinebankverbindungid').is(':checked')) {
        //$(".hasData").hide();
        $("#bankdaten").hide();
    }

    //Wenn auf Überweisung geklickt wird, dann Lastschrift-Felder leeren und verstecken
    $("[name='bedit_zahlart']").change(function () {
      if (this.value == "L") {           
        $(".hasDataCheck").fadeIn();
        $("#payment").hide();
        if ($('#tedit_keinebankverbindungid').is(':checked')) {
          $("#bankdaten").hide();
        } else{
           $("#bankdaten").fadeIn();
        }
      }
      else {//Wenn e-Payment ausgewählt wird, werden die e-Payment-Felder eingeblendet und die Bankdaten-Felder ausgeblendet
        if (this.value == "O") {
            $(".hasDataCheck").hide();
            $("#bankdaten").hide();
            $("#payment").fadeIn();
        } else {//Bankdaten ausblenden, wenn Überweisung ausgewählt wird
          divFelderLeeren($(".hasDataCheck"));
          divFelderLeeren($("#bankdaten"));
          $(".hasDataCheck").hide();
          $("#bankdaten").hide();
          $("#payment").hide();
        }
      }
    });

    //Wenn Haken "keinebankverbindung" gesetzt wird, dann Bankdaten ausblenden.
    //Wird der Haken entfernt, dann Bankdaten wieder einblenden.
    $('#tedit_keinebankverbindungid').change(function () {
      if (this.checked) {
          divFelderLeeren($("#bankdaten"));	 
          $("#bankdaten").hide();
      } else {
          $("#bankdaten").fadeIn();
      }
    });

   /*$("[name='tedit_geschlecht']").change(function () {
       if (this.value != "F") {
         $("#bedit_zahlartueberid").click();
       }
    });*/
    
});

//Leert alle Felder, die sich innerhalb des targetDivs befinden.
//Wie divFelderLeerenBeiAnderung, nur dass diese Funktion innerhalb einer anderen Funktion aufgerufen werden kann, die verwaltet,
//wann etwas geändert werden soll und wann nicht.
//Im Zweifelsfalle lieber divFelderLeerenBeiAenderung() benutzen!
function divFelderLeeren($targetDiv){
      //Für alle vom div eingeschlossenen textareas und input-Felder außer Checkboxen:
	  $targetDiv.find('input:not([type=checkbox]), textarea').each(function() {
	    $(this).val(''); //Inhalt des Feldes leeren
		$(this).trigger('change'); //per change aktualisieren, damit auch KnockoutJS die observables aktualisiert
	  });
	  
      //Für alle vom div eingeschlossenen Checkbox-Felder:
	  $targetDiv.find('input[type=checkbox]').each(function() {
        //KnockoutJS scheint auf "click" zu prüfen und nicht auf change. Wir setzen es auf checked und "klicken" dann,
        //sodass die Checkbox nicht mehr angehakt ist.
	    $(this).prop('checked', true).trigger('click');
	  });

}

//Alle Input-Felder, Textareas und Checkboxen leeren, die vom targetDiv eingeschlossen sind,
//wenn sich change ändert.
//Beispiel zur Benutzung: divFelderLeerenBeiAenderung($("[name='bedit_zahlart']"), $('#bankdaten')); in einen JavaScript-Bereich auf der Seite einbauen
//--> Wenn auf eine andere Zahlart geklickt wird, dann alle Input-Felder und Textareas innerhalb des Divs mit der Klasse "bankdaten" leeren
function divFelderLeerenBeiAenderung($change, $targetDiv){
	$change.change(function() {
		divFelderLeeren($targetDiv); //Wenn change angeklickt wird, dann rufe die Funktion zum leeren der Felder auf
	});
}