/* Copyright 2014-2023 askanimus@gmail.com */

/* This File is part of "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2).
 *
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2).  If not, see <http://www.gnu.org/licenses/>.
 *
 * Diese Datei ist Teil von "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2).
 *
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) ist Freie Software: Sie können es unter den Bedingungen
 * der GNU General Public License, wie von der Free Software Foundation,
 * Version 3 der Lizenz oder (nach Ihrer Wahl) jeder neueren
 * veröffentlichten Version, weiter verteilen und/oder modifizieren.
 *
 * "Arbeitszeitkonto" (askanimus.arbeitszeiterfassung2) wird in der Hoffnung, dass es nützlich sein wird, aber
 * OHNE JEDE GEWÄHRLEISTUNG, bereitgestellt; sogar ohne die implizite
 * Gewährleistung der MARKTFÄHIGKEIT oder EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
 * Siehe die GNU General Public License für weitere Details.
 *
 * Sie sollten eine Kopie der GNU General Public License zusammen mit diesem
 * Programm erhalten haben. Wenn nicht, siehe <https://www.gnu.org/licenses/>.
 */
package askanimus.arbeitszeiterfassung2.export;

import android.content.Context;

import com.pdfjet.Cell;

import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;

import askanimus.arbeitszeiterfassung2.R;
import askanimus.arbeitszeiterfassung2.StorageHelper;
import askanimus.arbeitszeiterfassung2.Zeitraum.IZeitraum;
import askanimus.arbeitszeiterfassung2.abwesenheiten.Abwesenheit;
import askanimus.arbeitszeiterfassung2.arbeitsplatz.Arbeitsplatz;
import askanimus.arbeitszeiterfassung2.arbeitsschicht.Arbeitsschicht;
import askanimus.arbeitszeiterfassung2.arbeitstag.Arbeitstag;
import askanimus.arbeitszeiterfassung2.setup.ASettings;
import askanimus.arbeitszeiterfassung2.zusatzeintrag.IZusatzfeld;
import askanimus.arbeitszeiterfassung2.zusatzeintrag.ZusatzfeldDefinition;

/**
 * @author askanimus@gmail.com
 */
class Export_PDF_Zeitraum_LGAV extends AExport_Zeitraum_PDF implements IExport_Zeitraum_PDF {
    //boolean farbeHintergrund;
    int positionSaldo;
    int maxSchichten = 0;

    Export_PDF_Zeitraum_LGAV(
            Context context,
            IZeitraum zeitraum,
            BitSet spalten,
            BitSet optionen,
            BitSet zusatzwerte,
            String notiz,
            StorageHelper storageHelper
            //String pfad
    ) throws Exception {
        super(context, zeitraum, spalten, optionen, zusatzwerte, null);
        // farbeHintergrund = false;

        // den Dateiname zusammenstellen
        //String dateiname = mZeitraum.getDateiname(context, R.string.exp_mon_lgav);
        //dateiname = ExportActivity.makeExportpfad(context, pfad, dateiname);

        if (mOptionen.get(OPTION_ZUSATZTABELLE_EORT)) {
            setupSeite(
                    TABTYP_ZEITRAUM,
                    mOptionen,
                    //false,
                    zeitraum.getTitel(context),
                    context.getString(R.string.sort_eort),
                    notiz,
                    zeitraum.getPDFFontSize()
            );
        } else {
            setupSeite(
                    TABTYP_ZEITRAUM,
                    mOptionen,
                    //false,
                    zeitraum.getTitel(context),
                    null,
                    notiz,
                    zeitraum.getPDFFontSize()
            );
        }

        schreibeTabelle(
                storageHelper,
                mZeitraum.getDateiname(context, R.string.exp_mon_lgav),
                TYP_PDF
        );
    }

