/* 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.content.ContentValues;
import android.database.Cursor;

import java.text.DecimalFormat;
import java.util.ArrayList;

import askanimus.arbeitszeiterfassung2.datenbank.DatenbankHelper;
import askanimus.arbeitszeiterfassung2.setup.ASettings;

public class ZusatzfeldDefinition {
    boolean isNoSave = false;

    private long mID = -1;
    private long mArbeitsplatzID;
    private String mName;
    private int mTyp;
    private String mEinheit;
    private final boolean isDezimal;
    private final DecimalFormat mFormater;
    private int mWirkung;
    private int mPosition;
    private int mSpalten;
    private ArrayList<Object> mAuswahl;

    @SuppressLint("Range")
    public ZusatzfeldDefinition(Cursor daten, boolean isdezimal){
        mID = daten.getLong(daten.getColumnIndex(DatenbankHelper.DB_F_ID));
        mArbeitsplatzID = daten.getLong(daten.getColumnIndex(DatenbankHelper.DB_F_JOB));
        mName = daten.getString(daten.getColumnIndex(DatenbankHelper.DB_F_NAME));
        mTyp = daten.getInt(daten.getColumnIndex(DatenbankHelper.DB_F_DATENTYP));
        mEinheit = daten.getString(daten.getColumnIndex(DatenbankHelper.DB_F_EINHEIT));
        mWirkung = daten.getInt(daten.getColumnIndex(DatenbankHelper.DB_F_WIRKUNG));
        mPosition = daten.getInt(daten.getColumnIndex(DatenbankHelper.DB_F_POSITION));
        mSpalten = Math.max(1, daten.getInt(daten.getColumnIndex(DatenbankHelper.DB_F_SPALTEN)));

        mFormater = new DecimalFormat("###,##0.00 '" + mEinheit + "'");
        isDezimal = isdezimal;
    }

    public ZusatzfeldDefinition(
            long jobID,
            String name,
            int typ,
            String einheit,
            int wirkung,
            int position,
            int spalten,
            boolean isdezimal
    ){
        mArbeitsplatzID = jobID;
        mName = name;
        mTyp = typ;
        mEinheit = einheit;
        mFormater = new DecimalFormat("###,##0.00 '" + einheit + "'");
        mWirkung = wirkung;
        mPosition = position;
        mSpalten = Math.max(1, spalten);
        isNoSave = true;
        isDezimal = isdezimal;
    }

    public void setName(String name){
        if(!mName.equals(name)){
            mName = name;
            isNoSave = true;
        }
    }

    public void setEinheit(String einheit){
        if(!mEinheit.equals(einheit)){
            mEinheit = einheit;
            isNoSave = true;
        }
    }

    public void setTyp(int typ){
        if(mTyp != typ) {
            mTyp = typ;
            isNoSave = true;
        }
    }

    public void setWirkung(int wirkung){
        if(mWirkung != wirkung) {
            mWirkung = wirkung;
            isNoSave = true;
        }
    }

    public void setColums(int colums){
        if(mSpalten != colums) {
            mSpalten = colums;
            isNoSave = true;
        }
    }

    public void setPosition( int position){
        if(mPosition != position){
            mPosition = position;
            isNoSave = true;
        }
    }

    public long getID(){
        return mID;
    }
    
    public int getPosition(){
        return mPosition;
    }

    public int getColums(){
        return mSpalten;
    }

    public String getName() {
        return mName;
    }

    public int getTyp(){
        return mTyp;
    }

    public String getEinheit(){
        return mEinheit;
    }

    public DecimalFormat getFormater(){
        return mFormater;
    }

    public int getWirkung(){
        return mWirkung;
    }

    public boolean isDezimal(){
        return isDezimal;
    }

    public void speichern(){
        if(isNoSave) {
            // SQLiteDatabase mDatenbank = ASettings.stundenDBHelper.getWritableDatabase();
            isNoSave = false;
            ContentValues werte = new ContentValues();
            werte.put(DatenbankHelper.DB_F_JOB, mArbeitsplatzID);
            werte.put(DatenbankHelper.DB_F_NAME, mName);
            werte.put(DatenbankHelper.DB_F_DATENTYP, mTyp);
            werte.put(DatenbankHelper.DB_F_EINHEIT, mEinheit);
            werte.put(DatenbankHelper.DB_F_WIRKUNG, mWirkung);
            werte.put(DatenbankHelper.DB_F_POSITION, mPosition);
            werte.put(DatenbankHelper.DB_F_SPALTEN, mSpalten);

            if (mID < 0)
                mID = ASettings.mDatenbank.insert(
                        DatenbankHelper.DB_T_ZUSATZFELD,
                        null,
                        werte);
            else {
                ASettings.mDatenbank.update(
                        DatenbankHelper.DB_T_ZUSATZFELD, werte,
                        DatenbankHelper.DB_F_ID + "=?",
                        new String[]{Long.toString(mID)});
            }
            // ASettings.mDatenbank.close();
        }
    }

    void delete(){
        // SQLiteDatabase mDatenbank = ASettings.stundenDBHelper.getWritableDatabase();
        // alle Defaultwerte löschen
        ASettings.mDatenbank.delete(
                DatenbankHelper.DB_T_ZUSATZWERT_DEFAULT,
                DatenbankHelper.DB_F_ZUSATZFELD + "=?",
                new String[]{String.valueOf(mID)});

        // alls Werte löschen
        ASettings.mDatenbank.delete(
                DatenbankHelper.DB_T_ZUSATZWERT,
                DatenbankHelper.DB_F_ZUSATZFELD + "=?",
                new String[]{String.valueOf(mID)});

        // alle Wertauswahlen löschen
        ASettings.mDatenbank.delete(
                DatenbankHelper.DB_T_ZUSATZWERT_AUSWAHL,
                DatenbankHelper.DB_F_ZUSATZFELD + "=?",
                new String[]{String.valueOf(mID)});

        // den Zusatzwert der in eine laufende Stempeluhr eingetragen wurde löschen
        ASettings.mDatenbank.delete(
                DatenbankHelper.DB_T_STEMPELUHR_ZUSATZWERT,
                DatenbankHelper.DB_F_ZUSATZFELD + "=?",
                new String[]{String.valueOf(mID)});

        // das Zusatzfeld löschen
        ASettings.mDatenbank.delete(
                DatenbankHelper.DB_T_ZUSATZFELD,
                DatenbankHelper.DB_F_ID + "=?",
                new String[]{String.valueOf(mID)});

        // mDatenbank.close();
    }

    void Klone(long ArbeitsplatzID){
        this.mArbeitsplatzID = ArbeitsplatzID;
        mID = -1;
        isNoSave = true;
        speichern();
    }

    /**
     * Anlegen eines leeren neuen Zusatzfeldes ohne Bezug zu einer Schicht
     *
     * @return leeres Zusatzfeld des Datentyps der Definition
     */
    public IZusatzfeld makeNewZusatzfeld() {
        return makeNewZusatzfeld(-1);
    }

    /**
     * Anlegen eines neuen Zusatzfeldes ohne ID und ohne Bezug zu einer Schicht
     * @param wert aus der Datenbank gelesener Wert (Text, Zahl, Zeit oder Bereich)
     * @return Zusatzfeld des Datentyps der Definition
     */
    public IZusatzfeld makeNewZusatzfeld(Cursor wert) {
        return makeNewZusatzfeld(-1, wert);
    }

    /**
     * Anlegen eines leeren neuen Zusatzfeldes mit Bezug zu einer Schicht
     * @param schichtID Id der zugehörigen Schicht
     * @return leeres Zusatzfeld des Datentyps der Definition
     */
    public IZusatzfeld makeNewZusatzfeld(long schichtID) {
        IZusatzfeld feld;
        switch (mTyp) {
            case IZusatzfeld.TYP_PROZENT:
            case IZusatzfeld.TYP_AUSWAHL_PROZENT:
                feld = new Prozentfeld(-1, schichtID,this, 0f);
                break;
            case IZusatzfeld.TYP_ZAHL:
            case IZusatzfeld.TYP_AUSWAHL_ZAHL:
                feld = new Zahlenfeld(-1, schichtID,this, 0f);
                break;
            case IZusatzfeld.TYP_ZEIT:
            case IZusatzfeld.TYP_AUSWAHL_ZEIT:
                feld = new Zeitfeld(-1, schichtID, this, 0, false);
                break;
            case IZusatzfeld.TYP_BEREICH_ZAHL:
                feld = new Bereichsfeld(-1, schichtID,this, 0f, 0f);
                break;
            case IZusatzfeld.TYP_BEREICH_ZEIT:
                feld = new Bereichsfeld(-1, schichtID, this, 0, 0);
                break;
            default:
                // als Text interpretieren
                feld = new Textfeld(-1, schichtID,this, "");
        }
        return feld;
    }

    /**
     * Anlegen eines, aus der Datenbank gelesenen Zusatzfeldes mit Bezug zu einer Schicht
     * @param schichtID Id der zugehörigen Schicht
     * @param result aus der Datenbank gelesene Daten des Feldes
     * @return Zusatzfeld des Datentyps der Definition
     */
    @SuppressLint("Range")
    public IZusatzfeld makeNewZusatzfeld(long schichtID, Cursor result) {
        IZusatzfeld feld;
        long id;
        if(schichtID < 0){
            id = -1;
        } else {
            id = result.getLong(result.getColumnIndex(DatenbankHelper.DB_F_ID));
        }

        switch (mTyp) {
            case IZusatzfeld.TYP_PROZENT:
            case IZusatzfeld.TYP_AUSWAHL_PROZENT:
                float prozent = result.getFloat(result.getColumnIndex(DatenbankHelper.DB_F_WERT));
                feld = new Prozentfeld(id, schichtID,this, prozent);
                break;
            case IZusatzfeld.TYP_ZAHL:
            case IZusatzfeld.TYP_AUSWAHL_ZAHL:
                float zahl = result.getFloat(result.getColumnIndex(DatenbankHelper.DB_F_WERT));
                feld = new Zahlenfeld(id, schichtID,this, zahl);
                break;
            case IZusatzfeld.TYP_ZEIT:
            case IZusatzfeld.TYP_AUSWAHL_ZEIT:
                int minuten = result.getInt(result.getColumnIndex(DatenbankHelper.DB_F_WERT));
                feld = new Zeitfeld(id, schichtID, this, minuten, false);
                break;
            case IZusatzfeld.TYP_BEREICH_ZAHL:
                String[] bZahl;
                bZahl = result
                        .getString(result.getColumnIndex(DatenbankHelper.DB_F_WERT))
                        .split(Bereichsfeld.BEREICH_TRENNER, 2);
                float fBeginn = bZahl[0].isEmpty() ? 0f : Float.parseFloat(bZahl[0]);
                float fEnde = bZahl[1].isEmpty() ? 0f : Float.parseFloat(bZahl[1]);
                feld = new Bereichsfeld(id, schichtID,this, fBeginn, fEnde);
                break;
            case IZusatzfeld.TYP_BEREICH_ZEIT:
                String[] bZeit;
                bZeit = result
                        .getString(result.getColumnIndex(DatenbankHelper.DB_F_WERT))
                        .split(Bereichsfeld.BEREICH_TRENNER, 2);
                int iBeginn = bZeit[0].isEmpty() ? 0 : Integer.parseInt(bZeit[0]);
                int iEnde = bZeit[1].isEmpty() ? 0 : Integer.parseInt(bZeit[1]);
                feld = new Bereichsfeld(id, schichtID, this, iBeginn, iEnde);
                break;
            default:
                // als Text interpretieren
                String text = result.getString(result.getColumnIndex(DatenbankHelper.DB_F_WERT));
                if (text == null) {
                    text = "";
                }
                feld = new Textfeld(id, schichtID,this, text);
        }
        return feld;
    }
}
