/* 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.content.Context;
import android.text.InputFilter;
import android.text.InputType;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.EditText;
import android.widget.Filter;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import androidx.appcompat.app.AlertDialog;
import androidx.core.content.res.ResourcesCompat;

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

import askanimus.arbeitszeiterfassung2.R;
import askanimus.arbeitszeiterfassung2.arbeitsplatz.Arbeitsplatz;
import askanimus.arbeitszeiterfassung2.setup.ASettings;
import askanimus.arbeitszeiterfassung2.setup.ISettings;

/**
 * @author askanimus@gmail.com on 27.12.15.
 */
public class EinsatzortListAdapter  extends BaseExpandableListAdapter {
    private final Context mContext;

    private final ArrayList<Einsatzort>[] mEinsatzorte;
    private final EinsatzortListeCallbacks mCallback;
    private final Arbeitsplatz mArbeitsplatz;

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

    public EinsatzortListAdapter(Context context, Arbeitsplatz arbeitsplatz, EinsatzortListeCallbacks callback){
        mContext = context;
        mArbeitsplatz = arbeitsplatz;
        mCallback = callback;

        mEinsatzorte = new ArrayList[2];
        mEinsatzorte[0] = mArbeitsplatz.getEinsatzortListe().getAktive();
        mEinsatzorte[1] = mArbeitsplatz.getEinsatzortListe().getPassive();
    }

    public Einsatzort add(String name, long datum){
        Einsatzort o = mArbeitsplatz.getEinsatzortListe().add(name);
        o.add_Verwendung(true, datum);
        update();
        return o;
    }

    public void update(){
        mArbeitsplatz.getEinsatzortListe().sort(ASettings.mPreferenzen.getInt(
                    ISettings.KEY_SORT_EORTLISTE,
                    ISettings.SORT_NO)
            );
        mEinsatzorte[0] = mArbeitsplatz.getEinsatzortListe().getAktive();
        mEinsatzorte[1] = mArbeitsplatz.getEinsatzortListe().getPassive();

        valueFilter = null;
        mFilterData = null;
        mCallback.onEinsatzorteChange();
    }

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

    @Override
    public int getChildrenCount(int groupPosition) {
        int mMenge;

        if (mFilterData != null){
            mMenge = mFilterData[groupPosition].size();
        } else
            mMenge = getGroup(groupPosition).size();

        return mMenge;
    }

    @Override
    public List<Einsatzort> getGroup(int groupPosition) {
        if(groupPosition < 2)
            return mEinsatzorte[groupPosition];
        else
            return mEinsatzorte[1];
    }