    @Override
    public ArrayList<AExportBasis.Spalte> makeSpaltenSet(
            BitSet spalten,
            BitSet zusatzwerte,
            Arbeitsplatz arbeitsplatz) {
        ArrayList<Spalte> listSpalten = new ArrayList<>();
        String[] namen = ASettings.res.getStringArray(R.array.export_spalten);
        int spalteNetto = 0;
        int spalteVerdienst = 0;
        boolean isText = false;

        // maximale Anzahl Schichten pro Tag in dieser Periode ermitteln
        for (Arbeitstag tag : mZeitraum.getTage()) {
            maxSchichten = Math.max(maxSchichten, tag.getSchichtAnzahl());
        }

        // die regulären Spalten
        listSpalten.add(new Spalte(IExport_Basis.SPALTE_DATUM, namen[IExport_Basis.SPALTE_DATUM], true));
        for (int i = 0; i < maxSchichten; i++) {
            if(mSpalten.get(SPALTE_EORT)){
              listSpalten.add(new Spalte(IExport_Basis.SPALTE_EORT, namen[IExport_Basis.SPALTE_EORT], true));
            }
            listSpalten.add(new Spalte(IExport_Basis.SPALTE_VON, namen[IExport_Basis.SPALTE_VON], false));
            listSpalten.add(new Spalte(IExport_Basis.SPALTE_BIS, namen[IExport_Basis.SPALTE_BIS], false));
        }

        for (int s = IExport_Basis.SPALTE_BRUTTO; s <= IExport_Basis.DEF_MAXBIT_SPALTE; s++) {
            if(spalten.get(s)){
                isText = s==SPALTE_ANGELEGT || s==SPALTE_AENDERUNG;
                listSpalten.add(new Spalte(s, namen[s], isText));

                if(s == IExport_Basis.SPALTE_NETTO){
                    spalteNetto = listSpalten.size()-1;
                } else if(s == IExport_Basis.SPALTE_VERDIENST){
                    spalteVerdienst = listSpalten.size()-1;
                }
            }
        }

        // die Zusatzwerte
        for(int z=0; z<arbeitsplatz.getZusatzfeldListe().size(); z++){
            if(zusatzwerte.get(z)) {
                ZusatzfeldDefinition zDef = arbeitsplatz.getZusatzDefinition(z);
                if (zDef != null) {
                    int s = IExport_Basis.SPALTE_ZUSATZ + z;
                    switch (zDef.getWirkung()) {
                        case IZusatzfeld.ADD_VERDIENST:
                        case IZusatzfeld.SUB_VERDIENST:
                            if (spalteVerdienst > 0) {
                                listSpalten.add(spalteVerdienst, new Spalte(s, zDef.getName(), false));
                            } else {
                                listSpalten.add(new Spalte(s, zDef.getName(), false));
                            }
                            break;
                        case IZusatzfeld.ADD_ISTSTUNDEN:
                        case IZusatzfeld.SUB_ISTSTUNDEN:
                        case IZusatzfeld.SUB_SOLLSTUNDEN:
                            if (spalteNetto > 0) {
                                listSpalten.add(spalteNetto, new Spalte(s, zDef.getName(), false));
                            } else {
                                listSpalten.add(new Spalte(s, zDef.getName(), false));
                            }
                            break;
                        default:
                            listSpalten.add(new Spalte(s,
                                    zDef.getName(),
                                    (zDef.getTyp() == IZusatzfeld.TYP_TEXT)));
                    }
                }
            }
        }


        return listSpalten;
    }

