/* 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 com.pdfjet.Table;

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

import askanimus.arbeitszeiterfassung2.StorageHelper;
import askanimus.arbeitszeiterfassung2.Zeitraum.IZeitraum;
import askanimus.arbeitszeiterfassung2.arbeitsplatz.Arbeitsplatz;
import askanimus.arbeitszeiterfassung2.arbeitsschicht.Arbeitsschicht;
import askanimus.arbeitszeiterfassung2.arbeitstag.Arbeitstag;
import askanimus.arbeitszeiterfassung2.einsatzort.Einsatzort;
import askanimus.arbeitszeiterfassung2.R;
import askanimus.arbeitszeiterfassung2.setup.ASettings;
import askanimus.arbeitszeiterfassung2.setup.ISettings;

/**
 * @author askanimus@gmail.com on 10.01.16.
 */
public class Export_PDF_Einsatzort  extends AExport_Zeitraum_PDF{
    Export_PDF_Einsatzort(
            Context context,
            IZeitraum zeitraum,
            BitSet spalten,
            BitSet optionen,
            BitSet zusatzwerte,
            String notiz,
            StorageHelper storageHelper,
            ArrayList<MultiSelectItem> listeOrte
            //String pfad
    ) throws Exception {
        super(context, zeitraum, spalten, optionen, zusatzwerte, listeOrte);

        // den Dateiname zusammenstellen
        String dateiname;

        if(mOptionen.get(OPTION_NUR_ORTE)){
            dateiname = context.getString(
                    R.string.exp_dateiname_eort,
                    ASettings.mPreferenzen.getString(
                            ISettings.KEY_USERNAME, "")
                            .replaceAll(ASettings.REG_EX_PFAD, "_"),
                    context.getString(R.string.eort_liste)
                            .replaceAll(ASettings.REG_EX_PFAD, "_")
            );
            setupSeite(
                    TABTYP_EORT,
                    mOptionen,
                    //true,
                    context.getString(R.string.eort_liste),
                    null,
                    notiz,
                    ASettings.mPreferenzen.getInt(ISettings.KEY_EXP_EO_FONTSIZE, IExport_Basis.MIN_FONTSIZE)
                            + IExport_Basis.MIN_FONTSIZE

            );
        } else {
            if(mOptionen.get(OPTION_ALL_JOBS)){
                dateiname = mContext.getString(
                        R.string.exp_dateiname_zeitraum,
                        ASettings.mPreferenzen.getString(
                            ISettings.KEY_USERNAME, "")
                            .replaceAll(ASettings.REG_EX_PFAD, "_"),
                        context.getString(R.string.zeitraum),
                        mZeitraum.getTitel(mContext),
                        "_" + mContext.getString(R.string.einsatzorte)
                );
            } else {
                dateiname = mZeitraum.getDateiname(context, 0);
                dateiname += "_" + mContext.getString(R.string.einsatzorte);
            }
            setupSeite(
                    TABTYP_EORT,
                    mOptionen,
                    //false,
                    zeitraum.getTitel(context),
                    null,
                    notiz,
                    ASettings.mPreferenzen.getInt(ISettings.KEY_EXP_EO_FONTSIZE, IExport_Basis.MIN_FONTSIZE)
                            + IExport_Basis.MIN_FONTSIZE
            );
        }

        schreibeTabelle(storageHelper, dateiname, TYP_PDF);
    }

