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

import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.Filter;
import android.widget.TextView;

import androidx.activity.OnBackPressedCallback;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.SearchView;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.res.ResourcesCompat;

import java.util.ArrayList;
import java.util.Arrays;

import askanimus.arbeitszeiterfassung2.Datum;
import askanimus.arbeitszeiterfassung2.MainActivity;
import askanimus.arbeitszeiterfassung2.R;
import askanimus.arbeitszeiterfassung2.Uhrzeit;
import askanimus.arbeitszeiterfassung2.abwesenheiten.Abwesenheit;
import askanimus.arbeitszeiterfassung2.arbeitsplatz.Arbeitsplatz;
import askanimus.arbeitszeiterfassung2.datenbank.DatenbankHelper;
import askanimus.arbeitszeiterfassung2.setup.ASettings;
import askanimus.arbeitszeiterfassung2.setup.ISettings;
import askanimus.arbeitszeiterfassung2.setup.LocaleHelper;

public class Suche_Activity extends AppCompatActivity implements ExpandableListView.OnChildClickListener {
    // gewünschte Spalten für die Einsatzortabfrage
    private final String[] eortSpalten = new String[]{
            DatenbankHelper.DB_F_ID,
            DatenbankHelper.DB_F_NAME,
            DatenbankHelper.DB_F_ANZAHL_VERWENDET
    };

    // gewünschte Spalten für die Einsatzortabfrage
    private final String[] defSchichtSpalten = new String[]{
            DatenbankHelper.DB_F_ID,
            DatenbankHelper.DB_F_NAME
    };

    // gewünschte Spalten für die Schichtabfrage
    private final String[] schichtSpalten = new String[]{
            DatenbankHelper.DB_F_ID,
            DatenbankHelper.DB_F_SCHICHT_DEFAULT,
            DatenbankHelper.DB_F_NAME,
            DatenbankHelper.DB_F_TAG,
            DatenbankHelper.DB_F_VON,
            DatenbankHelper.DB_F_BIS,
            DatenbankHelper.DB_F_PAUSE,
            DatenbankHelper.DB_F_EORT,
            DatenbankHelper.DB_F_ABWESENHEIT
    };

    // Spalten für die Abfage eines Tages
    private final String[] allSpalten = new String[]{"*"};

    private Context mContext;

    private ErgebnisListadapter myAdapter;

    private String mSuchstring;
    private SearchView mSuche;
    private Toolbar mToolbar;

    //private TextView vSuchstring;
    private ExpandableListView lErgebnis;

    private ArrayList<ArrayList<Ergebnis>> mErgebnisse;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mContext = this;
        setTheme(ASettings.isThemaDunkel ? R.style.MyFullscreenTheme : R.style.MyFullscreenTheme_Light);
        setContentView(R.layout.activity_suche);

