"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.cast_de_nrw_schule_svws_core_abschluss_gost_AbiturdatenManager = exports.AbiturdatenManager = void 0;
const JavaObject_1 = require("../../../java/lang/JavaObject");
const Naturwissenschaften_1 = require("../../../core/abschluss/gost/belegpruefung/Naturwissenschaften");
const SprachendatenManager_1 = require("../../../core/SprachendatenManager");
const Schwerpunkt_1 = require("../../../core/abschluss/gost/belegpruefung/Schwerpunkt");
const HashMap_1 = require("../../../java/util/HashMap");
const KurszahlenUndWochenstunden_1 = require("../../../core/abschluss/gost/belegpruefung/KurszahlenUndWochenstunden");
const GostBesondereLernleistung_1 = require("../../../core/types/gost/GostBesondereLernleistung");
const GostBelegpruefungErgebnis_1 = require("../../../core/abschluss/gost/GostBelegpruefungErgebnis");
const GostKursart_1 = require("../../../core/types/gost/GostKursart");
const Latinum_1 = require("../../../core/abschluss/gost/belegpruefung/Latinum");
const GostFachbereich_1 = require("../../../core/types/gost/GostFachbereich");
const Allgemeines_1 = require("../../../core/abschluss/gost/belegpruefung/Allgemeines");
const Sport_1 = require("../../../core/abschluss/gost/belegpruefung/Sport");
const GostHalbjahr_1 = require("../../../core/types/gost/GostHalbjahr");
const GostSchriftlichkeit_1 = require("../../../core/types/gost/GostSchriftlichkeit");
const ZulaessigesFach_1 = require("../../../core/types/statkue/ZulaessigesFach");
const Collections_1 = require("../../../java/util/Collections");
const Vector_1 = require("../../../java/util/Vector");
const GesellschaftswissenschaftenUndReligion_1 = require("../../../core/abschluss/gost/belegpruefung/GesellschaftswissenschaftenUndReligion");
const AbiFaecher_1 = require("../../../core/abschluss/gost/belegpruefung/AbiFaecher");
const HashSet_1 = require("../../../java/util/HashSet");
const LiterarischKuenstlerisch_1 = require("../../../core/abschluss/gost/belegpruefung/LiterarischKuenstlerisch");
const GostAbiturFach_1 = require("../../../core/types/gost/GostAbiturFach");
const GostBelegpruefung_1 = require("../../../core/abschluss/gost/GostBelegpruefung");
const GostFachManager_1 = require("../../../core/abschluss/gost/GostFachManager");
const Projektkurse_1 = require("../../../core/abschluss/gost/belegpruefung/Projektkurse");
const Deutsch_1 = require("../../../core/abschluss/gost/belegpruefung/Deutsch");
const Fremdsprachen_1 = require("../../../core/abschluss/gost/belegpruefung/Fremdsprachen");
const GostBelegpruefungErgebnisFehler_1 = require("../../../core/abschluss/gost/GostBelegpruefungErgebnisFehler");
const Mathematik_1 = require("../../../core/abschluss/gost/belegpruefung/Mathematik");
class AbiturdatenManager extends JavaObject_1.JavaObject {
    abidaten;
    gostFaecher;
    pruefungsArt;
    mapFachbereiche = new HashMap_1.HashMap();
    belegpruefungen = new Vector_1.Vector();
    belegpruefungsfehler = new Vector_1.Vector();
    belegpruefungErfolgreich = false;
    /**
     * Erstellt ein neues Manager-Objekt, welches mit den übergebenen Abiturdaten verknüpft wird.
     *
     * @param abidaten       die Abiturdaten
     * @param gostFaecher    die Fächer der Gymnasialen Oberstufe, die bei dem Abiturjahrgang zur Verfügung stehen.
     * @param pruefungsArt   die Art der Belegpruefung (z.B. EF1 oder GESAMT)
     */
    constructor(abidaten, gostFaecher, pruefungsArt) {
        super();
        this.abidaten = abidaten;
        this.gostFaecher = new HashMap_1.HashMap();
        for (let i = 0; i < gostFaecher.size(); i++) {
            let fach = gostFaecher.get(i);
            if (fach !== null)
                this.gostFaecher.put(fach.id, fach);
        }
        this.pruefungsArt = pruefungsArt;
        this.init();
    }
    /**
     * Führt die Belegprüfung der Art pruefungs_art für einen Schüler durch, dessen Abiturdaten mit dem angegebenen
     * Manager verwaltet werden.
     *
     * @param pruefungs_art    die Art der Prüfung, die durchgeführt wird
     *
     * @return eine Liste mit den durchgefuehrten Belegpruefungen
     */
    getPruefungen(pruefungs_art) {
        let pruefungen = new Vector_1.Vector();
        pruefungen.add(new Deutsch_1.Deutsch(this, pruefungs_art));
        let pruefungFremdsprachen = new Fremdsprachen_1.Fremdsprachen(this, pruefungs_art);
        pruefungen.add(pruefungFremdsprachen);
        pruefungen.add(new Latinum_1.Latinum(this, pruefungs_art));
        pruefungen.add(new LiterarischKuenstlerisch_1.LiterarischKuenstlerisch(this, pruefungs_art));
        pruefungen.add(new GesellschaftswissenschaftenUndReligion_1.GesellschaftswissenschaftenUndReligion(this, pruefungs_art));
        pruefungen.add(new Mathematik_1.Mathematik(this, pruefungs_art));
        let pruefungNaturwissenschaften = new Naturwissenschaften_1.Naturwissenschaften(this, pruefungs_art);
        pruefungen.add(pruefungNaturwissenschaften);
        pruefungen.add(new Sport_1.Sport(this, pruefungs_art));
        let pruefungProjektkurse = new Projektkurse_1.Projektkurse(this, pruefungs_art);
        pruefungen.add(pruefungProjektkurse);
        pruefungen.add(new Schwerpunkt_1.Schwerpunkt(this, pruefungs_art, pruefungFremdsprachen, pruefungNaturwissenschaften));
        pruefungen.add(new AbiFaecher_1.AbiFaecher(this, pruefungs_art));
        pruefungen.add(new KurszahlenUndWochenstunden_1.KurszahlenUndWochenstunden(this, pruefungs_art, pruefungProjektkurse));
        pruefungen.add(new Allgemeines_1.Allgemeines(this, pruefungs_art));
        return pruefungen;
    }
    /**
     * Initialisiert bzw. reinitialisert die Datenstrukturen, die für den schnellen Zugriff auf die Daten
     * eingerichtet werden.
     */
    init() {
        if (this.abidaten === null)
            return;
        this.initMapFachbereiche();
        this.belegpruefungen = this.getPruefungen(this.pruefungsArt);
        for (let i = 0; i < this.belegpruefungen.size(); i++) {
            let belegpruefung = this.belegpruefungen.get(i);
            belegpruefung.pruefe();
        }
        this.belegpruefungsfehler = GostBelegpruefung_1.GostBelegpruefung.getBelegungsfehlerAlle(this.belegpruefungen);
        this.belegpruefungErfolgreich = GostBelegpruefung_1.GostBelegpruefung.istErfolgreich(this.belegpruefungsfehler);
    }
    /**
     * Initialisiert bzw. reinitialisiert die Map für den schnellen Zugriff auf Fachbelegungen
     * anhand des Fachbereichs.
     */
    initMapFachbereiche() {
        this.mapFachbereiche.clear();
        let fachbereiche = GostFachbereich_1.GostFachbereich.values();
        for (let fachbereich of fachbereiche) {
            this.mapFachbereiche.put(fachbereich, new Vector_1.Vector());
        }
        let fachbelegungen = this.abidaten.fachbelegungen;
        for (let fachbelegung of fachbelegungen) {
            if (this.zaehleBelegung(fachbelegung) > 0) {
                fachbereiche = GostFachbereich_1.GostFachbereich.getBereiche(this.getFach(fachbelegung));
                for (let fachbereich of fachbereiche) {
                    let listFachbelegungen = this.mapFachbereiche.get(fachbereich);
                    if (listFachbelegungen === null)
                        continue;
                    listFachbelegungen.add(fachbelegung);
                }
            }
        }
    }
    /**
     * Liefert die in den Abiturdaten enthaltenen Sprachendaten.
     *
     * @return Die Sprachendaten (siehe {@link Sprachendaten})
     */
    getSprachendaten() {
        return this.abidaten.sprachendaten;
    }
    /**
     * Berechnet die Wochenstunden, welche von dem Schüler in den einzelnen
     * Halbjahren der gymnasialen Oberstufe für das Abitur relevant belegt wurden.
     *
     * @return ein Array mit den Wochenstunden für die sechs Halbjahre
     */
    getWochenstunden() {
        let stunden = [0, 0, 0, 0, 0, 0];
        for (let i = 0; i < 6; i++) {
            for (let fb of this.abidaten.fachbelegungen) {
                let hjb = fb.belegungen[i];
                if ((hjb === null) || (JavaObject_1.JavaObject.equalsTranspiler("AT", (hjb.kursartKuerzel))))
                    continue;
                stunden[i] += hjb.wochenstunden;
            }
        }
        return stunden;
    }
    /**
     * Berechnet die Anzahl der anrechenbaren Kurse, welche von dem Schüler in den einzelnen
     * Halbjahren der gymnasialen Oberstufe für das Abitur belegt wurden.
     *
     * @return ein Array mit den anrechenbaren Kursen für die sechs Halbjahre
     */
    getAnrechenbareKurse() {
        let anzahl = [0, 0, 0, 0, 0, 0];
        let bll = GostBesondereLernleistung_1.GostBesondereLernleistung.fromKuerzel(this.abidaten.besondereLernleistung);
        for (let i = 0; i < 6; i++) {
            for (let fb of this.abidaten.fachbelegungen) {
                let hjb = fb.belegungen[i];
                if ((hjb === null) || (JavaObject_1.JavaObject.equalsTranspiler("AT", (hjb.kursartKuerzel))))
                    continue;
                let kursart = GostKursart_1.GostKursart.fromKuerzel(hjb.kursartKuerzel);
                if ((kursart !== GostKursart_1.GostKursart.VTF) && (!((kursart === GostKursart_1.GostKursart.PJK) && (bll === GostBesondereLernleistung_1.GostBesondereLernleistung.PROJEKTKURS))))
                    anzahl[i]++;
            }
        }
        return anzahl;
    }
    /**
     * Liefert das Fach der gymnasialen Oberstufe für die angegeben Abiturfachbelegung.
     *
     * @param belegung   die Fachbelegung (siehe {@link AbiturFachbelegung})
     *
     * @return das Fach der gymnasialen Oberstufe (siehe {@link GostFach})
     */
    getFach(belegung) {
        if (belegung === null)
            return null;
        return this.gostFaecher.get(belegung.fachID);
    }
    /**
     * Prüft, ob das Faches in allen angegebenen Halbjahren belegt wurde.
     * Ist die Fachbelegung null, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
     * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
     *
     * @param fachbelegung      die zu prüfende Fachbelegung
     * @param halbjahre         die zu prüfenden Halbjahre
     *
     * @return true, falls das Fach in den Halbjahren belegt wurde, sonst false
     */
    pruefeBelegung(fachbelegung, ...halbjahre) {
        if (fachbelegung === null)
            return false;
        if ((halbjahre === null) || (halbjahre.length === 0))
            return true;
        for (let halbjahr of halbjahre) {
            let belegungHalbjahr = fachbelegung.belegungen[halbjahr.id];
            if ((belegungHalbjahr === null) || (belegungHalbjahr.kursartKuerzel === null))
                return false;
        }
        return true;
    }
    /**
     * Bestimmt die Anzahl der Fachbelegungen, die dem Fach zugeordnet sind.
     * Wird keine gültige Fachbelegung übergeben, so wird 0 zurückgegeben.
     *
     * @param fachbelegung   die Fachbelegung
     *
     * @return die Anzahl der Belegungen des Faches
     */
    zaehleBelegung(fachbelegung) {
        if (fachbelegung === null)
            return 0;
        let anzahl = 0;
        for (let i = 0; i < GostHalbjahr_1.GostHalbjahr.maxHalbjahre; i++) {
            if (fachbelegung.belegungen[i] !== null)
                anzahl++;
        }
        return anzahl;
    }
    /**
     * Zählt die Anzahl der Belegungen für die angegebenen Fachbelegungen in den angegeben Halbjahren.
     * Ist die Fachbelegung null, so wird 0 zurückgegeben. Wird bei einer gültigen Fachbelegung kein Halbjahr
     * angegeben, so wird ebenfalls 0 zurückgegeben.
     *
     * @param fachbelegungen      die Fachbelegungen
     * @param halbjahre           die Halbjahre
     *
     * @return die Anzahl der Belegungen in den Halbjahren und den Fächern
     */
    zaehleBelegungInHalbjahren(fachbelegungen, ...halbjahre) {
        if (fachbelegungen === null)
            return 0;
        if ((halbjahre === null) || (halbjahre.length === 0))
            return 0;
        let anzahl = 0;
        for (let fachbelegung of fachbelegungen)
            for (let halbjahr of halbjahre)
                if (fachbelegung.belegungen[halbjahr.id] !== null)
                    anzahl++;
        return anzahl;
    }
    /**
     * Prüft, ob die Belegung des Faches in den angegebenen Halbjahren der angegebenen Kursart entspricht.
     * Ist die Fachbelegung null, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
     * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
     *
     * @param fachbelegung      die zu prüfende Fachnbelegung
     * @param kursart           die zu prüfende Kursart
     * @param halbjahre         die zu prüfenden Halbjahre
     *
     * @return true, falls die Schriftlichkeit in den Halbjahren gegeben ist, sonst false
     */
    pruefeBelegungMitKursart(fachbelegung, kursart, ...halbjahre) {
        if (fachbelegung === null)
            return false;
        if ((halbjahre === null) || (halbjahre.length === 0))
            return true;
        for (let halbjahr of halbjahre) {
            let belegungHalbjahr = fachbelegung.belegungen[halbjahr.id];
            if ((belegungHalbjahr === null) || (kursart !== GostKursart_1.GostKursart.fromKuerzel(belegungHalbjahr.kursartKuerzel)))
                return false;
        }
        return true;
    }
    /**
     * Prüft, ob eine Fachbelegung existiert, welche in den angegebenen Halbjahren der angegebenen Kursart
     * entspricht.
     * Ist keine Fachbelegung angegeben, so schlägt die Prüfung fehl. Wird bei einer gültigen
     * Fachbelegung kein Halbjahr angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
     *
     * @param fachbelegungen    die zu prüfenden Fachnbelegungen
     * @param kursart           die zu prüfende Kursart
     * @param halbjahre         die zu prüfenden Halbjahre
     *
     * @return true, falls die Schriftlichkeit in den Halbjahren gegeben ist, sonst false
     */
    pruefeBelegungExistiertMitKursart(fachbelegungen, kursart, ...halbjahre) {
        if ((fachbelegungen === null) || (fachbelegungen.size() <= 0))
            return false;
        if ((halbjahre === null) || (halbjahre.length === 0))
            return true;
        for (let fachbelegung of fachbelegungen) {
            if (this.pruefeBelegungMitKursart(fachbelegung, kursart, ...halbjahre))
                return true;
        }
        return false;
    }
    /**
     * Prüft, ob die Belegung des Faches in den angegebenen Halbjahren mindestens einmal die angegebenen Kursart hat.
     * Ist die Fachbelegung null, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
     * angegeben, so ist die Prüfung nicht erfolgreich, da kein Halbjahr geprüft werden muss und somit die Kursart nicht
     * einmal existiert.
     *
     * @param fachbelegung      die zu prüfende Fachnbelegung
     * @param kursart           die zu prüfende Kursart
     * @param halbjahre         die zu prüfenden Halbjahre
     *
     * @return true, falls die Kursart mindestens einmal in den Halbjahren gegeben ist, sonst false
     */
    pruefeBelegungHatMindestensEinmalKursart(fachbelegung, kursart, ...halbjahre) {
        if (fachbelegung === null)
            return false;
        if ((halbjahre === null) || (halbjahre.length === 0))
            return false;
        for (let halbjahr of halbjahre) {
            let belegungHalbjahr = fachbelegung.belegungen[halbjahr.id];
            if (belegungHalbjahr === null)
                continue;
            if (kursart === GostKursart_1.GostKursart.fromKuerzel(belegungHalbjahr.kursartKuerzel))
                return true;
        }
        return false;
    }
    /**
     * Prüft, ob die Belegung des Faches in dem angegebenen Halbjahr der angegebenen Schriftlichkeit entspricht.
     * Ist die Fachbelegung null, so schlägt die Prüfung fehl.
     *
     * @param fachbelegung      die zu prüfende Fachnbelegung
     * @param schriftlichkeit   die zu prüfende Schriftlichkeit
     * @param halbjahr          das zu prüfende Halbjahr
     *
     * @return true, falls die Schriftlichkeit in dem Halbjahr gegeben ist, sonst false
     */
    pruefeBelegungMitSchriftlichkeitEinzeln(fachbelegung, schriftlichkeit, halbjahr) {
        if (fachbelegung === null)
            return false;
        let belegungHalbjahr = fachbelegung.belegungen[halbjahr.id];
        if ((belegungHalbjahr === null) || (belegungHalbjahr.schriftlich === null) || ((schriftlichkeit !== GostSchriftlichkeit_1.GostSchriftlichkeit.BELIEBIG) && (((schriftlichkeit === GostSchriftlichkeit_1.GostSchriftlichkeit.SCHRIFTLICH) && (!belegungHalbjahr.schriftlich)) || ((schriftlichkeit === GostSchriftlichkeit_1.GostSchriftlichkeit.MUENDLICH) && (belegungHalbjahr.schriftlich)))))
            return false;
        return true;
    }
    /**
     * Prüft, ob die Belegung des Faches in den angegebenen Halbjahren der angegebenen Schriftlichkeit entspricht.
     * Ist die Fachbelegung null, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
     * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
     *
     * @param fachbelegung      die zu prüfende Fachnbelegung
     * @param schriftlichkeit   die zu prüfende Schriftlichkeit
     * @param halbjahre         die zu prüfenden Halbjahre
     *
     * @return true, falls die Schriftlichkeit in den Halbjahren gegeben ist, sonst false
     */
    pruefeBelegungMitSchriftlichkeit(fachbelegung, schriftlichkeit, ...halbjahre) {
        if (fachbelegung === null)
            return false;
        if ((halbjahre === null) || (halbjahre.length === 0))
            return true;
        for (let halbjahr of halbjahre)
            if (!this.pruefeBelegungMitSchriftlichkeitEinzeln(fachbelegung, schriftlichkeit, halbjahr))
                return false;
        return true;
    }
    /**
     * Prüft, ob eine Belegung des Faches in den angegebenen Halbjahren nicht der angegebenen Schriftlichkeit entspricht.
     * Ist die Fachbelegung null, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
     * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
     *
     * @param fachbelegung      die zu prüfende Fachnbelegung
     * @param schriftlichkeit   die zu prüfende Schriftlichkeit
     * @param halbjahre         die zu prüfenden Halbjahre
     *
     * @return true, falls die Schriftlichkeit in den Halbjahren nicht gegeben ist, sonst false
     */
    pruefeBelegungErfuelltNicht(fachbelegung, schriftlichkeit, ...halbjahre) {
        if (fachbelegung === null)
            return false;
        if ((halbjahre === null) || (halbjahre.length === 0))
            return true;
        for (let halbjahr of halbjahre) {
            let belegungHalbjahr = fachbelegung.belegungen[halbjahr.id];
            if ((belegungHalbjahr === null) || ((schriftlichkeit !== GostSchriftlichkeit_1.GostSchriftlichkeit.BELIEBIG) && (((schriftlichkeit === GostSchriftlichkeit_1.GostSchriftlichkeit.SCHRIFTLICH) && (!belegungHalbjahr.schriftlich)) || ((schriftlichkeit === GostSchriftlichkeit_1.GostSchriftlichkeit.MUENDLICH) && (belegungHalbjahr.schriftlich)))))
                return true;
        }
        return false;
    }
    /**
     * Prüft, ob eine Belegung des Faches in den angegebenen Halbjahren nicht der angegebenen Schriftlichkeit entspricht,
     * sofern es in dem Halbjahr überhaupt belegt wurde..
     * Ist die Fachbelegung null, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
     * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
     *
     * @param fachbelegung      die zu prüfende Fachnbelegung
     * @param schriftlichkeit   die zu prüfende Schriftlichkeit
     * @param halbjahre         die zu prüfenden Halbjahre
     *
     * @return true, falls die Schriftlichkeit in den Halbjahren nicht gegeben ist, sonst false
     */
    pruefeBelegungErfuelltNichtFallsBelegt(fachbelegung, schriftlichkeit, ...halbjahre) {
        if (fachbelegung === null)
            return false;
        if ((halbjahre === null) || (halbjahre.length === 0))
            return true;
        for (let halbjahr of halbjahre) {
            let belegungHalbjahr = fachbelegung.belegungen[halbjahr.id];
            if (belegungHalbjahr === null)
                continue;
            let schriftlich = belegungHalbjahr.schriftlich === null ? false : belegungHalbjahr.schriftlich;
            if (((schriftlichkeit !== GostSchriftlichkeit_1.GostSchriftlichkeit.BELIEBIG) && (((schriftlichkeit === GostSchriftlichkeit_1.GostSchriftlichkeit.SCHRIFTLICH) && (!schriftlich)) || ((schriftlichkeit === GostSchriftlichkeit_1.GostSchriftlichkeit.MUENDLICH) && (schriftlich)))))
                return true;
        }
        return false;
    }
    /**
     * Prüft, ob die Belegung des Faches in den angegebenen Halbjahren mindestens einmal die angegebene Schritflichkeit hat.
     * Ist die Fachbelegung null, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
     * angegeben, so ist die Prüfung nicht erfolgreich, da kein Halbjahr geprüft werden muss und somit die Schriftlichkeit nicht
     * einmal existiert.
     *
     * @param fachbelegung      die zu prüfende Fachbelegung
     * @param schriftlichkeit   die zu prüfende Schriftlichkeit
     * @param halbjahre         die zu prüfenden Halbjahre
     *
     * @return true, falls die angegebene Schriftlichkeit mindestens einmal in den Halbjahren gegeben ist, sonst false
     */
    pruefeBelegungHatMindestensEinmalSchriftlichkeit(fachbelegung, schriftlichkeit, ...halbjahre) {
        if (fachbelegung === null)
            return false;
        if ((halbjahre === null) || (halbjahre.length === 0))
            return false;
        for (let halbjahr of halbjahre) {
            let belegungHalbjahr = fachbelegung.belegungen[halbjahr.id];
            if (belegungHalbjahr === null)
                continue;
            if ((schriftlichkeit.istSchriftlich === null) || (schriftlichkeit.istSchriftlich === belegungHalbjahr.schriftlich))
                return true;
        }
        return false;
    }
    /**
     * Prüft, ob eine Fachbelegung existiert, welche in den angegebenen Halbjahren mindestens einmal die angegebene
     * Schritflichkeit hat.
     * Ist die Fachbelegung null, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
     * angegeben, so ist die Prüfung nicht erfolgreich, da kein Halbjahr geprüft werden muss und somit die Schriftlichkeit nicht
     * einmal existiert.
     *
     * @param fachbelegungen    die zu prüfenden Fachbelegungen
     * @param schriftlichkeit   die zu prüfende Schriftlichkeit
     * @param halbjahre         die zu prüfenden Halbjahre
     *
     * @return true, falls die angegebene Schriftlichkeit bei einer Fachbelegung mindestens einmal in den Halbjahren gegeben ist, sonst false
     */
    pruefeBelegungExistiertHatMindestensEinmalSchriftlichkeit(fachbelegungen, schriftlichkeit, ...halbjahre) {
        if ((fachbelegungen === null) || (fachbelegungen.size() <= 0))
            return false;
        if ((halbjahre === null) || (halbjahre.length === 0))
            return false;
        for (let fachbelegung of fachbelegungen)
            if (this.pruefeBelegungHatMindestensEinmalSchriftlichkeit(fachbelegung, schriftlichkeit, ...halbjahre))
                return true;
        return false;
    }
    /**
     * Prüft, ob die Belegung eines der angegebenen Fächer mit den angegebenen Halbjahren existiert.
     * Ist keine Fachbelegung gegeben, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
     * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
     * In dieser Methode wird ggf. auch geprüft, ob weitere Fachbelegungen existieren, welche das gleiche
     * Statistik-Kürzel haben und Ersatzweise eine Halbjahres-Belegung ersetzen können. Dies ist z.B. bei bilingualen
     * Fächern nötig oder bei der Unterscheidung von Sport-Profilen.
     *
     * @param fachbelegungen    die zu prüfenden Fachnbelegungen
     * @param halbjahre         die zu prüfenden Halbjahre
     *
     * @return true, falls eine Fachbelegung mit den Halbjahren existiert, sonst false
     */
    pruefeBelegungExistiert(fachbelegungen, ...halbjahre) {
        if (fachbelegungen === null)
            return false;
        if ((halbjahre === null) || (halbjahre.length === 0))
            return true;
        for (let fachbelegung of fachbelegungen) {
            let fach = this.gostFaecher.get(fachbelegung.fachID);
            if (fach === null)
                continue;
            let alleBelegungen = this.getFachbelegungByFachkuerzel(fach.kuerzel);
            if ((alleBelegungen === null) || (alleBelegungen.size() === 0))
                continue;
            let hatBelegung = true;
            for (let halbjahr of halbjahre) {
                let hatHalbjahresBelegung = false;
                for (let aktFachbelegung of alleBelegungen) {
                    if (aktFachbelegung.belegungen[halbjahr.id] !== null) {
                        hatHalbjahresBelegung = true;
                        break;
                    }
                }
                if (!hatHalbjahresBelegung) {
                    hatBelegung = false;
                    break;
                }
            }
            if (hatBelegung)
                return true;
        }
        return false;
    }
    /**
     * Prüft, ob die Belegung eines der angegebenen Fächer mit dem angegebenen Halbjahr existiert.
     * Ist keine Fachbelegung gegeben, so schlägt die Prüfung fehl.
     * In dieser Methode wird ggf. auch geprüft, ob weitere Fachbelegungen existieren, welche das gleiche
     * Statistik-Kürzel haben und Ersatzweise eine Halbjahres-Belegung ersetzen können. Dies ist z.B. bei bilingualen
     * Fächern nötig oder bei der Unterscheidung von Sport-Profilen.
     *
     * @param fachbelegungen    die zu prüfenden Fachnbelegungen
     * @param halbjahr          das zu prüfende Halbjahr
     *
     * @return true, falls eine Fachbelegung mit dem Halbjahr existiert, sonst false
     */
    pruefeBelegungExistiertEinzeln(fachbelegungen, halbjahr) {
        if (fachbelegungen === null)
            return false;
        for (let fachbelegung of fachbelegungen) {
            let fach = this.gostFaecher.get(fachbelegung.fachID);
            if (fach === null)
                continue;
            let alleBelegungen = this.getFachbelegungByFachkuerzel(fach.kuerzel);
            if ((alleBelegungen === null) || (alleBelegungen.size() === 0))
                continue;
            for (let aktFachbelegung of alleBelegungen)
                if (aktFachbelegung.belegungen[halbjahr.id] !== null)
                    return true;
        }
        return false;
    }
    /**
     * Prüft, ob die Belegung eines der angegebenen Fächer mit einer durchgängigen Belegung existiert,
     * die zumindest in der Q1 und der Q2.1 schriftlich ist.
     * In dieser Methode wird ggf. auch geprüft, ob weitere Fachbelegungen existieren, welche das gleiche
     * Statistik-Kürzel haben und Ersatzweise eine Halbjahres-Belegung ersetzen können. Dies ist bei bilingualen
     * Fächern nötig.
     * Ist keine Fachbelegung gegeben, so schlägt die Prüfung fehl.
     *
     * @param fachbelegungen    die zu prüfenden Fachnbelegungen
     *
     * @return true, falls eine durchgehend schriftliche Fachbelegung existiert, sonst false
     */
    pruefeBelegungExistiertDurchgehendSchriftlich(fachbelegungen) {
        if (fachbelegungen === null)
            return false;
        for (let fachbelegung of fachbelegungen) {
            let fach = this.gostFaecher.get(fachbelegung.fachID);
            if (fach === null)
                continue;
            let alleBelegungen = this.getFachbelegungByFachkuerzel(fach.kuerzel);
            if ((alleBelegungen === null) || (alleBelegungen.size() === 0))
                continue;
            let hatBelegung = true;
            for (let halbjahr of GostHalbjahr_1.GostHalbjahr.values()) {
                let hatHalbjahresBelegung = false;
                for (let aktFachbelegung of alleBelegungen) {
                    if (aktFachbelegung.belegungen[halbjahr.id] !== null) {
                        let belegungHalbjahr = aktFachbelegung.belegungen[halbjahr.id];
                        if (((halbjahr !== GostHalbjahr_1.GostHalbjahr.Q11) && (halbjahr !== GostHalbjahr_1.GostHalbjahr.Q12) && (halbjahr !== GostHalbjahr_1.GostHalbjahr.Q21)) || ((belegungHalbjahr !== null) && (belegungHalbjahr.schriftlich !== null) && (belegungHalbjahr.schriftlich)))
                            hatHalbjahresBelegung = true;
                    }
                }
                if (!hatHalbjahresBelegung) {
                    hatBelegung = false;
                    break;
                }
            }
            if (hatBelegung)
                return true;
        }
        return false;
    }
    /**
     * Prüft, ob die Belegung eines der angegebenen Fächer in dem angegebenen Halbjahr der angegebenen Schriftlichkeit entspricht.
     * Ist keine Fachbelegung gegeben, so schlägt die Prüfung fehl.
     *
     * @param fachbelegungen    die zu prüfenden Fachnbelegungen
     * @param schriftlichkeit   die zu prüfende Schriftlichkeit
     * @param halbjahr          das zu prüfende Halbjahr
     *
     * @return true, falls bei einer Fachbelegung die Schriftlichkeit in dem Halbjahr gegeben ist, sonst false
     */
    pruefeBelegungExistiertMitSchriftlichkeitEinzeln(fachbelegungen, schriftlichkeit, halbjahr) {
        if (fachbelegungen === null)
            return false;
        for (let fachbelegung of fachbelegungen) {
            if (this.pruefeBelegungMitSchriftlichkeitEinzeln(fachbelegung, schriftlichkeit, halbjahr))
                return true;
        }
        return false;
    }
    /**
     * Prüft, ob die Belegung eines der angegebenen Fächer in den angegebenen Halbjahren der angegebenen Schriftlichkeit entspricht.
     * Ist keine Fachbelegung gegeben, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
     * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
     *
     * @param fachbelegungen    die zu prüfenden Fachnbelegungen
     * @param schriftlichkeit   die zu prüfende Schriftlichkeit
     * @param halbjahre         die zu prüfenden Halbjahre
     *
     * @return true, falls bei einer Fachbelegung die Schriftlichkeit in den Halbjahren gegeben ist, sonst false
     */
    pruefeBelegungExistiertMitSchriftlichkeit(fachbelegungen, schriftlichkeit, ...halbjahre) {
        if (fachbelegungen === null)
            return false;
        for (let fachbelegung of fachbelegungen) {
            if (this.pruefeBelegungMitSchriftlichkeit(fachbelegung, schriftlichkeit, ...halbjahre))
                return true;
        }
        return false;
    }
    /**
     * Prüft, ob die Belegung eines der angegebenen Fächer in den angegebenen Halbjahren mindestens einmal die angegebene Kursart
     * hat. Ist keine Fachbelegung gegeben, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
     * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
     *
     * @param fachbelegungen    die zu prüfenden Fachnbelegungen
     * @param kursart           die zu prüfende Kursart
     * @param halbjahre         die zu prüfenden Halbjahre
     *
     * @return true, falls die Kursart bei einer Fachbelegung mindestens einmal in den Halbjahren gegeben ist, sonst false
     */
    pruefeBelegungExistiertHatMindestensEinmalKursart(fachbelegungen, kursart, ...halbjahre) {
        if (fachbelegungen === null)
            return false;
        for (let fachbelegung of fachbelegungen) {
            if (this.pruefeBelegungHatMindestensEinmalKursart(fachbelegung, kursart, ...halbjahre))
                return true;
        }
        return false;
    }
    /**
     * Prüft, ob die Belegung eines der angegebenen Fächer in den angegebenen Halbjahren existiert,
     * bei welchem in mind. einem der Halbjahren die angebene Schriftlichkeit nicht gegeben ist.
     * Ist keine Fachbelegung gegeben, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
     * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
     *
     * @param fachbelegungen    die zu prüfenden Fachnbelegungen
     * @param schriftlichkeit   die zu prüfende Schriftlichkeit
     * @param halbjahre         die zu prüfenden Halbjahre
     *
     * @return true oder false (siehe oben)
     */
    pruefeBelegungExistiertErfuelltNicht(fachbelegungen, schriftlichkeit, ...halbjahre) {
        if (fachbelegungen === null)
            return false;
        for (let fachbelegung of fachbelegungen) {
            if (this.pruefeBelegungErfuelltNicht(fachbelegung, schriftlichkeit, ...halbjahre))
                return true;
        }
        return false;
    }
    /**
     * Prüft, ob die Belegung eines der angegebenen Fächer in den angegebenen Halbjahren existiert,
     * bei welchem in mind. einem der Halbjahren die angebene Schriftlichkeit nicht gegeben ist, sofern
     * das Fach überhaupt belegt wurde.
     * Ist keine Fachbelegung gegeben, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
     * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
     *
     * @param fachbelegungen    die zu prüfenden Fachnbelegungen
     * @param schriftlichkeit   die zu prüfende Schriftlichkeit
     * @param halbjahre         die zu prüfenden Halbjahre
     *
     * @return true oder false (siehe oben)
     */
    pruefeBelegungExistiertErfuelltNichtFallsBelegt(fachbelegungen, schriftlichkeit, ...halbjahre) {
        if (fachbelegungen === null)
            return false;
        for (let fachbelegung of fachbelegungen) {
            if (this.pruefeBelegungErfuelltNichtFallsBelegt(fachbelegung, schriftlichkeit, ...halbjahre))
                return true;
        }
        return false;
    }
    /**
     * Prüft, ob die Belegung des Faches in den angegebenen Halbjahren der angegebenen Schriftlichkeit entspricht
     * und das Fach durchgehend belegbar ist.
     * Ist die Fachbelegung null, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
     * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
     *
     * @param fachbelegung      die zu prüfende Fachnbelegung
     * @param schriftlichkeit   die zu prüfende Schriftlichkeit
     * @param halbjahre         die zu prüfenden Halbjahre
     *
     * @return true, falls die Schriftlichkeit in den Halbjahren gegeben ist, sonst false
     */
    pruefeBelegungDurchgehendBelegbar(fachbelegung, schriftlichkeit, ...halbjahre) {
        if (fachbelegung === null)
            return false;
        if (!GostFachManager_1.GostFachManager.istDurchgehendBelegbarBisQ22(this.getFach(fachbelegung)))
            return false;
        return this.pruefeBelegungMitSchriftlichkeit(fachbelegung, schriftlichkeit, ...halbjahre);
    }
    /**
     * Prüft, ob die Belegung eines der angegebenen Fächer in den angegebenen Halbjahren der angegebenen Schriftlichkeit entspricht
     * und das Fach durchgängig belegbar ist.
     * Ist keine Fachbelegung gegeben, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
     * angegeben, so ist die Prüfung erfolgreich, da kein Halbjahr geprüft werden muss.
     *
     * @param fachbelegungen    die zu prüfenden Fachnbelegungen
     * @param schriftlichkeit   die zu prüfende Schriftlichkeit
     * @param halbjahre         die zu prüfenden Halbjahre
     *
     * @return true, falls bei einer Fachbelegung die Schriftlichkeit in den Halbjahren gegeben ist, sonst false
     */
    pruefeBelegungDurchgehendBelegbarExistiert(fachbelegungen, schriftlichkeit, ...halbjahre) {
        if (fachbelegungen === null)
            return false;
        for (let fachbelegung of fachbelegungen) {
            if (this.pruefeBelegungDurchgehendBelegbar(fachbelegung, schriftlichkeit, ...halbjahre))
                return true;
        }
        return false;
    }
    /**
     * Prüft, ob die Belegung eines der angegebenen Fächer in den angegebenen Halbjahren der angegebenen Schriftlichkeit entspricht
     * und das Fach durchgängig belegt ist.
     * Ist keine Fachbelegung gegeben, so schlägt die Prüfung fehl. Wird bei einer gültigen Fachbelegung kein Halbjahr
     * angegeben, so ist die Prüfung erfolgreich sofern das Fach durchgängig belegt wurde, da kein Halbjahr auf die
     * Schriftlichkeit geprüft werden muss.
     *
     * @param fachbelegungen    die zu prüfenden Fachnbelegungen
     * @param schriftlichkeit   die zu prüfende Schriftlichkeit
     * @param halbjahre         die zu prüfenden Halbjahre
     *
     * @return true, falls bei eine Fachbelegung durchgängig belegt wurde und die Schriftlichkeit in den Halbjahren gegeben ist, sonst false
     */
    pruefeBelegungDurchgehendBelegtExistiert(fachbelegungen, schriftlichkeit, ...halbjahre) {
        if (fachbelegungen === null)
            return false;
        for (let fachbelegung of fachbelegungen) {
            if (this.pruefeBelegung(fachbelegung, GostHalbjahr_1.GostHalbjahr.EF1, GostHalbjahr_1.GostHalbjahr.EF2, GostHalbjahr_1.GostHalbjahr.Q11, GostHalbjahr_1.GostHalbjahr.Q12, GostHalbjahr_1.GostHalbjahr.Q21, GostHalbjahr_1.GostHalbjahr.Q22))
                if (this.pruefeBelegungMitSchriftlichkeit(fachbelegung, schriftlichkeit, ...halbjahre))
                    return true;
        }
        return false;
    }
    /**
     * Prüft, ob die Fachbelegung in mindestens einem der Halbjahre die angegebene Kursart aufweist.
     * Existiert die Fachbelegung nicht (null), so kommt die Kursart auch nicht vor.
     *
     * @param fachbelegung   die Fachbelegung
     * @param kursart        die Kursart
     *
     * @return true, falls mindestens einmal die Kursart belegt wurde, sonst false
     */
    pruefeAufKursart(fachbelegung, kursart) {
        if (fachbelegung === null)
            return false;
        for (let belegunghalbjahr of fachbelegung.belegungen) {
            if ((belegunghalbjahr !== null) && GostKursart_1.GostKursart.fromKuerzel(belegunghalbjahr.kursartKuerzel) === kursart)
                return true;
        }
        return false;
    }
    /**
     * Filtert die Fachbelegungen und gibt nur die Fachbelegungen zurück, bei denen die
     * Kursart existiert.
     * Wird keine Fachbelegung übergeben (null oder leere Liste), so kommt auch keine
     * Belegung mit der Kursart vor.
     *
     * @param fachbelegungen   die Fachbelegungen
     * @param kursart          die Kursart
     *
     * @return eine Liste mit den Fachbelegungen, welche die kursart haben
     */
    filterBelegungKursartExistiert(fachbelegungen, kursart) {
        let result = new Vector_1.Vector();
        if ((fachbelegungen === null) || (fachbelegungen.size() <= 0))
            return result;
        for (let fachbelegung of fachbelegungen) {
            if (this.pruefeAufKursart(fachbelegung, kursart))
                result.add(fachbelegung);
        }
        return result;
    }
    /**
     * Prüft, ob die Fachbelegung eine durchgängige Belegung hat. Zusatzkurse können nicht für eine
     * durchgängige Belegung zählen.
     *
     * @param fachbelegung   die zu prüfende Fachbelegung
     *
     * @return true, wenn die Belegung durchgängig ist.
     */
    pruefeDurchgaengigkeit(fachbelegung) {
        if ((fachbelegung === null) || (this.pruefeAufKursart(fachbelegung, GostKursart_1.GostKursart.ZK)))
            return false;
        return this.pruefeBelegung(fachbelegung, GostHalbjahr_1.GostHalbjahr.EF1, GostHalbjahr_1.GostHalbjahr.EF2, GostHalbjahr_1.GostHalbjahr.Q11, GostHalbjahr_1.GostHalbjahr.Q12, GostHalbjahr_1.GostHalbjahr.Q21, GostHalbjahr_1.GostHalbjahr.Q22);
    }
    /**
     * Zählt die Fachbelegungen, welche eine durchgängige Belegung aufweisen. Zusatzkurse zählen
     * nicht für eine durchgängige Belegung.
     * In dieser Methode wird ggf. auch geprüft, ob weitere Fachbelegungen existieren, welche das gleiche
     * Statistik-Kürzel haben und Ersatzweise eine Halbjahres-Belegung ersetzen können. Dies ist bei bilingualen
     * Fächern nötig.
     *
     * @param fachbelegungen   die zu überprüfenden Fachbelegungen
     *
     * @return die Anzahl der durchgängigen Belegungen
     */
    zaehleDurchgaengigeBelegungen(fachbelegungen) {
        if (fachbelegungen === null)
            return 0;
        let anzahl = 0;
        for (let fachbelegung of fachbelegungen) {
            let fach = this.gostFaecher.get(fachbelegung.fachID);
            if (fach === null)
                continue;
            if (fachbelegung.belegungen[GostHalbjahr_1.GostHalbjahr.EF1.id] === null)
                continue;
            let alleBelegungen = this.getFachbelegungByFachkuerzel(fach.kuerzel);
            if ((alleBelegungen === null) || (alleBelegungen.size() === 0))
                continue;
            let hatBelegung = true;
            let halbjahre = [GostHalbjahr_1.GostHalbjahr.EF1, GostHalbjahr_1.GostHalbjahr.Q11, GostHalbjahr_1.GostHalbjahr.Q12, GostHalbjahr_1.GostHalbjahr.Q21, GostHalbjahr_1.GostHalbjahr.Q22];
            for (let halbjahr of halbjahre) {
                let hatHalbjahresBelegung = false;
                for (let aktFachbelegung of alleBelegungen) {
                    if (aktFachbelegung.belegungen[halbjahr.id] !== null) {
                        hatHalbjahresBelegung = true;
                        break;
                    }
                }
                if (!hatHalbjahresBelegung) {
                    hatBelegung = false;
                    break;
                }
            }
            if (hatBelegung)
                anzahl++;
        }
        return anzahl;
    }
    /**
     * Prüft, ob die Fachbelegung eine durchgängige Belegung hat und prüft die Schriftlichkeit
     * in der Qualifikationsphase. Ein Fach in der Qualifikationsphase gilt als Schriftlich belegt,
     * sofern die ersten 3 Halbjahre der Qualifikationsphase schriftlich belegt wurden.
     * - Zusatzkurse können nicht für eine durchgängige Belegung zählen.
     *
     * @param fachbelegung   die zu prüfende die zu überprüfenden Fachbelegung
     *
     * @return true, wenn die Belegung durchgängig ist und die Schriftlichkeit den Anforderungen genügt.
     */
    pruefeDurchgaengigkeitSchriftlich(fachbelegung) {
        if (!this.pruefeDurchgaengigkeit(fachbelegung))
            return false;
        return this.pruefeBelegungMitSchriftlichkeit(fachbelegung, GostSchriftlichkeit_1.GostSchriftlichkeit.SCHRIFTLICH, GostHalbjahr_1.GostHalbjahr.Q11, GostHalbjahr_1.GostHalbjahr.Q12, GostHalbjahr_1.GostHalbjahr.Q21);
    }
    /**
     * Prüft, ob unter den angegebenen Fachbelegungen ein Fach als Abiturfach von einem der angegebenen Arten
     * gewählt wurde. Wird keine Art angebeben, so wird jede Fachbelegung akzeptiert und true zurückgegeben.
     *
     * @param fachbelegungen   die Fachbelegungen
     * @param arten            die Arten der Abiturfächer
     *
     * @return true, falls unter den Fachbelegungen mindestens ein Fach als Abiturfach von einem der
     *         angegebenen Arten gewählt wurde und false sonst
     */
    pruefeExistiertAbiFach(fachbelegungen, ...arten) {
        if ((arten === null) || (arten.length === 0))
            return true;
        if (fachbelegungen === null)
            return false;
        for (let fachbelegung of fachbelegungen)
            for (let art of arten) {
                let abiturFach = GostAbiturFach_1.GostAbiturFach.fromID(fachbelegung.abiturFach);
                if (abiturFach === art)
                    return true;
            }
        return false;
    }
    /**
     * Prüft anhand des Statistik-Kürzels, ob in dem angegebenen Halbjahr eine doppelte Fachbelegung
     * vorliegt oder nicht. Bei den Fremdsprachen werden nur unterschiedliche Fremdsprachen in einem Halbjahr
     * akzeptiert und es dürfen mehrere Vertiefungsfächer (VX) in einem Halbjahr vorkommen.
     *
     * @param halbjahr   das zu prüfende Halbjahr
     *
     * @return true, falls eine doppelte Belegung vorliegt, sonst false
     */
    hatDoppelteFachbelegungInHalbjahr(halbjahr) {
        let set = new HashSet_1.HashSet();
        let fachbelegungen = this.abidaten.fachbelegungen;
        for (let fb of fachbelegungen) {
            let fach = this.getFach(fb);
            if (fach === null)
                continue;
            let belegung = this.getBelegungHalbjahr(fb, halbjahr, GostSchriftlichkeit_1.GostSchriftlichkeit.BELIEBIG);
            if (belegung === null)
                continue;
            let kuerzel = GostFachManager_1.GostFachManager.getFremdsprache(fach);
            if (kuerzel === null)
                kuerzel = fach.kuerzel === null ? "" : fach.kuerzel;
            if (!set.add(kuerzel) && (!JavaObject_1.JavaObject.equalsTranspiler("VX", (kuerzel))))
                return true;
        }
        return false;
    }
    /**
     * Prüft anhand des Statistik-Kürzels, ob in einem der angegebenen Halbjahre eine doppelte Fachbelegung
     * vorliegt oder nicht. Bei den Fremdsprachen werden nur unterschiedliche Fremdsprachen in einem Halbjahr
     * akzeptiert und es dürfen mehrere Vertiefungsfächer (VX) in einem Halbjahr vorkommen.
     *
     * @param halbjahre   die zu prüfenden Halbjahre
     *
     * @return true, falls eine doppelte Belegung vorliegt, sonst false
     */
    hatDoppelteFachbelegung(...halbjahre) {
        if ((halbjahre === null) || (halbjahre.length === 0))
            return false;
        for (let halbjahr of halbjahre)
            if (this.hatDoppelteFachbelegungInHalbjahr(halbjahr))
                return true;
        return false;
    }
    /**
     * Gibt zurück, ob der Projektkurs als besondere Lernleistung verwendet wird.
     *
     * @return true, falls der Projektkurs als besondere Lernleistung verwendet wird
     */
    istProjektKursBesondereLernleistung() {
        return (GostBesondereLernleistung_1.GostBesondereLernleistung.PROJEKTKURS.is(this.abidaten.besondereLernleistung));
    }
    /**
     * Bestimmt die erste Fachbelegung mit dem angegebenen Statistik-Kürzel
     *
     * @param kuerzel          das Kürzel des Faches, kann null sein (dann wird auch null zurückgegeben)
     *
     * @return die Fachbelegung oder null, falls keine vorhanden ist
     */
    getFachbelegungByKuerzel(kuerzel) {
        if ((kuerzel === null) || (JavaObject_1.JavaObject.equalsTranspiler("", (kuerzel))))
            return null;
        let fachbelegungen = this.abidaten.fachbelegungen;
        for (let fb of fachbelegungen) {
            let fach = this.getFach(fb);
            if ((fach !== null) && (JavaObject_1.JavaObject.equalsTranspiler(kuerzel, (fach.kuerzel))))
                return fb;
        }
        return null;
    }
    /**
     * Liefert alle Fachbelegungen der Abiturdaten, welche den angegebenen Fachbereichen zuzuordnen sind.
     * Wird kein Fachbereich angegeben, so werden alle Fachbelegungen der Abiturdaten zurückgegeben.
     *
     * @param fachbereiche   die Fachbereiche
     *
     * @return eine Liste der Fachbelegungen aus den Fachbereichen
     */
    getFachbelegungen(...fachbereiche) {
        if ((fachbereiche === null) || (fachbereiche.length === 0))
            return this.abidaten.fachbelegungen;
        let result = new Vector_1.Vector();
        for (let fachbereich of fachbereiche) {
            let fachbelegungen = this.mapFachbereiche.get(fachbereich);
            if (fachbelegungen === null)
                continue;
            result.addAll(fachbelegungen);
        }
        return result;
    }
    /**
     * Liefert alle Fachbelegungen, die bilingual unterrichtet wurden.
     *
     * @return eine Liste der Fachbelegungen
     */
    getFachbelegungenBilingual() {
        let result = new Vector_1.Vector();
        let fachbelegungen = this.abidaten.fachbelegungen;
        for (let fb of fachbelegungen) {
            if (this.zaehleBelegung(fb) <= 0)
                continue;
            let fach = this.getFach(fb);
            if ((fach !== null) && (!GostFachbereich_1.GostFachbereich.FREMDSPRACHE.hat(fach)) && (!GostFachbereich_1.GostFachbereich.DEUTSCH.hat(fach)) && (fach.biliSprache !== null) && (!JavaObject_1.JavaObject.equalsTranspiler("D", (fach.biliSprache))))
                result.add(fb);
        }
        return result;
    }
    /**
     * Filtert die Fachbelegungen auf neu einsetzende Fremdsprachen.
     *
     * @param fachbelegungen   die zu filternden Fachbelegungen
     *
     * @return die gefilterten Fachbelegungen
     */
    filterFremdspracheNeuEinsetzend(fachbelegungen) {
        if (fachbelegungen === null)
            return Collections_1.Collections.emptyList();
        let result = new Vector_1.Vector();
        for (let fb of fachbelegungen) {
            let fach = this.getFach(fb);
            if ((fach !== null) && fach.istFremdsprache && fach.istFremdSpracheNeuEinsetzend)
                result.add(fb);
        }
        return result;
    }
    /**
     * Filtert die Fachbelegungen auf fortgeführte Fremdsprachen.
     *
     * @param fachbelegungen   die zu filternden Fachbelegungen
     *
     * @return die gefilterten Fachbelegungen
     */
    filterFremdspracheFortgefuehrt(fachbelegungen) {
        if (fachbelegungen === null)
            return Collections_1.Collections.emptyList();
        let result = new Vector_1.Vector();
        for (let fb of fachbelegungen) {
            let fach = this.getFach(fb);
            if ((fach !== null) && fach.istFremdsprache && !fach.istFremdSpracheNeuEinsetzend)
                result.add(fb);
        }
        return result;
    }
    /**
     * Filtert die Fachbelegungen danach, ob sie durchgehend belegbar sind
     *
     * @param fachbelegungen   die zu filternden Fachbelegungen
     *
     * @return die gefilterten Fachbelegungen
     */
    filterDurchgehendBelegbar(fachbelegungen) {
        let result = new Vector_1.Vector();
        if (fachbelegungen === null)
            return result;
        for (let fb of fachbelegungen) {
            let fach = this.getFach(fb);
            if (GostFachManager_1.GostFachManager.istDurchgehendBelegbarBisQ22(fach))
                result.add(fb);
        }
        return result;
    }
    /**
     * Filtert die Fachbelegungen. Es werden nur Fachbelegungen behalten, die in den angegebenen Halbjahren eine Belegung aufweisen.
     * Wird kein Halbjahr angegeben, so wird nichts gefiltert, da kein Halbjahr geprüft werden muss.
     *
     * @param fachbelegungen    die zu filternden Fachbelegungen
     * @param halbjahre         die Halbjahre, die belegt sein müssen
     *
     * @return die gefilterten Fachbelegungen
     */
    filterBelegungen(fachbelegungen, ...halbjahre) {
        if (fachbelegungen === null)
            return Collections_1.Collections.emptyList();
        let result = new Vector_1.Vector();
        for (let fb of fachbelegungen) {
            if (this.pruefeBelegung(fb, ...halbjahre))
                result.add(fb);
        }
        return result;
    }
    /**
     * Diese Methode zählt die Anzahl der angegebenen Fachbelegungen, welche in allen
     * Halbjahren belegt sind. Dabei werden Fachbelegungen, welche dem gleichem Statistik-Fach
     * zuzuordnen sind zusammengefasst. Dies ist bei der Abwahl von bilingualen Sachfächern
     * relevant.
     *
     * @param fachbelegungen   die zu zählenden Fachbelegungen
     *
     * @return die Anzahl der Fachbelegungen
     */
    zaehleBelegungenDurchgaengig(fachbelegungen) {
        if (fachbelegungen === null)
            return 0;
        let faecher = new HashSet_1.HashSet();
        for (let fb of fachbelegungen) {
            let fach = this.gostFaecher.get(fb.fachID);
            if (fach === null)
                continue;
            let zulFach = ZulaessigesFach_1.ZulaessigesFach.getByKuerzelASD(fach.kuerzel);
            if (zulFach !== ZulaessigesFach_1.ZulaessigesFach.DEFAULT)
                faecher.add(zulFach);
        }
        let count = 0;
        for (let zulFach of faecher) {
            let vorhanden = true;
            for (let halbjahr of GostHalbjahr_1.GostHalbjahr.values()) {
                let belegung_vorhanden = false;
                for (let fb of fachbelegungen) {
                    let fbFach = this.gostFaecher.get(fb.fachID);
                    if (fbFach === null)
                        continue;
                    let fbZulFach = ZulaessigesFach_1.ZulaessigesFach.getByKuerzelASD(fbFach.kuerzel);
                    if ((zulFach === fbZulFach) && (fb.belegungen[halbjahr.id] !== null)) {
                        belegung_vorhanden = true;
                        break;
                    }
                }
                if (!belegung_vorhanden) {
                    vorhanden = false;
                    break;
                }
            }
            if (vorhanden)
                count++;
        }
        return count;
    }
    /**
     * Diese Methode zählt die Anzahl der angegebenen Fachbelegungen, welche in allen
     * Halbjahren belegt sind. Dabei werden Fachbelegungen, welche dem gleichem Statistik-Fach
     * zuzuordnen sind zusammengefasst. Dies ist bei der Abwahl von bilingualen Sachfächern
     * relevant.
     *
     * @param fachbelegungen   die zu zählenden Fachbelegungen
     *
     * @return die Anzahl der Fachbelegungen
     */
    zaehleBelegungenDurchgaengigSchriftlichInQPhase(fachbelegungen) {
        if (fachbelegungen === null)
            return 0;
        let faecher = new HashSet_1.HashSet();
        for (let fb of fachbelegungen) {
            let fach = this.gostFaecher.get(fb.fachID);
            if (fach === null)
                continue;
            let zulFach = ZulaessigesFach_1.ZulaessigesFach.getByKuerzelASD(fach.kuerzel);
            if (zulFach !== ZulaessigesFach_1.ZulaessigesFach.DEFAULT)
                faecher.add(zulFach);
        }
        let count = 0;
        for (let zulFach of faecher) {
            let vorhanden = true;
            for (let halbjahr of GostHalbjahr_1.GostHalbjahr.values()) {
                let belegung_vorhanden = false;
                for (let fb of fachbelegungen) {
                    let fbFach = this.gostFaecher.get(fb.fachID);
                    if (fbFach === null)
                        continue;
                    let fbZulFach = ZulaessigesFach_1.ZulaessigesFach.getByKuerzelASD(fbFach.kuerzel);
                    if (zulFach === fbZulFach) {
                        let belegung = fb.belegungen[halbjahr.id];
                        if (belegung !== null) {
                            let istSchriftlichkeitOK = true;
                            if (((halbjahr === GostHalbjahr_1.GostHalbjahr.Q11) || (halbjahr === GostHalbjahr_1.GostHalbjahr.Q12) || (halbjahr === GostHalbjahr_1.GostHalbjahr.Q21)) && ((belegung.schriftlich === null) || (!belegung.schriftlich)))
                                istSchriftlichkeitOK = false;
                            if (istSchriftlichkeitOK) {
                                belegung_vorhanden = true;
                                break;
                            }
                        }
                    }
                }
                if (!belegung_vorhanden) {
                    vorhanden = false;
                    break;
                }
            }
            if (vorhanden)
                count++;
        }
        return count;
    }
    /**
     * Filtert die Fachbelegungen. Es werden nur Belegungen behalten, die in den angegebenen Halbjahren die geforderte Schriftlichkeit aufweisen.
     * Wird kein Halbjahr angegeben, so wird nichts gefiltert, da kein Halbjahr geprüft werden muss.
     *
     * @param fachbelegungen    die zu filternden Fachbelegungen
     * @param schriftlichkeit   die geforderte Schriftlichkeit
     * @param halbjahre         die Halbjahre, die belegt sein müssen
     *
     * @return die gefilterten Fachbelegungen
     */
    filterBelegungenMitSchriftlichkeit(fachbelegungen, schriftlichkeit, ...halbjahre) {
        if (fachbelegungen === null)
            return Collections_1.Collections.emptyList();
        let result = new Vector_1.Vector();
        for (let fb of fachbelegungen) {
            if (this.pruefeBelegungMitSchriftlichkeit(fb, schriftlichkeit, ...halbjahre))
                result.add(fb);
        }
        return result;
    }
    /**
     * Liefert die erste Fachbelegung für den Fachbereich - sofern eine existiert
     *
     * @param fachbereich   der Fachbereich
     *
     * @return die Fachbelegung oder null
     */
    getFachbelegung(fachbereich) {
        let faecher = this.mapFachbereiche.get(fachbereich);
        if ((faecher === null) || (faecher.size() === 0))
            return null;
        return faecher.get(0);
    }
    /**
     * Liefert alle Fachbelegungen mit dem angegebenen Statistk-Kürzel des Faches
     *
     * @param kuerzel   das Kürzel des Faches
     *
     * @return eine Liste mit den Fachbelegungen
     */
    getFachbelegungByFachkuerzel(kuerzel) {
        let fachbelegungen = new Vector_1.Vector();
        if (kuerzel === null)
            return fachbelegungen;
        let tmpFachbelegungen = this.abidaten.fachbelegungen;
        for (let fachbelegung of tmpFachbelegungen) {
            let fach = this.gostFaecher.get(fachbelegung.fachID);
            if ((fach === null) || (!JavaObject_1.JavaObject.equalsTranspiler(kuerzel, (fach.kuerzel))))
                continue;
            fachbelegungen.add(fachbelegung);
        }
        return fachbelegungen;
    }
    /**
     * Prüft, ob der Kurs in dem angegebenen Halbjahr mit der angegebenen Schriftlichkeit belegt ist
     * und gibt ggf. die Belegung zurück.
     *
     * @param fachbelegung   die Abiturfachbelegung aus welcher die Belegungsinformationen für das Halbjahr entnommen wird
     * @param halbjahr       das Halbjahr, in welchem die Belegung gesucht wird.
     * @param schriftlich    gibt an, ob das Fach schriftlich oder mündlich belegt sein muss
     *
     * @return die Belegungsinformationen zu dem Fach
     */
    getBelegungHalbjahr(fachbelegung, halbjahr, schriftlich) {
        let belegung = fachbelegung.belegungen[halbjahr.id];
        return ((belegung !== null) && ((schriftlich === GostSchriftlichkeit_1.GostSchriftlichkeit.BELIEBIG) || ((schriftlich === GostSchriftlichkeit_1.GostSchriftlichkeit.SCHRIFTLICH) && (belegung.schriftlich)) || ((schriftlich === GostSchriftlichkeit_1.GostSchriftlichkeit.MUENDLICH) && (!belegung.schriftlich)))) ? belegung : null;
    }
    /**
     * Liefert die erste Sprachbelegung - sofern eine existiert
     *
     * @param sprache   das einstellige Kürzel der Sprache
     *
     * @return die Fachbelegung für die Sprache
     */
    getSprachbelegung(sprache) {
        if (sprache === null)
            return null;
        let fachbelegungen = this.abidaten.fachbelegungen;
        for (let fb of fachbelegungen) {
            let fach = this.getFach(fb);
            if ((fach === null) || (!GostFachManager_1.GostFachManager.istFremdsprachenfach(fach, sprache)))
                continue;
            if (JavaObject_1.JavaObject.equalsTranspiler(sprache, (GostFachManager_1.GostFachManager.getFremdsprache(fach))))
                return fb;
        }
        return null;
    }
    /**
     * Liefert für die übergebene Fachbelegung die Halbjahre, in denen das Fach mit einer der angebenen
     * Kursarten belegt wurde. Ist keine Kursart angegeben, so werden die Halbjahre aller Belegungen
     * zurückgegeben. Ist keine Fachbelegung angegeben, so wird eine leere Liste zurückgegeben.
     *
     * @param fachbelegung   die Fachbelegung
     * @param kursarten      die Kursarten
     *
     * @return eine Liste der Halbjahre in den das Fach mit einer der Kursarten belegt wurde
     */
    getHalbjahreKursart(fachbelegung, ...kursarten) {
        let halbjahre = new Vector_1.Vector();
        if (fachbelegung !== null) {
            for (let belegungHalbjahr of fachbelegung.belegungen) {
                if (belegungHalbjahr === null)
                    continue;
                let halbjahr = GostHalbjahr_1.GostHalbjahr.fromKuerzel(belegungHalbjahr.halbjahrKuerzel);
                if (halbjahr === null)
                    continue;
                if ((kursarten === null) || (kursarten.length === 0)) {
                    halbjahre.add(halbjahr);
                    continue;
                }
                for (let kursart of kursarten) {
                    if (JavaObject_1.JavaObject.equalsTranspiler(kursart, (GostKursart_1.GostKursart.fromKuerzel(belegungHalbjahr.kursartKuerzel)))) {
                        halbjahre.add(halbjahr);
                        break;
                    }
                }
            }
        }
        return halbjahre;
    }
    /**
     * Gibt die Sprache des bilingualen Bildungsgang zurück oder null, falls keiner gewählt wurde.
     *
     * @return die Sprache des bilingualen Bildungsgang oder null
     */
    getBiligualenBildungsgang() {
        return this.abidaten.bilingualeSprache;
    }
    /**
     * Prüft bei der Sprachenfolge, ob eine laut Sprachenfolge fortgeführte
     * Fremdsprache fehlerhafterweise als neu einsetzende Fremdsprache belegt wurde.
     * Übergebene Fachbelegungen, die keine Fremdsprachen sind werden ignoriert.
     *
     * @param fremdsprachen   die zu prüfenden Fachbelegungen
     *
     * @return true, falls eine fortgeführte Fremdsprache bei den übergebenen
     *         Fachbelegungen existiert, ansonsten false
     */
    hatFortgefuehrteFremdspracheInSprachendaten(fremdsprachen) {
        if (fremdsprachen === null)
            return false;
        if (this.abidaten.sprachendaten === null)
            return false;
        for (let fs of fremdsprachen) {
            let fach = this.getFach(fs);
            if ((fach === null) || (!fach.istFremdsprache))
                continue;
            if (SprachendatenManager_1.SprachendatenManager.istFortfuehrbareSpracheInGOSt(this.abidaten.sprachendaten, GostFachManager_1.GostFachManager.getFremdsprache(fach))) {
                return true;
            }
        }
        return false;
    }
    /**
     * Prüft bei der Sprachenfolge, ob für eine laut Sprachenfolge neu einsetzende
     * Fremdsprache fehlerhafterweise ein Kurs in einer fortgeführten Fremdsprache belegt wurde.
     * Übergebene Fachbelegungen, die keine Fremdsprachen sind werden ignoriert.
     *
     * @param fremdsprachen   die zu prüfenden Fachbelegungen
     *
     * @return true, falls eine neu einsetzende Fremdsprache bei den übergebenen
     *         Fachbelegungen existiert, ansonsten false
     */
    hatNeuEinsetzendeFremdspracheInSprachendaten(fremdsprachen) {
        if (fremdsprachen === null)
            return false;
        if (this.abidaten.sprachendaten === null)
            return false;
        for (let fs of fremdsprachen) {
            let fach = this.getFach(fs);
            if ((fach === null) || (!fach.istFremdsprache))
                continue;
            if (!SprachendatenManager_1.SprachendatenManager.istFortfuehrbareSpracheInGOSt(this.abidaten.sprachendaten, GostFachManager_1.GostFachManager.getFremdsprache(fach))) {
                return true;
            }
        }
        return false;
    }
    /**
     * Gibt an, ob am Ende der EF eine Muttersprachenprüfung geplant bzw. erfolgt ist.
     *
     * @return true, falls eine Muttersprachenprüfung am Ende der EF vorliegt, sonst false
     */
    hatMuttersprachenPruefungEndeEF() {
        return this.abidaten.muttersprachenpruefungEndeEF;
    }
    /**
     * Gibt an, ob die zweite Fremdsprache in der Sekundarstufe manuell erfolgreich
     * geprüft wurde und dort eine entsprechende Belegung existiert.
     *
     * @return true, falls in der Sek I eine zweite Fremdsprache belegt wurde
     */
    istSekIZweiteFremdspracheManuellGeprueft() {
        return this.abidaten.sek1Fremdsprache2ManuellGeprueft;
    }
    /**
     * Prüft, ob die Belegung seit der EF1 vorhanden ist. Hierbei werden
     * Zusatz-, Vertiefungs- und Projektkurse auch als später einsetzend akzeptiert.
     * Dies gilt auch für Literatur, instrumental- und vokalpraktische Kurse sowie
     * für Religion und Philosophie.
     *
     * @param fachbelegung   die Abiturfachbelegungen, die geprüft werden
     *
     * @return true, falls das Fach seit EF1 durchgängig belegt wurde oder eine der Ausnahmen zutrifft, sonsta false
     */
    istBelegtSeitEF(fachbelegung) {
        let fach = this.getFach(fachbelegung);
        if (fach === null)
            return false;
        if (GostFachbereich_1.GostFachbereich.LITERARISCH_KUENSTLERISCH_ERSATZ.hat(fach))
            return true;
        if (GostFachbereich_1.GostFachbereich.RELIGION.hat(fach))
            return true;
        if (JavaObject_1.JavaObject.equalsTranspiler("PL", (fach.kuerzel)))
            return true;
        for (let belegung of fachbelegung.belegungen) {
            if (belegung === null)
                continue;
            let halbjahr = GostHalbjahr_1.GostHalbjahr.fromKuerzel(belegung.halbjahrKuerzel);
            let kursart = GostKursart_1.GostKursart.fromKuerzel(belegung.kursartKuerzel);
            if ((halbjahr === null) || (kursart === null))
                continue;
            if ((kursart === GostKursart_1.GostKursart.ZK) || (kursart === GostKursart_1.GostKursart.PJK) || (kursart === GostKursart_1.GostKursart.VTF))
                continue;
            let prevHalbjahr = halbjahr.previous();
            if (prevHalbjahr === null)
                continue;
            if (fachbelegung.belegungen[prevHalbjahr.id] === null) {
                let alleBelegungen = this.getFachbelegungByFachkuerzel(fach.kuerzel);
                if ((alleBelegungen === null) || (alleBelegungen.size() <= 1))
                    return false;
                if (!this.pruefeBelegungExistiert(alleBelegungen, prevHalbjahr))
                    return false;
            }
        }
        return true;
    }
    /**
     * Gibt das Ergebnis der Belegprüfung zurück. Dieses enthält eine Liste der Fehler, die bei der Belegprüfung
     * festgestellt wurden und ob diese erfolgreich gewesen ist oder nicht.
     *
     * @return das Ergebnis der Belegprüfung
     */
    getBelegpruefungErgebnis() {
        let ergebnis = new GostBelegpruefungErgebnis_1.GostBelegpruefungErgebnis();
        ergebnis.erfolgreich = this.belegpruefungErfolgreich;
        for (let i = 0; i < this.belegpruefungsfehler.size(); i++) {
            let fehler = this.belegpruefungsfehler.get(i);
            ergebnis.fehlercodes.add(new GostBelegpruefungErgebnisFehler_1.GostBelegpruefungErgebnisFehler(fehler, this.pruefungsArt));
        }
        return ergebnis;
    }
    isTranspiledInstanceOf(name) {
        return ['de.nrw.schule.svws.core.abschluss.gost.AbiturdatenManager'].includes(name);
    }
}
exports.AbiturdatenManager = AbiturdatenManager;
function cast_de_nrw_schule_svws_core_abschluss_gost_AbiturdatenManager(obj) {
    return obj;
}
exports.cast_de_nrw_schule_svws_core_abschluss_gost_AbiturdatenManager = cast_de_nrw_schule_svws_core_abschluss_gost_AbiturdatenManager;
//# sourceMappingURL=AbiturdatenManager.js.map