    @Override
    public Einsatzort getChild(int groupPosition, int childPosition) {
        if(mFilterData != null) {
            return getGroup(groupPosition).get(mFilterData[groupPosition].get(childPosition));
        } else {
            return getGroup(groupPosition).get(childPosition);
        }
    }

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

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

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

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {

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

            if (layInflator != null) {
                convertView = layInflator.inflate(R.layout.item_eort_gruppe, parent, false);
            }
        }
        if(convertView != null) {
            TextView mTitel = convertView.findViewById(R.id.eortGruppe_Text);
            mTitel.setText((groupPosition == 0) ? R.string.eort_sichtbar : R.string.eort_ausgeblendet);
            RelativeLayout lContainer = (RelativeLayout) mTitel.getParent();
            lContainer.setBackgroundColor(((groupPosition == 0) ? mArbeitsplatz.getFarbe_Schicht_gerade() : mArbeitsplatz.getFarbe_Schicht_ungerade()));
            //mTitel.setTextColor(mArbeitsplatz.getFarbe_Schrift());

            ImageView mIcon = convertView.findViewById(R.id.eortGruppe_button);
            mIcon.setImageDrawable((groupPosition == 0) ?
                            ResourcesCompat.getDrawable(
                                    ASettings.res,
                                    android.R.drawable.ic_menu_view,
                                    mContext.getTheme()) :
                            ResourcesCompat.getDrawable(
                                    ASettings.res,
                                    R.drawable.ic_action_delete,
                                    mContext.getTheme())
            );

        }
        return convertView;
    }

    @Override
    public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        final Einsatzort mOrt = getChild(groupPosition, childPosition);//mEinsatzorte.getOrt(childPosition, (groupPosition == 0));


        LayoutInflater layInflator = (LayoutInflater) this.mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

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

            convertView.setBackgroundColor(((childPosition % 2 == 0) ?
                    mArbeitsplatz.getFarbe_Zeile_gerade() :
                    mArbeitsplatz.getFarbe_Zeile_ungerade()));

            final TextView vText = convertView.findViewById(R.id.eort_Text);
            vText.setText(mOrt.getName());

            if (groupPosition == 0) {
                ImageView iEdit = convertView.findViewById(R.id.eort_buttonL);
                iEdit.setOnClickListener(view -> {
                    final EditText input = new EditText(mContext);
                    input.setText(mOrt.getName());
                    input.setInputType(InputType.TYPE_CLASS_TEXT);
                    input.setSelection(input.getText().length());
                    input.setFocusableInTouchMode(true);
                    input.requestFocus();
                    input.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
                    //Längenbegrenzung des Inputstrings
                    InputFilter[] fa = new InputFilter[1];
                    fa[0] = new InputFilter.LengthFilter(ISettings.LAENGE_EORT);
                    input.setFilters(fa);
                    new AlertDialog.Builder(mContext)
                            .setTitle(mContext.getString(R.string.einsatzort))
                            .setView(input)
                            .setPositiveButton(mContext.getString(android.R.string.ok), (dialog, whichButton) -> {
                                String sWert = input.getText().toString();
                                mOrt.setName(sWert);
                                vText.setText(sWert);
                            }).setNegativeButton(mContext.getString(android.R.string.cancel), (dialog, whichButton) -> {
                                // Do nothing.
                            }).show();
                });
                ImageView iButton = convertView.findViewById(R.id.eort_buttonR);
                iButton.setImageDrawable(
                         ResourcesCompat.getDrawable(
                                 ASettings.res,
                                 R.drawable.ic_action_delete,
                                 mContext.getTheme())
                );
                iButton.setOnClickListener(view -> {
                    mOrt.delete();
                    update();
                });

            } else {
                ImageView iDelete = convertView.findViewById(R.id.eort_buttonR);
                if(mOrt.getVerwendung() <= 0) {
                    iDelete.setImageDrawable(
                            ResourcesCompat.getDrawable(
                                    ASettings.res,
                                    R.drawable.ic_action_delete_forever,
                                    mContext.getTheme())
                    );
                    iDelete.setOnClickListener(view -> {
                        mOrt.delete();
                        update();
                    });
                } else {
                    iDelete.setVisibility(View.INVISIBLE);
                }

                ImageView iView = convertView.findViewById(R.id.eort_buttonL);
                iView.setImageDrawable(
                         ResourcesCompat.getDrawable(
                                 ASettings.res,
                                 android.R.drawable.ic_menu_view,
                                 mContext.getTheme())
                );
                iView.setOnClickListener(view -> {
                    mOrt.undelete();
                    update();
                });
            }
        }
        return convertView;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }



    /*
    * 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 List[]{
                    new ArrayList<>(),
                    new ArrayList<>()
            };
            FilterResults results = new FilterResults();

            if (constraint.length() > 0) {
                int g = 0;
                for (ArrayList<Einsatzort> Orte : mEinsatzorte) {
                    int i = 0;
                    for (Einsatzort ort : Orte) {
                        if (ort.getName().toLowerCase().contains(constraint.toString().toLowerCase())) {
                            filterList[g].add(i);
                        }
                        i++;
                    }
                    g++;
                }
                results.count = 2;
                results.values = filterList;
            }

            return results;
        }

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


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

}