        getOnBackPressedDispatcher().addCallback(this, new OnBackPressedCallback(true) {
            @Override
            public void handleOnBackPressed() {
                BackPressed();
            }
        });
    }


    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(LocaleHelper.onAttach(base));
    }

    private void BackPressed() {
        Intent iMain = new Intent();
        iMain.setClass(getApplicationContext(), MainActivity.class);
        startActivity(iMain);
        finish();
    }

    @Override
    protected void onResume() {
        super.onResume();
        ASettings.init(mContext, () -> {
            lErgebnis = findViewById(R.id.SU_ergebnis);
            mSuche = findViewById(R.id.SU_filter);
            mToolbar = findViewById(R.id.su_toolbar);
            resume();
        });
    }

    private void resume() {
        if (mToolbar != null) {
            mToolbar.setTitle(ASettings.res.getString(R.string.suche));
            setSupportActionBar(mToolbar);
            mToolbar.setBackgroundColor(ASettings.aktJob.getFarbe());
            mToolbar.setTitleTextColor(ASettings.aktJob.getFarbe_Schrift_Titel());

            Intent mIntent = getIntent();
            mSuchstring = mIntent.getStringExtra(ISettings.KEY_SUCHE_STRING);

            sucheTask();

            mErgebnisse = new ArrayList<>();
            mErgebnisse.add(new ArrayList<>()); // Ergebnisse für die Suche in den Zusatzeingaben
            mErgebnisse.add(new ArrayList<>()); // Ergbenisse für die Suche in Einsatzorten
            mErgebnisse.add(new ArrayList<>()); // Ergebnisse für die Suche in den Schichtnamen
            myAdapter = new ErgebnisListadapter();
            lErgebnis.setAdapter(myAdapter);
            lErgebnis.setOnChildClickListener(this);

            // handler für das öffnen der Kindelemente, nur eins soll zur gleichen Zeit offen sein
            lErgebnis.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
                int previousGroup = -1;

                @Override
                public void onGroupExpand(int groupPosition) {
                    if (groupPosition != previousGroup)
                        lErgebnis.collapseGroup(previousGroup);
                    previousGroup = groupPosition;
                }
            });


            mSuche.setQueryHint(getString(R.string.su_filter_hint));
            mSuche.setIconified(false);
            mSuche.clearFocus();
            mSuche.clearFocus();
            mSuche.setOnQueryTextListener(new androidx.appcompat.widget.SearchView.OnQueryTextListener() {
                @Override
                public boolean onQueryTextSubmit(String query) {
                    return false;
                }

                @Override
                public boolean onQueryTextChange(String newText) {
                    myAdapter.getFilter().filter(newText);

                    return false;
                }

            });
            myAdapter.mFilterData = null;
        }
    }

    private void UpdateView() {
        myAdapter.notifyDataSetChanged();
        //vSuchstring.setText(getString(R.string.su_nach,
        //      mSuchstring, mErgebnisse[0].size() + mErgebnisse[1].size()));
    }

    // Ein Listenelement wurde angeklickt
    @Override
    public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
        Ergebnis mErgebnis = (Ergebnis) myAdapter.getChild(groupPosition, childPosition);

        //Activity mActivity = this;
        //if(mActivity != null) {
        Intent iMain = new Intent();
        iMain.putExtra(ISettings.KEY_ANZEIGE_VIEW, ISettings.VIEW_TAG);
        iMain.putExtra(ISettings.KEY_ANZEIGE_DATUM, mErgebnis.datum.getTimeInMillis());
        iMain.putExtra(ISettings.KEY_JOBID, mErgebnis.job.getId());
        iMain.setClass(this, MainActivity.class);
        startActivity(iMain);
        finish();
        //}
        return true;
    }

    private void sucheTask() {
        final ProgressDialog mDialog = new ProgressDialog(mContext);

        // Fortschritsdialog öffnen
        mDialog.setIndeterminate(true);
        mDialog.setIndeterminateDrawable(
                ResourcesCompat.getDrawable(
                        getResources(),
                        R.drawable.progress_dialog_anim,
                        getTheme()));
        mDialog.setMessage(getString(R.string.suche));
        mDialog.setCancelable(false);
        mDialog.show();

        Handler mHandler = new Handler();
        new Thread(() -> {
            mSuchstring = mSuchstring.toLowerCase();
            String[] s = mSuchstring.split("[\\s\\xA0]+");

            // Suchbegriffe
            ArrayList<String> filterArgumente = new ArrayList<>();
            for (String b : s) {
                if (!b.isEmpty()) {
                    filterArgumente.add("%" + b + "%");
                }
            }

            try {
                Object[] fa = filterArgumente.toArray();
                mErgebnisse.get(0).addAll(sucheInZusatzeintraege(fa));
                mErgebnisse.get(1).addAll(sucheInEinsatzorte(fa));
                mErgebnisse.get(2).addAll(sucheInSchichtnamen(fa));
            } catch (NullPointerException ne) {
                // Ergebnissarray leeren
                mErgebnisse = new ArrayList<>();
                mErgebnisse.add(new ArrayList<>());
                mErgebnisse.add(new ArrayList<>());
                mErgebnisse.add(new ArrayList<>());
            }

            mHandler.post(() -> {
                // Fortschrittsdialog schliessen
                mDialog.dismiss();
                UpdateView();
            });
        }).start();
    }


    // Suche in Zusatzeinträgen
    @SuppressLint("Range")
    private ArrayList<Ergebnis> sucheInZusatzeintraege(Object[] begriffe) {
        ArrayList<Ergebnis> ergebnisListe = new ArrayList<>();
        // SQLiteDatabase mDatenbank = ASettings.stundenDBHelper.getReadableDatabase();

        //den Filterstring bauen
        StringBuilder filter = new StringBuilder();
        for (int i = 0; i < begriffe.length; i++) {
            if (i > 0) {
                filter.append(" OR ");
            }
            filter.append("wert LIKE ?");
        }

        // alle relevanten Zusatzeinträge lesen
        Cursor resultZusatz = ASettings.mDatenbank.query(
                true,
                DatenbankHelper.DB_T_ZUSATZWERT,
                allSpalten,
                filter.toString(),
                Arrays.copyOf(begriffe, begriffe.length, String[].class),
                null, null, null, null
        );

        while (resultZusatz.moveToNext()) {
            // alle Schichten lesen, in denen der Einsatzort zugeordnet ist
            Cursor resultSchichten = ASettings.mDatenbank.query(
                    true,
                    DatenbankHelper.DB_T_SCHICHT,
                    schichtSpalten,
                    DatenbankHelper.DB_F_ID + " = ?",
                    new String[]{String.valueOf(resultZusatz.getLong(resultZusatz.getColumnIndex(DatenbankHelper.DB_F_SCHICHT)))},
                    null, null, DatenbankHelper.DB_F_TAG, null
            );

            while (resultSchichten.moveToNext()) {
                Ergebnis ergebnis = new Ergebnis();
                ergebnis.schichtID = resultSchichten.getLong(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_ID));
                ergebnis.tagID = resultSchichten.getLong(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_TAG));
                ergebnis.von = resultSchichten.getInt(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_VON));
                ergebnis.bis = resultSchichten.getInt(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_BIS));
                ergebnis.pause = resultSchichten.getInt(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_PAUSE));
                ergebnis.zusatzwert = resultZusatz.getString(resultZusatz.getColumnIndex(DatenbankHelper.DB_F_WERT));
                ergebnis.nameOrtOderSchicht = "";
                // Datum des Tages ermitteln
                Cursor resultTag = ASettings.mDatenbank.query(
                        true,
                        DatenbankHelper.DB_T_TAG,
                        allSpalten,
                        DatenbankHelper.DB_F_ID + " = ?",
                        new String[]{String.valueOf(ergebnis.tagID)},
                        null, null, null, "1"
                );
                if (resultTag.getCount() > 0) {
                    resultTag.moveToFirst();
                    ergebnis.job = ASettings.jobListe.getVonID(resultTag.getLong(
                            resultTag.getColumnIndex(DatenbankHelper.DB_F_JOB)));
                    ergebnis.nameZusatzwert = ergebnis.job.getZusatzDefinition(
                            resultZusatz.getLong(resultZusatz.getColumnIndex(DatenbankHelper.DB_F_ZUSATZFELD))
                    ).getName();
                    ergebnis.datum = new Datum(
                            resultTag.getInt(resultTag.getColumnIndex(DatenbankHelper.DB_F_JAHR)),
                            resultTag.getInt(resultTag.getColumnIndex(DatenbankHelper.DB_F_MONAT)),
                            resultTag.getInt(resultTag.getColumnIndex(DatenbankHelper.DB_F_TAG)),
                            ergebnis.job.getWochenbeginn());
                }
                resultTag.close();

                long abw = resultSchichten.getLong(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_ABWESENHEIT));
                ergebnis.abwesenheit = ergebnis.job.getAbwesenheiten().getVonId(abw);
                ergebnisListe.add(ergebnis);
            }
            resultSchichten.close();
        }
        resultZusatz.close();
        // ASettings.mDatenbank.close();

        return ergebnisListe;
    }

    // Suche in Einsatzorten
    @SuppressLint("Range")
    private ArrayList<Ergebnis> sucheInEinsatzorte(Object[] begriffe) {
        ArrayList<Ergebnis> ergebnisListe = new ArrayList<>();
        // SQLiteDatabase mDatenbank = ASettings.stundenDBHelper.getReadableDatabase();

        //den Filterstring bauen
        StringBuilder filter = new StringBuilder();
        for (int i = 0; i < begriffe.length; i++) {
            if (i > 0) {
                filter.append(" OR ");
            }
            filter.append("name LIKE ?");
        }

        // alle relevanten Einsatzorte lesen
        Cursor resultOrte = ASettings.mDatenbank.query(
                true,
                DatenbankHelper.DB_T_EORT,
                eortSpalten,
                filter.toString(),
                Arrays.copyOf(begriffe, begriffe.length, String[].class),
                null, null, DatenbankHelper.DB_F_NAME, null
        );

        while (resultOrte.moveToNext()) {
            if (resultOrte.getInt(resultOrte.getColumnIndex(DatenbankHelper.DB_F_ANZAHL_VERWENDET)) > 0) {
                // alle Schichten lesen, in denen der Einsatzort zugeordnet ist
                Cursor resultSchichten = ASettings.mDatenbank.query(
                        true,
                        DatenbankHelper.DB_T_SCHICHT,
                        schichtSpalten,
                        DatenbankHelper.DB_F_EORT + " = ?",
                        new String[]{String.valueOf(resultOrte.getLong(resultOrte.getColumnIndex(DatenbankHelper.DB_F_ID)))},
                        null, null, DatenbankHelper.DB_F_TAG, null
                );

                while (resultSchichten.moveToNext()) {
                    Ergebnis ergebnis = new Ergebnis();
                    ergebnis.schichtID = resultSchichten.getLong(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_ID));
                    ergebnis.tagID = resultSchichten.getLong(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_TAG));
                    ergebnis.von = resultSchichten.getInt(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_VON));
                    ergebnis.bis = resultSchichten.getInt(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_BIS));
                    ergebnis.pause = resultSchichten.getInt(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_PAUSE));
                    ergebnis.nameOrtOderSchicht = resultOrte.getString(resultOrte.getColumnIndex(DatenbankHelper.DB_F_NAME));
                    ergebnis.zusatzwert = "";
                    // Datum des Tages ermitteln
                    Cursor resultTag = ASettings.mDatenbank.query(
                            true,
                            DatenbankHelper.DB_T_TAG,
                            allSpalten,
                            DatenbankHelper.DB_F_ID + " = ?",
                            new String[]{String.valueOf(ergebnis.tagID)},
                            null, null, null, "1"
                    );
                    if (resultTag.getCount() > 0) {
                        resultTag.moveToFirst();
                        ergebnis.job = ASettings.jobListe.getVonID(resultTag.getLong(resultTag.getColumnIndex(DatenbankHelper.DB_F_JOB)));
                        ergebnis.datum = new Datum(
                                resultTag.getInt(resultTag.getColumnIndex(DatenbankHelper.DB_F_JAHR)),
                                resultTag.getInt(resultTag.getColumnIndex(DatenbankHelper.DB_F_MONAT)),
                                resultTag.getInt(resultTag.getColumnIndex(DatenbankHelper.DB_F_TAG)),
                                ergebnis.job.getWochenbeginn());
                    }
                    resultTag.close();

                    long abw = resultSchichten.getLong(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_ABWESENHEIT));
                    ergebnis.abwesenheit = ergebnis.job.getAbwesenheiten().getVonId(abw);
                    ergebnisListe.add(ergebnis);
                }
                resultSchichten.close();
            }
        }
        resultOrte.close();
        // mDatenbank.close();

        return ergebnisListe;
    }

 @SuppressLint("Range")
    private ArrayList<Ergebnis> sucheInSchichtnamen(Object[] begriffe) {
     ArrayList<Ergebnis> ergebnisListe = new ArrayList<>();
     ArrayList<defSchicht> defSchichtListe = new ArrayList<>();

     // Defaultschichten durchsuchen und zum Suchstring passende finden
     //den Filterstring bauen
     StringBuilder filter = new StringBuilder();
     for (int i = 0; i < begriffe.length; i++) {
         if (i > 0) {
             filter.append(" OR ");
         }
         filter.append("name LIKE ?");
     }

     // alle relevanten Defaultschichten lesen
     Cursor resultdefSchichten = ASettings.mDatenbank.query(
             true,
             DatenbankHelper.DB_T_SCHICHT_DEFAULT,
             defSchichtSpalten,
             filter.toString(),
             Arrays.copyOf(begriffe, begriffe.length, String[].class),
             null, null, DatenbankHelper.DB_F_NAME, null
     );
     // Liste mit gefundenen Defaultschichten befüllen
     while (resultdefSchichten.moveToNext()) {
         defSchichtListe.add(new defSchicht(
                 resultdefSchichten.getLong(resultdefSchichten.getColumnIndex(DatenbankHelper.DB_F_ID)),
                 resultdefSchichten.getString(resultdefSchichten.getColumnIndex(DatenbankHelper.DB_F_NAME))
         ));
     }
     resultdefSchichten.close();

     // Schichten, die von betreffenden Defaultschichten ableiten, finden
     // Ergebnisliste füllen
     for (defSchicht dSchicht : defSchichtListe) {
         Cursor resultSchichten = ASettings.mDatenbank.query(
                 true,
                 DatenbankHelper.DB_T_SCHICHT,
                 schichtSpalten,
                 DatenbankHelper.DB_F_SCHICHT_DEFAULT + " = ?",// and (" + DatenbankHelper.DB_F_NAME + " IS NULL) ",
                 new String[]{String.valueOf(dSchicht.id)},
                 null, null, DatenbankHelper.DB_F_TAG, null
         );
         while (resultSchichten.moveToNext()) {
             long tagID = resultSchichten.getLong(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_TAG));
             // Datum des Tages ermitteln
             Cursor resultTag = ASettings.mDatenbank.query(
                     true,
                     DatenbankHelper.DB_T_TAG,
                     allSpalten,
                     DatenbankHelper.DB_F_ID + " = ?",
                     new String[]{String.valueOf(tagID)},
                     null, null, null, "1"
             );

             if (resultTag.getCount() > 0) {
                 resultTag.moveToFirst();
                 Arbeitsplatz job = ASettings.jobListe.getVonID(resultTag.getLong(resultTag.getColumnIndex(DatenbankHelper.DB_F_JOB)));

                 long abw = resultSchichten.getLong(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_ABWESENHEIT));
                 Abwesenheit abwesenheit = job.getAbwesenheiten().getVonId(abw);

                 // nur wenn es Arbeitszeit ist, ist auch der Schichtname relevant
                 if (abwesenheit.getKategorie() == Abwesenheit.KAT_ARBEITSZEIT) {
                     Ergebnis ergebnis = new Ergebnis();
                     ergebnis.schichtID = resultSchichten.getLong(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_ID));
                     ergebnis.tagID = tagID;
                     ergebnis.von = resultSchichten.getInt(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_VON));
                     ergebnis.bis = resultSchichten.getInt(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_BIS));
                     ergebnis.pause = resultSchichten.getInt(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_PAUSE));
                     ergebnis.nameOrtOderSchicht = dSchicht.name;
                     ergebnis.zusatzwert = "";
                     ergebnis.job = job;
                     ergebnis.datum = new Datum(
                             resultTag.getInt(resultTag.getColumnIndex(DatenbankHelper.DB_F_JAHR)),
                             resultTag.getInt(resultTag.getColumnIndex(DatenbankHelper.DB_F_MONAT)),
                             resultTag.getInt(resultTag.getColumnIndex(DatenbankHelper.DB_F_TAG)),
                             ergebnis.job.getWochenbeginn());
                     ergebnis.abwesenheit = abwesenheit;
                     ergebnisListe.add(ergebnis);
                 }
             }
             resultTag.close();
         }
         resultSchichten.close();
     }

     // Schichten durchsuchen und zum Suchstring passende finden
     Cursor resultSchichten = ASettings.mDatenbank.query(
             true,
             DatenbankHelper.DB_T_SCHICHT,
             schichtSpalten,
             filter.toString(),
             Arrays.copyOf(begriffe, begriffe.length, String[].class),
             null, null, DatenbankHelper.DB_F_NAME, null
     );
     // Ergebnisliste füllen
     while (resultSchichten.moveToNext()) {
         Ergebnis ergebnis = new Ergebnis();
         ergebnis.schichtID = resultSchichten.getLong(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_ID));
         ergebnis.tagID = resultSchichten.getLong(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_TAG));
         ergebnis.von = resultSchichten.getInt(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_VON));
         ergebnis.bis = resultSchichten.getInt(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_BIS));
         ergebnis.pause = resultSchichten.getInt(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_PAUSE));
         ergebnis.nameOrtOderSchicht = resultSchichten.getString(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_NAME));
         ergebnis.zusatzwert = "";
         // Datum des Tages ermitteln
         Cursor resultTag = ASettings.mDatenbank.query(
                 true,
                 DatenbankHelper.DB_T_TAG,
                 allSpalten,
                 DatenbankHelper.DB_F_ID + " = ?",
                 new String[]{String.valueOf(ergebnis.tagID)},
                 null, null, null, "1"
         );
         if (resultTag.getCount() > 0) {
             resultTag.moveToFirst();
             ergebnis.job = ASettings.jobListe.getVonID(resultTag.getLong(resultTag.getColumnIndex(DatenbankHelper.DB_F_JOB)));
             ergebnis.datum = new Datum(
                     resultTag.getInt(resultTag.getColumnIndex(DatenbankHelper.DB_F_JAHR)),
                     resultTag.getInt(resultTag.getColumnIndex(DatenbankHelper.DB_F_MONAT)),
                     resultTag.getInt(resultTag.getColumnIndex(DatenbankHelper.DB_F_TAG)),
                     ergebnis.job.getWochenbeginn());
         }
         resultTag.close();

         long abw = resultSchichten.getLong(resultSchichten.getColumnIndex(DatenbankHelper.DB_F_ABWESENHEIT));
         ergebnis.abwesenheit = ergebnis.job.getAbwesenheiten().getVonId(abw);
         ergebnisListe.add(ergebnis);
     }
     resultSchichten.close();

     return ergebnisListe;
 }

    /*
     * Suchliste
     */
    public class ErgebnisListadapter extends BaseExpandableListAdapter {
        ArrayList<ArrayList<Integer>> mFilterData;
        private ValueFilter valueFilter;
        String eingabeFilter;

        @Override
        public int getGroupCount() {
            return 3;
        }

        @Override
        public int getChildrenCount(int g_pos) {
            //int mMenge = 0;
            if (mFilterData != null)
                return mFilterData.get(g_pos).size();
            else
                return mErgebnisse.get(g_pos).size();
        }

        @Override
        public ArrayList<Ergebnis> getGroup(int pos) {
            return mErgebnisse.get(pos);
        }

        @Override
        public Object getChild(int g_pos, int c_pos) {
            if (mFilterData != null) {
                return mErgebnisse.get(g_pos).get(mFilterData.get(g_pos).get(c_pos));
            } else
                return mErgebnisse.get(g_pos).get(c_pos);
        }

        @Override
        public long getGroupId(int pos) {
            return pos;
        }

        @Override
        public long getChildId(int g_pos, int c_pos) {
            Ergebnis mErgebnis;
            if (mFilterData != null)
                mErgebnis = mErgebnisse.get(g_pos).get(mFilterData.get(g_pos).get(c_pos));
            else
                mErgebnis = mErgebnisse.get(g_pos).get(c_pos);


            return mErgebnis.schichtID;
        }

        @Override
        public boolean hasStableIds() {
            return false;
        }

        @Override
        public View getGroupView(int pos, boolean b, View convertView, ViewGroup parent) {
            TextView mTreffer;
            if (convertView == null) {
                LayoutInflater layInflator = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

                if (layInflator != null) {
                    convertView = layInflator.inflate(android.R.layout.simple_list_item_2, parent, false);

                    TextView mTitel = convertView.findViewById(android.R.id.text1);
                    mTreffer = convertView.findViewById(android.R.id.text2);
                    mTitel.setPadding(24, 0, 0, 0);
                    mTreffer.setPadding(24, 0, 0, 0);

                    mTitel.setText((pos == 0) ? R.string.su_notiz : R.string.su_eort);
                    switch (pos){
                        case 0:
                            mTitel.setText(R.string.su_notiz);
                            break;
                        case 1:
                            mTitel.setText(R.string.su_eort);
                            break;
                        case 2:
                            mTitel.setText(R.string.su_schichtname);
                            break;

                    }
                    mTreffer.setText(getString(R.string.su_treffer,
                            (mFilterData != null) ? mFilterData.get(pos).size() : getGroup(pos).size()
                    ));
                }
            } else {
                mTreffer = convertView.findViewById(android.R.id.text2);
                mTreffer.setText(getString(R.string.su_treffer,
                        (mFilterData != null) ? mFilterData.get(pos).size() : getGroup(pos).size()
                ));
            }

            return convertView;
        }

        @Override
        public View getChildView(int g_pos, int c_pos, boolean b, View convertView, ViewGroup parent) {

            // if (convertView == null) {
            LayoutInflater layInflator = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            if (layInflator != null) {
                convertView = layInflator.inflate(R.layout.item_suche_schicht, parent, false);

                convertView.setBackgroundColor(
                        (c_pos % 2 == 0) ?
                                ASettings.aktJob.getFarbe_Zeile_gerade() :
                                ASettings.aktJob.getFarbe_Zeile_ungerade()
                );

                TextView mTitel = convertView.findViewById(R.id.SU_schicht_datum);
                TextView mZeitraum = convertView.findViewById(R.id.SU_schicht_zeit);
                TextView mDetail = convertView.findViewById(R.id.SU_schicht_detail);

                Ergebnis mWerte = (Ergebnis) getChild(g_pos, c_pos);

                // 1. Zeile
                String sTitel = mWerte.datum.getString_Datum(mContext);
                sTitel += " - " + mWerte.job.getName();
                mTitel.setText(sTitel);
                mTitel.setTextColor(mWerte.job.getFarbe_Schrift_Titel());
                mTitel.setBackgroundColor(mWerte.job.getFarbe());

                // 2. Zeile
                Uhrzeit mZeit = new Uhrzeit();
                switch (mWerte.abwesenheit.getWirkung()) {
                    case Abwesenheit.WIRKUNG_IST_PLUS_EFFEKTIV:
                    case Abwesenheit.WIRKUNG_SOLL_MINUS_EFFEKTIV:
                        sTitel = mWerte.abwesenheit.getName() + ": ";
                        mZeit.set(mWerte.von);
                        sTitel += mZeit.getUhrzeitString() + " - ";
                        mZeit.set(mWerte.bis);
                        sTitel += mZeit.getUhrzeitString();
                        break;
                    default:
                        sTitel = mWerte.abwesenheit.getName();
                }
                mZeitraum.setText(sTitel);

                // 3. Zeile
                mDetail.setText((g_pos == 0) ? mWerte.nameZusatzwert + ": " + mWerte.zusatzwert : mWerte.nameOrtOderSchicht);
            }
            // }
            return convertView;
        }

        @Override
        public boolean isChildSelectable(int g_pos, int c_pos) {
            return true;
        }


        /*
         * Listenfilter
         */

        public Filter getFilter() {
            if (valueFilter == null) {
                valueFilter = new ValueFilter();
            }
            return valueFilter;
        }

        private class ValueFilter extends Filter {

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                if (constraint.length() > 0) {
                    eingabeFilter = constraint.toString().toLowerCase();
                    FilterResults results = new FilterResults();
                    Ergebnis mErgebnis;
                    ArrayList<ArrayList<Integer>> filterList = new ArrayList<>();

                    for(int filterKategorie=0; filterKategorie < mErgebnisse.size(); filterKategorie++) {
                        filterList.add(new ArrayList<>());
                        for (int i = 0; i < mErgebnisse.get(filterKategorie).size(); i++) {
                            mErgebnis = mErgebnisse.get(filterKategorie).get(i);
                            if (
                                    mErgebnis.zusatzwert.toLowerCase().contains(eingabeFilter) ||
                                    mErgebnis.nameOrtOderSchicht.toLowerCase().contains(eingabeFilter) ||
                                    mErgebnis.job.getName().toLowerCase().contains(eingabeFilter) ||
                                    mErgebnis.abwesenheit.getName().toLowerCase().contains(eingabeFilter)
                            ) {
                                filterList.get(filterKategorie).add(i);
                            }
                        }
                    }

                    /*filterList.add(new ArrayList<>());
                    for (int i = 0; i < mErgebnisse.get(0).size(); i++) {
                        mErgebnis = mErgebnisse.get(0).get(i);
                        if (mErgebnis.zusatzwert.toLowerCase().contains(eingabeFilter)) {
                            filterList.get(0).add(i);
                        }
                    }
                    filterList.add(new ArrayList<>());
                    for (int i = 0; i < mErgebnisse.get(1).size(); i++) {
                        mErgebnis = mErgebnisse.get(1).get(i);
                        if (mErgebnis.nameOrtOderSchicht.toLowerCase().contains(eingabeFilter)) {
                            filterList.get(1).add(i);
                        }
                    }
                    filterList.add(new ArrayList<>());
                    for (int i = 0; i < mErgebnisse.get(2).size(); i++) {
                        mErgebnis = mErgebnisse.get(2).get(i);
                        if (mErgebnis.nameOrtOderSchicht.toLowerCase().contains(eingabeFilter)) {
                            filterList.get(2).add(i);
                        }
                    }*/
                    results.count = 3;
                    results.values = filterList;

                    return results;
                }

                return null;
            }

            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                if (results != null && results.values != null) {
                    try {
                        mFilterData = (ArrayList<ArrayList<Integer>>) results.values;
                    /*ArrayList<ArrayList<Integer>> fl = (ArrayList<ArrayList<Integer>>) results.values;
                    mFilterData = new ArrayList<>();
                    mFilterData.add(fl.get(0));
                    mFilterData.add(fl.get(1));*/
                    } catch (ClassCastException ce) {
                        mFilterData = null;
                    }
                } else
                    mFilterData = null;
                notifyDataSetChanged();
            }
        }
    }

    /*
     * Suchergebnis
     */
    private static class Ergebnis {
        //long jobID;
        long tagID;
        long schichtID;
        Datum datum;
        int von;
        int bis;
        int pause;
        //String jobname;
        Arbeitsplatz job;
        Abwesenheit abwesenheit;
        String nameOrtOderSchicht;
        String zusatzwert;
        String nameZusatzwert;
    }

    // Defaultschicht Eintrag
    private static class defSchicht {
        defSchicht(long id, String name){
            this.id = id;
            this.name = name;
        }
        long id;
        String name;
    }
}
