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

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

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.ConcurrentModificationException;
import java.util.Date;

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

/**
 * @author askanimus@gmail.com on 02.12.15.
 */
public class EinsatzortListe {
    private static final String SQL_READ_EORT =
            "select * from " + DatenbankHelper.DB_T_EORT +
                " where " + DatenbankHelper.DB_F_JOB +
                " = ?";

    private final long jobID;
    private final ArrayList<Einsatzort> mEinsatzorte;
    private int sortBy = -1;


    @SuppressLint("Range")
    public EinsatzortListe(long job) {
        // SQLiteDatabase mDatenbank = ASettings.stundenDBHelper.getReadableDatabase();
        mEinsatzorte = new ArrayList<>();
        jobID = job;

        Cursor result = ASettings.mDatenbank.rawQuery(
                SQL_READ_EORT, new String[]{Long.toString(jobID)}
        );
        while (result.moveToNext()) {
            mEinsatzorte.add(
                    new Einsatzort(result.getLong(result.getColumnIndex(DatenbankHelper.DB_F_ID)),
                            jobID,
                            result.getString(result.getColumnIndex(DatenbankHelper.DB_F_NAME)),
                            result.getInt(result.getColumnIndex(DatenbankHelper.DB_F_STATUS)),
                            result.getInt(result.getColumnIndex(DatenbankHelper.DB_F_ANZAHL_VERWENDET)),
                            result.getLong(result.getColumnIndex(DatenbankHelper.DB_F_ZULETZT_VERWENDET))
                    ));
        }

        sort(ASettings.mPreferenzen.getInt(
                ISettings.KEY_SORT_EORTLISTE,
                ISettings.SORT_NO)
        );
        result.close();
        // ASettings.mDatenbank.close();
    }

    void sort(int sort_by) {
        if (sortBy != sort_by) {
            sortBy = sort_by;
            switch (sortBy) {
                case ISettings.SORT_AZ:
                    sortNachName(false);
                    break;
                case ISettings.SORT_ZA:
                    sortNachName(true);
                    break;
                default:
                    sortNachBenutzung();
            }
        }
    }

    private void sortNachName(boolean rev) {
        Comparator<Einsatzort> comp = rev ? new NameComparator_ZA() : new NameComparator_AZ();
        try {
            Collections.sort(mEinsatzorte, comp);
        } catch (ConcurrentModificationException ce) {
            ce.printStackTrace();
        }

    }

    public void sortNachBenutzung() {
        Comparator<Einsatzort> comp = new BenutzungComparator();
        try {
            Collections.sort(mEinsatzorte, comp);
        } catch (ConcurrentModificationException ce){
            ce.printStackTrace();
        }

    }

    public void save() {
        for (Einsatzort eort : mEinsatzorte) {
            eort.save();
        }
    }


    public Einsatzort add(String name) {
        Einsatzort mOrt = new Einsatzort(
                -1,
                jobID,
                name,
                ISettings.STATUS_AKTIV,
                0,
                new Date().getTime());
        mEinsatzorte.add(0, mOrt);

        return mOrt;
    }

    public int getMenge(int status) {
        int m = 0;
        for (Einsatzort o:mEinsatzorte) {
            if(o.getStatus() == status)
                m++;
        }
        return m;
    }

    public int getMenge() {
        return mEinsatzorte.size();
    }

    /*public Einsatzort getOrt(int index) {
        if(index < mEinsatzorte.size())
            return mEinsatzorte.get(index);
        return null;
    }*/

    public Einsatzort getOrt(long id) {
        if(mEinsatzorte != null) {
            for (Einsatzort o : mEinsatzorte) {
                if (o.getId() == id)
                    return o;
            }
        }
        return null;
    }

    protected long getID(int index) {
        if(index < mEinsatzorte.size())
            return mEinsatzorte.get(index).getId();
        return -1;
    }

    /*private int getIndex(long id) {
        int i = 0;
        for (Einsatzort o:mEinsatzorte) {
            if(o.getId() == id)
                return i;
            i++;
        }
        return -1;
    }*/

    public ArrayList<Einsatzort> getAktive() {
        ArrayList<Einsatzort>mAktive = new ArrayList<>();

        for (Einsatzort o:mEinsatzorte) {
            if(o.getStatus() == ISettings.STATUS_AKTIV)
                mAktive.add(o);
        }
        return mAktive;
    }

    public ArrayList<Einsatzort> getPassive() {
        ArrayList<Einsatzort>mPassive = new ArrayList<>();

        for (Einsatzort o:mEinsatzorte) {
            if(o.getStatus() == ISettings.STATUS_INAKTIV)
                mPassive.add(o);
        }
        return mPassive;
    }

    public ArrayList<Einsatzort> getAlle() {
        return mEinsatzorte;
    }

    public void ListeKlone(long jobID_neu) {
        for (Einsatzort o:mEinsatzorte) {
            o.Klone(jobID_neu);
        }
    }

    /*
     * Sortierer für die Liste
     */
    private static class NameComparator_AZ implements Comparator<Einsatzort> {

        @Override
        public int compare(Einsatzort o1, Einsatzort o2) {

            return o1.getName().toLowerCase().compareTo(o2.getName().toLowerCase());
        }
    }
    private static class NameComparator_ZA implements Comparator<Einsatzort> {

        @Override
        public int compare(Einsatzort o1, Einsatzort o2) {
            return o2.getName().toLowerCase().compareTo(o1.getName().toLowerCase());
        }
    }

    private static class BenutzungComparator implements Comparator<Einsatzort> {

        @Override
        public int compare(Einsatzort o1, Einsatzort o2) {
            if (o1.getzuletzt_Verwendet() < o2.getzuletzt_Verwendet()) {
                return 1;
            } else if (o1.getzuletzt_Verwendet() > o2.getzuletzt_Verwendet()) {
                return -1;
            } else {
                if (o1.getVerwendung() < o2.getVerwendung()) {
                    return 1;
                } else if (o1.getVerwendung() > o2.getVerwendung()) {
                    return -1;
                } else {
                    return o1.getName().toLowerCase().compareTo(o2.getName().toLowerCase());
                }
            }
        }
    }
}
