/* 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.zusatzeintrag;

import android.annotation.SuppressLint;
import android.database.Cursor;

import java.util.ArrayList;
import java.util.Comparator;

import askanimus.arbeitszeiterfassung2.Uhrzeit;
import askanimus.arbeitszeiterfassung2.arbeitsplatz.Arbeitsplatz;
import askanimus.arbeitszeiterfassung2.datenbank.DatenbankHelper;
import askanimus.arbeitszeiterfassung2.setup.ASettings;

public class ZusatzWertListe  implements Comparator<IZusatzfeld>{
    ArrayList<IZusatzfeld> mZusatzfelder;
    long mSchichtID;
    boolean mIsDefault;
    //int maxBreiteEinheit = 0;

    // erstellt die Zusatzwertliste einer Schicht
    @SuppressLint("Range")
    public ZusatzWertListe(long schichtID, ZusatzfeldDefinitionenListe defZusatzfelder, boolean isDefault) {
        // SQLiteDatabase mDatenbank = ASettings.stundenDBHelper.getReadableDatabase();
        mSchichtID = schichtID;
        mIsDefault = isDefault;

        final String SQL_READ_ZUSAETZE =
                "select * from "
                        + (isDefault ? DatenbankHelper.DB_T_ZUSATZWERT_DEFAULT : DatenbankHelper.DB_T_ZUSATZWERT)
                        + " where "
                        + (isDefault ? DatenbankHelper.DB_F_SCHICHT_DEFAULT : DatenbankHelper.DB_F_SCHICHT)
                        + " = ?";

        mZusatzfelder = new ArrayList<>();
        for (int i = 0; i < defZusatzfelder.size(); i++) {
            mZusatzfelder.add(null);
        }

        Cursor result = ASettings.mDatenbank.rawQuery(
                SQL_READ_ZUSAETZE,
                new String[]{Long.toString(schichtID)}
        );
        while (result.moveToNext()) {
            IZusatzfeld newFeld;
            ZusatzfeldDefinition def;
            def = defZusatzfelder.get(
                    result.getLong(result.getColumnIndex(DatenbankHelper.DB_F_ZUSATZFELD)));

            if (def != null && def.getPosition() < mZusatzfelder.size()) {
                newFeld = def.makeNewZusatzfeld(mSchichtID, result);
                mZusatzfelder.set(def.getPosition(), newFeld);
            }
        }
        result.close();
        // ASettings.mDatenbank.close();

        // nicht gespeicherte Felder als leere Felder erzeugen
        int i = 0;
        for (IZusatzfeld zf : mZusatzfelder) {
            if (zf == null) {
                ZusatzfeldDefinition def = defZusatzfelder.get(i);
                mZusatzfelder.set(i, def.makeNewZusatzfeld(mSchichtID));
            }
            i++;
        }
        //sort();
    }

    // erstellt eine Zusatzfeldliste  mit leeren Werten
    public ZusatzWertListe(ZusatzfeldDefinitionenListe defZusatzfelder, boolean mitTextfelder) {
        mSchichtID = -1;
        mIsDefault = false;
        mZusatzfelder = new ArrayList<>();

        // alle definierten Zusatzfelder mit leeeren Werten anlegen
        for (ZusatzfeldDefinition def : defZusatzfelder.mDefinitionen) {
            if((def.getTyp() != IZusatzfeld.TYP_TEXT && def.getTyp() != IZusatzfeld.TYP_AUSWAHL_TEXT)
                    || mitTextfelder)
            {
                mZusatzfelder.add(def.makeNewZusatzfeld(mSchichtID));
            }
        }
    }

    // erstellt eine Zusatzfeldliste  mit übergebenen Elementen
    public ZusatzWertListe(ArrayList<IZusatzfeld> elemente){
        mSchichtID = -1;
        mIsDefault = false;
        mZusatzfelder = elemente;
    }

    // kopiert die Zusatzwertliste
    public ZusatzWertListe copy(Arbeitsplatz job){
        ZusatzWertListe ziel = new ZusatzWertListe(job.getZusatzfeldListe(), true);

        int i = 0;
        for (IZusatzfeld ze : mZusatzfelder) {
            ziel.get(i).set(ze);
            i ++;
        }

        return ziel;
    }

    /*public void sort(){
        Collections.sort(mZusatzfelder, this);
    }*/

    public void speichern() {
        for (IZusatzfeld zf : mZusatzfelder) {
            zf.save(mIsDefault);
        }
    }

    public void setSchichtId(long schichtId){
        for (IZusatzfeld zf : mZusatzfelder) {
            zf.setSchichtId(schichtId);
        }
    }

    public boolean add(IZusatzfeld feld){
        return mZusatzfelder.add(feld);
    }

    // addiert die Werte der Zusatzwertliste mit denen der übergebenen Zusatzwertliste
    public void addListenWerte(ZusatzWertListe liste/*, boolean inclText*/){
        int i = 0;

        for (IZusatzfeld zQuelle : liste.mZusatzfelder) {
            //if(inclText || zQuelle.getDatenTyp() != IZusatzfeld.TYP_TEXT) {
                this.mZusatzfelder.get(i).add(zQuelle);
                i ++;
            //}
        }
    }

    // schreibt die Werte der übergebenen Liste in die Zusatwerte
    public void setListenWerte(ZusatzWertListe liste){
        int i = 0;
        for (IZusatzfeld ze : mZusatzfelder) {
            ze.set(liste.get(i));
            i ++;
        }
    }

    public void setListenWerte(ArrayList<IZusatzfeld> liste){
        int i = 0;
        for (IZusatzfeld ze : mZusatzfelder) {
            ze.set(liste.get(i));
            i ++;
        }
    }


    public int size(){
       return mZusatzfelder.size();
    }

    public IZusatzfeld get(int index){
        if(index < mZusatzfelder.size())
            return mZusatzfelder.get(index);
        else
            return null;
    }

    public IZusatzfeld get(long id){
        for (IZusatzfeld ze: mZusatzfelder) {
            if(ze.getId() == id)
                return ze;
        }
        return null;
    }

    // gibt den Wert zurück, um den die Istunden angepasst werden (+ oder -)
    public int getSummeKorrekturIstZeit(int netto){
        Uhrzeit korrekturZeit = new Uhrzeit(0);
        try {
            for (IZusatzfeld ze : mZusatzfelder) {
                /*if (ze.getDatenTyp() == IZusatzfeld.TYP_ZEIT
                        || ze.getDatenTyp() == IZusatzfeld.TYP_BEREICH_ZEIT
                        || ze.getDatenTyp() == IZusatzfeld.TYP_AUSWAHL_ZEIT
                ) {*/
                    if (ze.getWirkung() == IZusatzfeld.ADD_ISTSTUNDEN) {
                        if( ze.getDatenTyp() == IZusatzfeld.TYP_PROZENT
                                || ze.getDatenTyp() == IZusatzfeld.TYP_AUSWAHL_PROZENT ){
                            float wert = (float)ze.getWert() * netto;
                            korrekturZeit.add(Math.round(wert));
                        } else {
                            korrekturZeit.add((int) ze.getWert());
                        }
                    } else if (ze.getWirkung() == IZusatzfeld.SUB_ISTSTUNDEN) {
                        if( ze.getDatenTyp() == IZusatzfeld.TYP_PROZENT
                                || ze.getDatenTyp() == IZusatzfeld.TYP_AUSWAHL_PROZENT ){
                            float wert = (float)ze.getWert() * netto;
                            korrekturZeit.sub(Math.round(wert));
                        } else {
                            korrekturZeit.sub((int) ze.getWert());
                        }
                    }
               // }
            }
        }  catch (ClassCastException ce){
            ce.printStackTrace();
        }
        return korrekturZeit.getAlsMinuten();
    }

    // gibt den Wert zurück, um den die Sollstunden verringert werden
    public int getSummeMinusSollZeit(int tagsoll){
        Uhrzeit korrekturZeit = new Uhrzeit(0);
        try {
            for (IZusatzfeld ze : mZusatzfelder) {
                /*if (ze.getDatenTyp() == IZusatzfeld.TYP_ZEIT
                        || ze.getDatenTyp() == IZusatzfeld.TYP_BEREICH_ZEIT
                        || ze.getDatenTyp() == IZusatzfeld.TYP_AUSWAHL_ZEIT
                ) {*/
                    if (ze.getWirkung() == IZusatzfeld.SUB_SOLLSTUNDEN) {
                        if( ze.getDatenTyp() == IZusatzfeld.TYP_PROZENT
                                || ze.getDatenTyp() == IZusatzfeld.TYP_AUSWAHL_PROZENT ){
                            float wert = (float)ze.getWert() * tagsoll;
                            korrekturZeit.add(Math.round(wert));
                        } else {
                            korrekturZeit.add((int) ze.getWert());
                        }
                    }
                //}
            }
        } catch (ClassCastException ce){
            ce.printStackTrace();
        }
        return korrekturZeit.getAlsMinuten();
    }

    // gibt den Wert zurück, um den der Verdienst angepasst wird (+ oder -)
    public float getSummeKorrekturVerdienst(float verdienstMinuten, float stundenLohn){
        float korrektur = 0;
        try {
            for (IZusatzfeld ze : mZusatzfelder) {
                /*if (ze.getDatenTyp() == IZusatzfeld.TYP_ZAHL
                        || ze.getDatenTyp() == IZusatzfeld.TYP_BEREICH_ZAHL
                        || ze.getDatenTyp() == IZusatzfeld.TYP_AUSWAHL_ZAHL)
                {*/
                    if (ze.getWirkung() == IZusatzfeld.ADD_VERDIENST) {
                        if( ze.getDatenTyp() == IZusatzfeld.TYP_PROZENT
                                || ze.getDatenTyp() == IZusatzfeld.TYP_AUSWAHL_PROZENT ){
                            float wert = (float)ze.getWert() * ((verdienstMinuten/60) * stundenLohn);
                            korrektur += wert;
                        } else {
                            korrektur += (float) ze.getWert();
                        }
                    } else if (ze.getWirkung() == IZusatzfeld.SUB_VERDIENST) {
                        if( ze.getDatenTyp() == IZusatzfeld.TYP_PROZENT
                                || ze.getDatenTyp() == IZusatzfeld.TYP_AUSWAHL_PROZENT ){
                            float wert = (float)ze.getWert() * ((verdienstMinuten/60) * stundenLohn);
                            korrektur -= wert;
                        } else {
                            korrektur -= (float) ze.getWert();
                        }
                    }
               // }
            }
        } catch (ClassCastException ce){
            ce.printStackTrace();
        }

        return korrektur;
    }

    public ArrayList<IZusatzfeld> getListe(){
        return mZusatzfelder;
    }

    /*public int getMaxBreiteEinheit(){
        return maxBreiteEinheit;
    }*/

    @Override
    public int compare(IZusatzfeld t1, IZusatzfeld t2) {
        return t1.getPosition() - t2.getPosition();
    }
}
