/**
*
*/
package net.osmand.plus.activities.search;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v7.widget.PopupMenu;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import net.osmand.CollatorStringMatcher;
import net.osmand.CollatorStringMatcher.StringMatcherMode;
import net.osmand.data.LatLon;
import net.osmand.osm.AbstractPoiType;
import net.osmand.osm.PoiType;
import net.osmand.plus.IconsCache;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandPlugin;
import net.osmand.plus.R;
import net.osmand.plus.activities.search.SearchActivity.SearchActivityChild;
import net.osmand.plus.base.OsmAndListFragment;
import net.osmand.plus.poi.NominatimPoiFilter;
import net.osmand.plus.poi.PoiFiltersHelper;
import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.rastermaps.OsmandRasterMapsPlugin;
import net.osmand.plus.render.RenderingIcons;
import net.osmand.plus.resources.ResourceManager;
import net.osmand.util.Algorithms;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class SearchPoiFilterFragment extends OsmAndListFragment implements SearchActivityChild {
public static final String SEARCH_LAT = SearchActivity.SEARCH_LAT;
public static final String SEARCH_LON = SearchActivity.SEARCH_LON;
public static final int REQUEST_POI_EDIT = 55;
private EditText searchEditText;
private SearchPoiByNameTask currentTask = null;
private PoiFiltersAdapter poiFitlersAdapter;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.searchpoi, container, false);
v.findViewById(R.id.SearchFilterLayout).setVisibility(View.VISIBLE);
((EditText) v.findViewById(R.id.searchEditText)).setHint(R.string.search_poi_category_hint);
((ImageView) v.findViewById(R.id.search_icon)).setImageDrawable(
getMyApplication().getIconsCache().getThemedIcon(R.drawable.ic_action_search_dark));
setupSearchEditText((EditText) v.findViewById(R.id.searchEditText));
setupOptions((ImageView) v.findViewById(R.id.options));
v.findViewById(R.id.poiSplitbar).setVisibility(View.GONE);
return v;
}
private void setupOptions(ImageView options) {
options.setImageDrawable(getMyApplication().getIconsCache().getThemedIcon(R.drawable.ic_overflow_menu_white));
options.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showOptionsMenu(v);
}
});
}
@Override
public ArrayAdapter<?> getAdapter() {
return poiFitlersAdapter;
}
private void setupSearchEditText(EditText e) {
searchEditText = e;
searchEditText.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
if (currentTask != null) {
currentTask.cancel(true);
}
currentTask = new SearchPoiByNameTask();
currentTask.execute(s.toString().trim());
}
});
searchEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
final PoiUIFilter poiFilter = getApp().getPoiFilters().getSearchByNamePOIFilter();
poiFilter.setFilterByName(searchEditText.getText().toString());
showFilterActivity(poiFilter.getFilterId());
handled = true;
}
return handled;
}
});
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
poiFitlersAdapter = new PoiFiltersAdapter(getFilters(""));
setListAdapter(poiFitlersAdapter);
setHasOptionsMenu(true);
}
@Override
public void onResume() {
super.onResume();
poiFitlersAdapter.setResult(getFilters(searchEditText == null ? "" : searchEditText.getText().toString()));
}
public List<Object> getFilters(String s) {
List<Object> filters = new ArrayList<Object>();
OsmandApplication app = getApp();
if (app == null) {
return filters;
}
PoiFiltersHelper poiFilters = app.getPoiFilters();
if (Algorithms.isEmpty(s)) {
filters.addAll(poiFilters.getTopDefinedPoiFilters());
} else {
for (PoiUIFilter pf : poiFilters.getTopDefinedPoiFilters()) {
if (!pf.isStandardFilter() && pf.getName().toLowerCase().startsWith(s.toLowerCase())) {
filters.add(pf);
}
}
List<AbstractPoiType> res = app.getPoiTypes().getAllTypesTranslatedNames(
new CollatorStringMatcher(s, StringMatcherMode.CHECK_STARTS_FROM_SPACE));
final Collator inst = Collator.getInstance();
Collections.sort(res, new Comparator<AbstractPoiType>() {
@Override
public int compare(AbstractPoiType lhs, AbstractPoiType rhs) {
return inst.compare(lhs.getTranslation(), rhs.getTranslation());
}
});
for (AbstractPoiType p : res) {
filters.add(p);
}
filters.add(poiFilters.getSearchByNamePOIFilter());
if (OsmandPlugin.getEnabledPlugin(OsmandRasterMapsPlugin.class) != null) {
filters.add(poiFilters.getNominatimPOIFilter());
filters.add(poiFilters.getNominatimAddressFilter());
}
}
return filters;
}
public OsmandApplication getApp() {
FragmentActivity activity = getActivity();
if (activity == null) {
return null;
}
return (OsmandApplication) getActivity().getApplication();
}
private void updateIntentToLaunch(Intent intentToLaunch) {
LatLon loc = null;
boolean searchAround = false;
FragmentActivity parent = getActivity();
if (loc == null && parent instanceof SearchActivity) {
loc = ((SearchActivity) parent).getSearchPoint();
searchAround = ((SearchActivity) parent).isSearchAroundCurrentLocation();
}
if (loc == null) {
loc = getApp().getSettings().getLastKnownMapLocation();
}
if (loc != null) {
intentToLaunch.putExtra(SearchActivity.SEARCH_LAT, loc.getLatitude());
intentToLaunch.putExtra(SearchActivity.SEARCH_LON, loc.getLongitude());
}
if (searchAround) {
intentToLaunch.putExtra(SearchActivity.SEARCH_NEARBY, true);
}
}
@Override
public void onListItemClick(ListView listView, View v, int position, long id) {
final Object item = getListAdapter().getItem(position);
ResourceManager rm = getApp().getResourceManager();
if (!rm.containsAmenityRepositoryToSearch(false)) {
Toast.makeText(getActivity(), R.string.data_to_search_poi_not_available, Toast.LENGTH_LONG);
return;
}
if (item instanceof PoiUIFilter) {
PoiUIFilter model = ((PoiUIFilter) item);
if (PoiUIFilter.BY_NAME_FILTER_ID.equals(model.getFilterId())
|| model instanceof NominatimPoiFilter) {
model.setFilterByName(searchEditText.getText().toString());
} else {
model.setFilterByName(model.getSavedFilterByName());
}
showFilterActivity(model.getFilterId());
} else {
PoiUIFilter custom = getApp().getPoiFilters().getFilterById(PoiUIFilter.STD_PREFIX + ((AbstractPoiType) item).getKeyName());
if (custom != null) {
if (item instanceof PoiType && ((PoiType) item).isAdditional()) {
// it is already set
} else {
custom.setFilterByName(null);
}
custom.clearFilter();
custom.updateTypesToAccept(((AbstractPoiType) item));
showFilterActivity(custom.getFilterId());
}
}
}
private void showFilterActivity(String filterId) {
final Intent newIntent = new Intent(getActivity(), SearchPOIActivity.class);
newIntent.putExtra(SearchPOIActivity.AMENITY_FILTER, filterId);
newIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
updateIntentToLaunch(newIntent);
startActivityForResult(newIntent, 0);
}
class SearchPoiByNameTask extends AsyncTask<String, Object, List<Object>> {
@Override
protected List<Object> doInBackground(String... params) {
String filter = params[0];
return getFilters(filter);
}
@Override
protected void onPostExecute(List<Object> result) {
if (!isCancelled() && isVisible()) {
poiFitlersAdapter.setResult(result);
}
}
}
class PoiFiltersAdapter extends ArrayAdapter<Object> {
PoiFiltersAdapter(List<Object> list) {
super(getActivity(), R.layout.searchpoifolder_list, list);
}
public void setResult(List<Object> filters) {
setNotifyOnChange(false);
clear();
for (Object o : filters) {
add(o);
}
setNotifyOnChange(true);
notifyDataSetInvalidated();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
LayoutInflater inflater = getActivity().getLayoutInflater();
row = inflater.inflate(R.layout.searchpoifolder_list, parent, false);
}
TextView label = (TextView) row.findViewById(R.id.folder_label);
ImageView icon = (ImageView) row.findViewById(R.id.folder_icon);
Object item = getItem(position);
String name;
if (item instanceof PoiUIFilter) {
final PoiUIFilter model = (PoiUIFilter) item;
if (RenderingIcons.containsBigIcon(model.getIconId())) {
icon.setImageDrawable(RenderingIcons.getBigIcon(getActivity(), model.getIconId()));
} else if (PoiUIFilter.BY_NAME_FILTER_ID.equals(model.getFilterId()) ||
model instanceof NominatimPoiFilter) {
icon.setImageResource(R.drawable.mx_name_finder);
} else {
icon.setImageResource(R.drawable.mx_user_defined);
}
name = model.getName();
} else {
AbstractPoiType st = (AbstractPoiType) item;
if (RenderingIcons.containsBigIcon(st.getIconKeyName())) {
icon.setImageDrawable(RenderingIcons.getBigIcon(getActivity(), st.getIconKeyName()));
} else if (st instanceof PoiType
&& RenderingIcons.containsBigIcon(((PoiType) st).getOsmTag() + "_"
+ ((PoiType) st).getOsmValue())) {
icon.setImageResource(RenderingIcons.getBigIconResourceId(((PoiType) st).getOsmTag() + "_"
+ ((PoiType) st).getOsmValue()));
} else {
icon.setImageDrawable(null);
}
name = st.getTranslation();
if (st.isAdditional()) {
name += " (" + ((PoiType) st).getParentType().getTranslation() + ")";
}
}
label.setText(name);
return (row);
}
}
private void showOptionsMenu(View v) {
// Show menu with search all, name finder, name finder poi
IconsCache iconsCache = getMyApplication().getIconsCache();
final PopupMenu optionsMenu = new PopupMenu(getActivity(), v);
MenuItem item = optionsMenu.getMenu().add(R.string.poi_filter_custom_filter)
.setIcon(iconsCache.getThemedIcon(R.drawable.ic_action_filter_dark));
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
PoiUIFilter filter = getApp().getPoiFilters().getCustomPOIFilter();
filter.clearFilter();
showFilterActivity(filter.getFilterId());
return true;
}
});
optionsMenu.show();
}
@Override
public void onCreateOptionsMenu(Menu onCreate, MenuInflater inflater) {
if (getActivity() instanceof SearchActivity) {
((SearchActivity) getActivity()).getClearToolbar(false);
}
}
@Override
public void locationUpdate(LatLon l) {
}
public OsmandApplication getMyApplication() {
return (OsmandApplication) getActivity().getApplication();
}
}