    @Override
    public void makeTabellenKopf(List<List<Cell>> tableData) {
        Arbeitsplatz mJob = mZeitraum.getArbeitsplatz();
        ArrayList<Cell> row = new ArrayList<>();
        int colspan;

        //Kopfzeile 1
        if (mSpalten.get(SPALTE_DATUM)) {
            row.add(makeZelleLeer(false));
        }

        if (mSpalten.get(SPALTE_EORT)) {
            colspan = 3;
        } else {
            colspan = 2;
        }

        for (int i = 0; i < maxSchichten; i++) {
            if(mArbeitsplatz.isTeilschicht() && i < mArbeitsplatz.getAnzahlSchichten()) {
                row.add(makeZelleKopf(mArbeitsplatz.getDefaultSchichten().getAktive(i).getName()));
            } else {
                row.add(makeZelleLeer(false));
            }
            if (mSpalten.get(SPALTE_EORT)) {
                row.add(makeZelleLeer(false));
            }
            row.add(makeZelleLeer(false));
            row.get(row.size() - colspan).setColSpan(colspan);
        }

        colspan = 3;
        row.add(makeZelleKopf(ASettings.res.getString(R.string.arbeitszeit)));
        row.add(makeZelleLeer(false));
        row.add(makeZelleLeer(false));
        for (Spalte spalte : mSpaltenSatz) {
            if (spalte.mSpalte >= SPALTE_ZUSATZ) {
                switch (mJob.getZusatzDefinition(spalte.mSpalte - SPALTE_ZUSATZ).getWirkung()) {
                    case IZusatzfeld.ADD_ISTSTUNDEN:
                    case IZusatzfeld.SUB_ISTSTUNDEN:
                    case IZusatzfeld.SUB_SOLLSTUNDEN:
                        row.add(makeZelleLeer(false));
                        colspan++;
                        break;
                }
            }
        }
        row.get(row.size() - colspan).setColSpan(colspan);
        positionSaldo = row.size() - 2;

        for (Spalte spalte : mSpaltenSatz) {
            if (spalte.mSpalte == SPALTE_VERDIENST) {
                row.add(makeZelleKopf(ASettings.res.getString(R.string.gehalt)));
            } else {
                if (spalte.mSpalte >= SPALTE_ZUSATZ) {
                    switch (mJob.getZusatzDefinition(spalte.mSpalte - SPALTE_ZUSATZ).getWirkung()) {
                        case IZusatzfeld.NEUTRAL:
                        case IZusatzfeld.SUB_VERDIENST:
                        case IZusatzfeld.ADD_VERDIENST:
                            row.add(makeZelleKopf(spalte.mName));
                            break;
                    }
                }
            }
        }
        tableData.add(row);

        //Kopfzeile 2
        row = new ArrayList<>();
        //leere Zelle unter Datum
        if (mSpalten.get(SPALTE_DATUM)) {
            row.add(makeZelleKopf(ASettings.res.getString(R.string.datum)));
        }
        for (int i = 0; i < maxSchichten; i++) {
            if (mSpalten.get(SPALTE_EORT)) {
                row.add(makeZelleKopf(ASettings.res.getString(R.string.einsatzort)));
            }
            row.add(makeZelleKopf(ASettings.res.getString(R.string.von)));
            row.add(makeZelleKopf(ASettings.res.getString(R.string.bis)));
        }
        row.add(makeZelleKopf(ASettings.res.getString(R.string.brutto)));
        row.add(makeZelleKopf(ASettings.res.getString(R.string.pause)));
        for (Spalte spalte : mSpaltenSatz) {
            if (spalte.mSpalte >= SPALTE_ZUSATZ) {
                switch (mJob.getZusatzDefinition(spalte.mSpalte - SPALTE_ZUSATZ).getWirkung()) {
                    case IZusatzfeld.ADD_ISTSTUNDEN:
                    case IZusatzfeld.SUB_ISTSTUNDEN:
                    case IZusatzfeld.SUB_SOLLSTUNDEN:
                        row.add(makeZelleKopf(spalte.mName));
                        break;
                }
            }
        }
        row.add(makeZelleKopf(ASettings.res.getString(R.string.netto)));

        for (Spalte spalte : mSpaltenSatz) {
            if (spalte.mSpalte == SPALTE_VERDIENST) {
                row.add(makeZelleKopf(ASettings.sWaehrung));
            } else {
                if (spalte.mSpalte >= SPALTE_ZUSATZ) {
                    switch (mJob.getZusatzDefinition(spalte.mSpalte - SPALTE_ZUSATZ).getWirkung()) {
                        case IZusatzfeld.NEUTRAL:
                        case IZusatzfeld.SUB_VERDIENST:
                        case IZusatzfeld.ADD_VERDIENST:
                            row.add(makeZelleKopf(mJob.getZusatzDefinition(spalte.mSpalte - SPALTE_ZUSATZ).getEinheit()));
                            break;
                    }
                }
            }
        }
        tableData.add(row);
    }


