/*
 * Copyright (C) 2016 Jorge Ruesga
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.ruesga.rview.adapters;

import android.content.Context;
import android.databinding.DataBindingUtil;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;

import com.ruesga.rview.R;
import com.ruesga.rview.databinding.DropdownItemBinding;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

public abstract class FilterableAdapter extends android.widget.BaseAdapter implements Filterable {

    private static final int MAX_RESULTS = 5;

    private Context mContext;
    private List<CharSequence> mResults;
    private List<CharSequence> mFilteredResults = new ArrayList<>();
    private final ResultFilter mFilter;

    public FilterableAdapter(Context context) {
        mContext = context;
        mFilter = new ResultFilter(this);
    }

    public Context getContext() {
        return mContext;
    }

    @Override
    public int getCount() {
        return mFilteredResults.size();
    }

    @Override
    public CharSequence getItem(int position) {
        return mFilteredResults.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        if (v == null) {
            DropdownItemBinding binding = DataBindingUtil.inflate(
                    LayoutInflater.from(mContext), R.layout.dropdown_item, parent, false);
            v = binding.getRoot();
            v.setTag(binding);
        }

        CharSequence result = mFilteredResults.get(position);
        DropdownItemBinding binding = (DropdownItemBinding) v.getTag();
        binding.item.setText(result);
        binding.executePendingBindings();

        return v;
    }

    public int getMaxResults() {
        return MAX_RESULTS;
    }

    @Override
    public Filter getFilter() {
        return mFilter;
    }

    public abstract List<CharSequence> getResults();


    private static class ResultFilter extends Filter {

        private WeakReference<FilterableAdapter> mInnerClass;
        private final List<CharSequence> mTemp = new ArrayList<>();

        ResultFilter(FilterableAdapter adapter) {
            mInnerClass = new WeakReference<>(adapter);
        }

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterableAdapter innerClass = mInnerClass.get();

            FilterResults results = new FilterResults();
            if (innerClass != null && constraint != null) {
                // Fetch if needed
                if (innerClass.mResults == null) {
                    innerClass.mResults = innerClass.getResults();
                }

                // Filter results
                mTemp.clear();
                if (innerClass.mResults != null) {
                    for (CharSequence v : innerClass.mResults) {
                        if (v.toString().contains(constraint)) {
                            mTemp.add(v);
                        }
                        final int maxResults = innerClass.getMaxResults();
                        if (maxResults > 0 &&  mTemp.size() >= maxResults) {
                            break;
                        }
                    }
                }

                results.values = mTemp;
                results.count = mTemp.size();
            }
            return results;
        }

        @Override
        @SuppressWarnings("unchecked")
        protected void publishResults(CharSequence constraint, FilterResults results) {
            FilterableAdapter innerClass = mInnerClass.get();
            if (innerClass != null) {
                innerClass.mFilteredResults.clear();
                if (results.count > 0) {
                    innerClass.mFilteredResults.addAll((List<CharSequence>) results.values);
                    innerClass.notifyDataSetChanged();
                } else {
                    innerClass.notifyDataSetInvalidated();
                }
            }
        }
    }

}

@@ -2383,13 +2383,8 @@
 ing.
-item.
 setT
@@ -2393,16 +2393,96 @@
 t(result
+.toString());%0A        binding.setIcon(null);%0A        binding.setIsSelected(false
 );%0A     

Use databinding instead of normal text linking