package ch.spherIC.recurvebowsight.utilities;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.TextView;

import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import ch.spherIC.recurvebowsight.R;

/**
 * Almost unbelievably, if we want to create a Material Spinner,
 * we're forced to subclass ArrayAdapter.  That statement alone
 * is maddening.  The issue is that there's no such thing as a Material
 * Spinner. Instead, there's an Exposed Dropdown Menu, which is really
 * an AutoCompleteTextView wrapped in a TextInputLayout, which replaces a
 * Spinner. The reason we have to subclass ArrayAdapter is because we need
 * the AutoCompleteTextView to act like a proper Spinner.  Thus we have to
 * override the AutoCompleteTextView's Filter so that it NEVER performs
 * filtering of the dropdown menu items.
 */
public class NoFilterArrayAdapter<T extends Object> extends ArrayAdapter<T> {

    private final List<T> objects;
    private final DecimalFormat formatter;

    private final Filter filter_that_does_nothing = new Filter() {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();
            results.values = NoFilterArrayAdapter.this.objects;
            results.count = NoFilterArrayAdapter.this.objects.size();
            return results;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            notifyDataSetChanged();
        }
    };

    /**
     * Constructor
     *
     * @param context the context
     * @param resource the resource
     * @param objects the list of objects
     */
    public NoFilterArrayAdapter(@NonNull Context context, int resource, @NonNull List<T> objects) {
        this(context, resource, objects, null);
    }

    /**
     * Constructor
     *
     * @param context the context
     * @param resource the resource
     * @param objects the list of objects
     * @param formatter a formatter for the items
     */
    public NoFilterArrayAdapter(@NonNull Context context, int resource, @NonNull List<T> objects, @Nullable DecimalFormat formatter) {
        super(context, resource, objects);
        this.objects = objects;
        this.formatter = formatter;
    }

    /**
     * Constructor
     *
     * @param context the context
     * @param resource the resource
     * @param objects the list of objects
     */
    public NoFilterArrayAdapter(@NonNull Context context, int resource, @NonNull T[] objects) {
        this(context, resource, objects, null);
    }

    /**
     * Constructor
     *
     * @param context the context
     * @param resource the resource
     * @param objects the list of objects
     * @param formatter a formatter for the items
     */
    public NoFilterArrayAdapter(@NonNull Context context, int resource, @NonNull T[] objects, @Nullable DecimalFormat formatter) {
        super(context, resource, objects);
        this.objects = Arrays.asList(objects);
        this.formatter = formatter;
    }

    @NonNull
    @Override
    public Filter getFilter() {
        return filter_that_does_nothing;
    }

    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        if (this.formatter == null) {
            return super.getView(position, convertView, parent);
        } else {
            T item = getItem(position);
            if (item instanceof Double) {
                String val = this.formatter.format(item);
                convertView = LayoutInflater.from(getContext()).inflate(R.layout.simple_spinner_line, parent, false);
                TextView tv = convertView.findViewById(R.id.idSimpleLineText);
                tv.setText(val);
            } else {
                return super.getView(position, convertView, parent);
            }
            return convertView;
        }
    }
}