    @Override
    public ArrayList<TabellenArbeitsplatz> erzeugeTabellen() throws Exception {
        mTabellen = new ArrayList<>();
        TabellenArbeitsplatz mTabellenArbeitsplatz;

        // die Arbeitsplatzliste abarbeiten
        for (int i = 0; i < mArbeitsplatzListe.size(); i++) {
            mArbeitsplatz = mArbeitsplatzListe.get(i);
            mSpaltenSatz = makeSpaltenSet(mSpalten, mZusatzwerte, mArbeitsplatz);
            mListeOrteArbeitsplatzAuswahl = makeEinsatzortListeAuswahl(mArbeitsplatz, mListeOrteAuswahl);
            if (i > 0) {
                mZeitraum = mZeitraum.wechselArbeitsplatz(mArbeitsplatz);
            }
            isDezimal = mArbeitsplatz.isOptionSet(Arbeitsplatz.OPT_ANZEIGE_DEZIMAL);
            // neuen Tabellensatz für diesen Arbeitsplatz anlegen
            mTabellenArbeitsplatz = new TabellenArbeitsplatz();
            mTabellenArbeitsplatz.arbeitsplatz = mArbeitsplatz;

            if (mOptionen.get(OPTION_NUR_ORTE) ) {
                if(mArbeitsplatz.getEinsatzortListe().getMenge() > 0) {
                    // es soll nur eine Liste aller Einsatzorte ausgegeben werden
                    mTabellenArbeitsplatz.einzeltabelle = makeTabelle_EortListe(mArbeitsplatz);
                    mTabellen.add(mTabellenArbeitsplatz);
                }
            } else {
                // es werden für jeden Einsatzort die Schichten aufgelistet
                mTabellenArbeitsplatz.multitabelle = makeTabelle_EorteSchichtenListe(true);
                if (mTabellenArbeitsplatz.multitabelle.size() > 0) {
                    mTabellen.add(mTabellenArbeitsplatz);

                    // Zusammenfassung erzeugen wenn gewünscht
                    if (mOptionen.get(OPTION_ZUSAMMENFASSUNG)) {
                        List<List<Cell>> tabZusammenfassung = makeZusammenfassung();
                        if (tabZusammenfassung.size() > 0) {
                            Table t = makeTabelle(
                                    tabZusammenfassung,
                                    Table.DATA_HAS_0_HEADER_ROWS,
                                    false,
                                    mSpaltenSatz);
                            t.setNoCellBorders();
                            mTabellenArbeitsplatz.zusammenfassung = t;
                        }
                    }
                }
            }
        }
        return mTabellen;
    }
    
    // Tabelle mit Liste aller Einsatzorte erstellen
    private Table makeTabelle_EortListe(Arbeitsplatz job) throws Exception {
        Table mTabelle = new Table();
        List<List<Cell>> tableData = new ArrayList<>();
        List<Cell> row;
        
        // die aktiven Orte
        if(job.getEinsatzortListe().getAktive().size() > 0) {
           makeTitel(tableData, ASettings.res.getString(R.string.eort_sichtbar), 1);
           makeLeerzeile(tableData, 1, true);
           // alle aktiven Einsatzorte auflisten
            for (Einsatzort eor : job.getEinsatzortListe().getAktive()) {
                row = new ArrayList<>();
                row.add(makeZelleString(eor.getName(), false));
                tableData.add(row);
            }
           makeLeerzeile(tableData, 1, true);
        }
        
        // die passiven Orte
        if(job.getEinsatzortListe().getPassive().size() > 0) {
           makeTitel(tableData, ASettings.res.getString(R.string.eort_ausgeblendet), 1);
           makeLeerzeile(tableData, 1, true);
           // alle passiven Einsatzorte auflisten
            for (Einsatzort eor : job.getEinsatzortListe().getPassive()) {
                row = new ArrayList<>();
                row.add(makeZelleString(eor.getName(), false));
                tableData.add(row);
            }
        }


        // Tabelleneinstellungen
        mTabelle.setData(tableData, Table.DATA_HAS_1_HEADER_ROWS);
        if(tableData.size() > 0) {
            //mTabelle.setCellBordersWidth(0.2f);
            mTabelle.setNoCellBorders();
            mTabelle.rightAlignNumbers();
            mTabelle.autoAdjustColumnWidths();

            // Spaltenbreiten erweitern
            mTabelle.setColumnWidth(0, mTabelle.getColumnWidth(0) + 0.4f);
        }
        return mTabelle;
    }


