/* 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.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.appcompat.widget.AppCompatCheckBox;
import androidx.core.widget.CompoundButtonCompat;

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

import askanimus.arbeitszeiterfassung2.R;
import askanimus.arbeitszeiterfassung2.setup.ASettings;
import askanimus.arbeitszeiterfassung2.setup.ISettings;
public class ZusatzWerteAuswahlListAdapter extends BaseAdapter {
    private final Context context;
    ZusatzWertAuswahlListe auswahlListe;
    ZusatzwertAuswahlListeCallbacks callback;

    List<Integer> mFilterData;
    private ValueFilter valueFilter;
    String eingabeFilter;

    ZusatzWerteAuswahlListAdapter(
            ZusatzWertAuswahlListe liste, Context ctx, ZusatzwertAuswahlListeCallbacks cb
    ) {
        context = ctx;
        auswahlListe = liste;
        callback = cb;
    }

    public void update(){
        auswahlListe.sort(
                ASettings.mPreferenzen.getInt(
                    ISettings.KEY_SORT_AUSWAHLLISTE,
                    ISettings.SORT_NO
                )
            );
        valueFilter = null;
        mFilterData = null;
        callback.onZusatzwerteChange();
    }

    @Override
    public int getCount() {
        if(mFilterData != null){
            return mFilterData.size();
        }
        return auswahlListe.size();
    }

    @Override
    public ZusatzWertAuswahlListe.zusatzWertAuswahlItem getItem(int position) {
        if(mFilterData != null){
            return auswahlListe.getEintrag(mFilterData.get(position));
        }
         return auswahlListe.getEintrag(position);
    }

    @Override
    public long getItemId(int position) {
        if(mFilterData != null){
            return auswahlListe.getEintragWert(mFilterData.get(position)).getId();
        }
        return auswahlListe.getEintragWert(position).getId();
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ZusatzWertAuswahlListe.zusatzWertAuswahlItem item;
        final boolean isText;

        if (convertView == null && context != null) {
            LayoutInflater layInflator =
                    (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

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

        if (convertView != null) {
            item = getItem(position);
            isText = item.getWert().getDatenTyp() == IZusatzfeld.TYP_AUSWAHL_TEXT;

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

            // der Wert
            final TextView vText = convertView.findViewById(R.id.auswahl_Text);
            vText.setText(item.getWert().getString(true));

            // wenn es eine Textliste ist, dann können mehrere Einträge ausgewählt werden
            if (isText) {
                // das Icon zur Mehrfachauswahl
                AppCompatCheckBox cBox = convertView.findViewById(R.id.auswahl_checkBox);
                cBox.setVisibility(View.VISIBLE);
                CompoundButtonCompat.setButtonTintList(
                        cBox,
                        ASettings.aktJob.getFarbe_Radio()
                );
                cBox.setChecked(item.isSelect());
                cBox.setOnClickListener(v -> {
                    auswahlListe.changeSummeItemSelected(item.setSelect(cBox.isChecked()));
                    callback.onAuswahlItem();
                });

                convertView.setOnClickListener(v -> {
                    if (auswahlListe.getSummeSelectedItems() > 0) {
                        cBox.toggle();
                        auswahlListe.changeSummeItemSelected(item.setSelect(cBox.isChecked()));
                        callback.onAuswahlItem();
                    } else {
                        item.addVerwendet();
                        callback.onSelectItem(item.getWert());
                    }
                });
            } else {
                convertView.setOnClickListener(v -> {
                    item.addVerwendet();
                    callback.onSelectItem(item.getWert());
                });
            }

            //das Icon zum löschen des Wertes
            ImageView iDelete = convertView.findViewById(R.id.auswahl_buttonR);
            iDelete.setOnClickListener(v -> {
                callback.onDeleteItem(position);
            });

        }
        return convertView;
    }

    /*
     * Listenfilter
     */
    Filter getFilter() {
        if (valueFilter == null) {
            valueFilter = new ValueFilter();
        }
        return valueFilter;
    }

    private class ValueFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            eingabeFilter = constraint.toString();
            List<Integer> filterList = new ArrayList<>();
            FilterResults results = new FilterResults();

            if (constraint.length() > 0) {
                int i = 0;
                for (ZusatzWertAuswahlListe.zusatzWertAuswahlItem item : auswahlListe.getListe()) {
                    if (item.getWert().getString(false).toLowerCase()
                            .contains(constraint.toString().toLowerCase())
                    ) {
                        filterList.add(i);
                    }
                    i++;
                }
                results.count = filterList.size();
                results.values = filterList;
            }

            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            mFilterData = (List<Integer>) results.values;
            notifyDataSetChanged();
        }
    }

    /*
     * Callback Interfaces
     */
    public interface ZusatzwertAuswahlListeCallbacks {
        /**
         * Aufgerufen wenn sich die Ordnung in der Liste geändert hat
         */
        void onZusatzwerteChange();

        /**
         * wird aufgerufen wenn ein Wert ausgewählt wurde
         * @param itemWert der ausgewählte Wert
         */
        void onSelectItem(IZusatzfeld itemWert);

        /**
         * wird aufgerufen wenn ein Wert gelöscht wurde
         * @param  position die Position des Wertes in der Liste
         */
        void onDeleteItem(int position);

        void onAuswahlItem();
    }
}