    @Override
    public void makeTageszeile(List<List<Cell>> tableData, Arbeitstag tag, boolean farbeHintergrund) {
        Arbeitsplatz mJob = mZeitraum.getArbeitsplatz();
        ArrayList<Cell> row = new ArrayList<>();

        // Das Datum
        if (mSpalten.get(SPALTE_DATUM)) {
            row.add(makeZelleString(fDatum.format(tag.getKalender().getDate()), farbeHintergrund));
        }

        // die Zeiten oder Abwesenheiten der einzelnen Schichten
        for (Arbeitsschicht schicht : tag.getSchichten()) {
            // Einsatzort
            if (mSpalten.get(SPALTE_EORT)) {
                row.add(makeZelleString(schicht.getNameEinsatzort(), farbeHintergrund));
            }
            if (schicht.getAbwesenheit().getWirkung() == Abwesenheit.WIRKUNG_IST_PLUS_EFFEKTIV
                    && schicht.getAbwesenheit().getKategorie() != Abwesenheit.KAT_ZUSCHLAG) {
                row.add(makeZelleUhrzeit(schicht.getVon(), farbeHintergrund));
                row.add(makeZelleUhrzeit(schicht.getBis(), farbeHintergrund));
            } else {
                if (schicht.getAbwesenheit().getKategorie() != Abwesenheit.KAT_KEINESCHICHT) {
                    row.add(makeZelleString(schicht.getAbwesenheit().getName(), farbeHintergrund));
                } else {
                    row.add(makeZelleString("", farbeHintergrund));
                }
                row.add(makeZelleString("", farbeHintergrund));
                if (mSpalten.get(SPALTE_VON)) {
                    row.get(row.size() - 2).setColSpan(2);
                }
            }
        }

        // leere Schichten auffüllen
        for (int i = tag.getSchichtAnzahl(); i < maxSchichten; i++) {
            if (mSpalten.get(SPALTE_EORT)) {
                row.add(makeZelleString("", farbeHintergrund));
            }
            row.add(makeZelleString("", farbeHintergrund));
            row.add(makeZelleString("", farbeHintergrund));
        }

        // Brutto
        row.add(makeZelleStunden(tag.getTagBrutto(), isDezimal, false, farbeHintergrund));

        //Pause
        row.add(makeZelleStunden(tag.getTagPause(), isDezimal, false, farbeHintergrund));

        // evtl. Arbeitszeit beeinflussende Zusatzzeiten
        for (Spalte spalte : mSpaltenSatz) {
            if (spalte.mSpalte >= SPALTE_ZUSATZ) {
                switch (mJob.getZusatzDefinition(spalte.mSpalte - SPALTE_ZUSATZ).getWirkung()) {
                    case IZusatzfeld.ADD_ISTSTUNDEN:
                    case IZusatzfeld.SUB_ISTSTUNDEN:
                    case IZusatzfeld.SUB_SOLLSTUNDEN:
                        row.add(makeZelleStunden(
                                (int) tag.getTagZusatzwert(spalte.mSpalte - SPALTE_ZUSATZ).getWert(),
                                isDezimal,
                                false,
                                farbeHintergrund
                        ));
                        break;
                }
            }
        }

        //netto
        row.add(makeZelleStunden(tag.getTagNetto(), isDezimal, false, farbeHintergrund));

        // die restlichen Zusatzwerte
        for (Spalte spalte : mSpaltenSatz) {
            if (spalte.mSpalte == SPALTE_VERDIENST) {
                row.add(makeZelleWert(tag.getTagVerdienst(), ASettings.waehrungformat, farbeHintergrund));
            } else {
                if (spalte.mSpalte >= SPALTE_ZUSATZ) {
                    switch (mJob.getZusatzDefinition(spalte.mSpalte - SPALTE_ZUSATZ).getWirkung()) {
                        case IZusatzfeld.NEUTRAL:
                        case IZusatzfeld.SUB_VERDIENST:
                        case IZusatzfeld.ADD_VERDIENST:
                            row.add(
                                    makeZelleZusatzwert(
                                            tag.getTagZusatzwert(spalte.mSpalte - SPALTE_ZUSATZ),
                                            isDezimal,
                                            farbeHintergrund,
                                            true
                                    )
                            );
                            break;
                    }
                }
            }
        }
        tableData.add(row);
        farbeHintergrund = !farbeHintergrund;
    }

    /*@Override
    public void makeSummenzeile(List<List<Cell>> tableData) {
        int maxRows = tableData.get(0).size();
        // Iststunden
        tableData.add(addSummeZeile(
                positionSaldo,
                maxRows,
                ASettings.res.getString(R.string.ist),
                mZeitraum.getNetto(),
                isDezimal,
                false)
        );

        // Sollstunden
        tableData.add(addSummeZeile(
                positionSaldo,
                maxRows,
                ASettings.res.getString(R.string.soll),
                mZeitraum.getSoll(),
                isDezimal,
                false)
        );

        // die Saldo Zeilen

        // die Soll/Ist Differenz
        tableData.add(addSummeZeile(
                positionSaldo,
                maxRows,
                ASettings.res.getString(R.string.diff),
                mZeitraum.getNetto() - mZeitraum.getSoll(),
                isDezimal,
                !mZeitraum.isMonat()));
        if (mZeitraum.isMonat()) {
            // Saldo Vormonat
            tableData.add(addSummeZeile(
                    positionSaldo,
                    maxRows,
                    ASettings.res.getString(R.string.saldo_vm),
                    mZeitraum.getSaldoUebertrag(),
                    isDezimal,
                    false));

            // Ausbezahlte Überstunden
            if (mZeitraum.getAuszahlung() > 0)
                tableData.add(addSummeZeile(
                        positionSaldo,
                        maxRows,
                        ASettings.res.getString(R.string.ueberstunden_ausbezahlt),
                        -mZeitraum.getAuszahlung(),
                        isDezimal,
                        false));

            //Saldo
            tableData.add(addSummeZeile(
                    positionSaldo,
                    maxRows,
                    ASettings.res.getString(R.string.saldo),
                    mZeitraum.getSaldo(),
                    isDezimal,
                    true));
        }
        tableData.get(tableData.size() - 1).get(positionSaldo).setUnderline(true);
    }*/
}