    // die, neben der Haupttabelle angezeigte, Zusammenfassung
    @Override
    public  List<List<Cell>> makeZusammenfassung() {
        ArrayList<EortSchichten> eorteSchichten = new ArrayList<>();
        ArrayList<Schicht> schichten = new ArrayList<>();
        List<List<Cell>> tableData = new ArrayList<>();
        ArrayList<Cell> row;

        int tagSoll = mArbeitsplatz.getSollstundenTagPauschal(mZeitraum.getBeginn().getJahr(), mZeitraum.getBeginn().getMonat());
        int tage = 0;

        // Schichtnamen einsammeln
        for (Arbeitstag tag : mZeitraum.getTage()) {
            for (Arbeitsschicht schicht : tag.getSchichten()) {
                if (schicht.getNetto() > 0) {
                    boolean isNeu = true;
                    for (Schicht s : schichten) {
                        if (s.name.equals(schicht.getName())) {
                            isNeu = false;
                            break;
                        }
                    }
                    if (isNeu) {
                        schichten.add(new Schicht(schicht.getName()));
                    }
                }
            }
        }

        //Einsatzorte und deren Schichten einsammeln
        for (Einsatzort ort : mListeOrteArbeitsplatzAuswahl) {
            EortSchichten eos = new EortSchichten(ort);
            // die gefundenen Schichten des Zeitraums abfragen
            for (Schicht schicht : schichten) {
                int n = mZeitraum.getEortSchichtNetto(ort != null? ort.getId() : 0, schicht.getName());
                if(tagSoll == 0) {
                    tage = mZeitraum.getEortTage(ort != null? ort.getId() : 0, schicht.getName());
                }
                if (n != 0) {
                    eos.Schichten.add(new Schicht(schicht.getName(), n, tage));
                }
            }

            if (eos.Schichten.size() > 0) {
                eorteSchichten.add(eos);
            }
        }

        // Einsatzorte mit deren Schichten auflisten
        if (eorteSchichten.size() > 0) {
            // die einzelnen Einsatzorte
            for (EortSchichten eort : eorteSchichten) {
                if (eort.Schichten.size() > 0) {
                    makeTitel(
                            tableData,
                            eort.Eort != null ?
                                    eort.Eort.getName() :
                                    "<" + ASettings.res.getString(R.string.kein_einsatzort) + ">",
                            3);
                    for (Schicht schicht : eort.Schichten) {
                        row = new ArrayList<>();
                        row.add(makeZelleKopf(
                                (schicht.name.length() > 0) ?
                                        schicht.name :
                                        "<" + ASettings.res.getString(R.string.no_name) + ">"));
                        row.add(makeZelleStunden(
                                schicht.minuten,
                                isDezimal,
                                true,
                                false
                        ));
                        if(tagSoll > 0) {
                            row.add(makeZelleString(
                                    "(" + ASettings.tageformat.format((float) schicht.minuten / tagSoll) + ")",
                                    false
                            ));
                        } else {
                            row.add(makeZelleString(
                                    "(" + ASettings.tageformat.format((float) schicht.tage) + ")",
                                    false
                            ));
                        }
                        tableData.add(row);
                        makeLeerzeile(tableData, 3, true);
                    }
                }
            }
        }
        return tableData;
    }

    public static class Schicht{
        String name;
        int minuten;
        int tage;

        Schicht(String n){
            name = n;
            minuten = 0;
            tage = 0;
        }

        Schicht(String n, int m, int t){
            name = n;
            minuten = m;
            tage = t;
        }

        void addMinuten(int m){
            minuten += m;
        }

        String getName(){
            return name;
        }

        int getMinuten(){
            return minuten;
        }
    }

    private static class EortSchichten{
        Einsatzort Eort;
        ArrayList<Schicht> Schichten;

        EortSchichten(Einsatzort eort){
            Eort = eort;
            Schichten = new ArrayList<>();
        }
    }
}
