package net.osmand.plus.search;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.AppCompatImageView;
import android.support.v7.widget.AppCompatTextView;
import android.support.v7.widget.SwitchCompat;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.ListView;
import android.widget.TextView;
import net.osmand.osm.PoiCategory;
import net.osmand.osm.PoiType;
import net.osmand.plus.IconsCache;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.OsmandSettings;
import net.osmand.plus.R;
import net.osmand.plus.poi.PoiFiltersHelper;
import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.render.RenderingIcons;
import net.osmand.util.Algorithms;
import java.text.Collator;
import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
public class QuickSearchCustomPoiFragment extends DialogFragment {
public static final String TAG = "QuickSearchCustomPoiFragment";
private static final String QUICK_SEARCH_CUSTOM_POI_FILTER_ID_KEY = "quick_search_custom_poi_filter_id_key";
private View view;
private ListView listView;
private CategoryListAdapter listAdapter;
private String filterId;
private PoiUIFilter filter;
private PoiFiltersHelper helper;
private View bottomBarShadow;
private View bottomBar;
private TextView barTitle;
private TextView barButton;
private boolean editMode;
public QuickSearchCustomPoiFragment() {
}
private OsmandApplication getMyApplication() {
return (OsmandApplication) getActivity().getApplication();
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
boolean isLightTheme = getMyApplication().getSettings().OSMAND_THEME.get() == OsmandSettings.OSMAND_LIGHT_THEME;
int themeId = isLightTheme ? R.style.OsmandLightTheme : R.style.OsmandDarkTheme;
setStyle(STYLE_NO_FRAME, themeId);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final OsmandApplication app = getMyApplication();
helper = app.getPoiFilters();
if (getArguments() != null) {
filterId = getArguments().getString(QUICK_SEARCH_CUSTOM_POI_FILTER_ID_KEY);
} else if (savedInstanceState != null) {
filterId = savedInstanceState.getString(QUICK_SEARCH_CUSTOM_POI_FILTER_ID_KEY);
}
if (filterId != null) {
filter = helper.getFilterById(filterId);
}
if (filter == null) {
filter = helper.getCustomPOIFilter();
filter.clearFilter();
}
editMode = !filterId.equals(helper.getCustomPOIFilter().getFilterId());
view = inflater.inflate(R.layout.search_custom_poi, container, false);
Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
toolbar.setNavigationIcon(app.getIconsCache().getIcon(R.drawable.ic_action_remove_dark));
toolbar.setNavigationContentDescription(R.string.shared_string_close);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
TextView title = (TextView) view.findViewById(R.id.title);
if (editMode) {
title.setText(filter.getName());
}
listView = (ListView) view.findViewById(android.R.id.list);
listView.setBackgroundColor(getResources().getColor(
app.getSettings().isLightContent() ? R.color.ctx_menu_info_view_bg_light
: R.color.ctx_menu_info_view_bg_dark));
View header = getLayoutInflater(savedInstanceState).inflate(R.layout.list_shadow_header, null);
listView.addHeaderView(header, null, false);
View footer = inflater.inflate(R.layout.list_shadow_footer, listView, false);
listView.addFooterView(footer, null, false);
listAdapter = new CategoryListAdapter(app, app.getPoiTypes().getCategories(false));
listView.setAdapter(listAdapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
PoiCategory category = listAdapter.getItem(position - listView.getHeaderViewsCount());
showDialog(category, false);
}
});
bottomBarShadow = view.findViewById(R.id.bottomBarShadow);
bottomBar = view.findViewById(R.id.bottomBar);
barTitle = (TextView) view.findViewById(R.id.barTitle);
barButton = (TextView) view.findViewById(R.id.barButton);
bottomBar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
QuickSearchDialogFragment quickSearchDialogFragment = getQuickSearchDialogFragment();
if (quickSearchDialogFragment != null) {
quickSearchDialogFragment.showFilter(filterId);
}
}
});
return view;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(QUICK_SEARCH_CUSTOM_POI_FILTER_ID_KEY, filterId);
}
@Override
public void onDismiss(DialogInterface dialog) {
if (editMode) {
QuickSearchDialogFragment quickSearchDialogFragment = getQuickSearchDialogFragment();
if (quickSearchDialogFragment != null) {
getMyApplication().getSearchUICore().refreshCustomPoiFilters();
quickSearchDialogFragment.replaceQueryWithUiFilter(filter, "");
quickSearchDialogFragment.reloadCategories();
}
}
super.onDismiss(dialog);
}
private QuickSearchDialogFragment getQuickSearchDialogFragment() {
Fragment parent = getParentFragment();
if (parent instanceof QuickSearchDialogFragment) {
return (QuickSearchDialogFragment) parent;
} else if (parent instanceof QuickSearchPoiFilterFragment
&& parent.getParentFragment() instanceof QuickSearchDialogFragment) {
return (QuickSearchDialogFragment) parent.getParentFragment();
} else {
return null;
}
}
private int getIconId(PoiCategory category) {
OsmandApplication app = getMyApplication();
String id = null;
if (category != null) {
if (RenderingIcons.containsBigIcon(category.getIconKeyName())) {
id = category.getIconKeyName();
}
}
if (id != null) {
return RenderingIcons.getBigIconResourceId(id);
} else {
return 0;
}
}
public static void showDialog(DialogFragment parentFragment, String filterId) {
Bundle bundle = new Bundle();
if (filterId != null) {
bundle.putString(QUICK_SEARCH_CUSTOM_POI_FILTER_ID_KEY, filterId);
}
QuickSearchCustomPoiFragment fragment = new QuickSearchCustomPoiFragment();
fragment.setArguments(bundle);
fragment.show(parentFragment.getChildFragmentManager(), TAG);
}
private class CategoryListAdapter extends ArrayAdapter<PoiCategory> {
private OsmandApplication app;
CategoryListAdapter(OsmandApplication app, List<PoiCategory> items) {
super(app, R.layout.list_item_icon24_and_menu, items);
this.app = app;
}
@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) app.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View row = convertView;
if (row == null) {
row = inflater.inflate(R.layout.list_item_icon24_and_menu, parent, false);
}
PoiCategory category = getItem(position);
if (category != null) {
AppCompatImageView iconView = (AppCompatImageView) row.findViewById(R.id.icon);
AppCompatImageView secondaryIconView = (AppCompatImageView) row.findViewById(R.id.secondary_icon);
AppCompatTextView titleView = (AppCompatTextView) row.findViewById(R.id.title);
AppCompatTextView descView = (AppCompatTextView) row.findViewById(R.id.description);
SwitchCompat check = (SwitchCompat) row.findViewById(R.id.toggle_item);
boolean categorySelected = filter.isTypeAccepted(category);
IconsCache ic = app.getIconsCache();
int iconId = getIconId(category);
if (iconId != 0) {
if (categorySelected) {
iconView.setImageDrawable(ic.getIcon(iconId, R.color.osmand_orange));
} else {
iconView.setImageDrawable(ic.getThemedIcon(iconId));
}
} else {
iconView.setImageDrawable(null);
}
secondaryIconView.setImageDrawable(
ic.getIcon(R.drawable.ic_action_additional_option, app.getSettings().isLightContent() ? R.color.icon_color_light : 0));
check.setOnCheckedChangeListener(null);
check.setChecked(filter.isTypeAccepted(category));
String textString = category.getTranslation();
titleView.setText(textString);
Set<String> subtypes = filter.getAcceptedSubtypes(category);
if (categorySelected) {
if (subtypes == null) {
descView.setText(getString(R.string.shared_string_all));
} else {
StringBuilder sb = new StringBuilder();
for (String st : subtypes) {
if (sb.length() > 0) {
sb.append(", ");
}
sb.append(app.getPoiTypes().getPoiTranslation(st));
}
descView.setText(sb.toString());
}
descView.setVisibility(View.VISIBLE);
} else {
descView.setVisibility(View.GONE);
}
row.findViewById(R.id.divider).setVisibility(position == getCount() - 1 ? View.GONE : View.VISIBLE);
addRowListener(category, check);
}
return (row);
}
private void addRowListener(final PoiCategory category, final SwitchCompat check) {
check.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (check.isChecked()) {
showDialog(category, true);
} else {
filter.setTypeToAccept(category, false);
saveFilter();
notifyDataSetChanged();
}
}
});
}
}
private void saveFilter() {
helper.editPoiFilter(filter);
if (!editMode) {
if (filter.isEmpty()) {
bottomBarShadow.setVisibility(View.GONE);
bottomBar.setVisibility(View.GONE);
} else {
barTitle.setText(getContext().getString(R.string.selected_categories) + ": " + filter.getAcceptedTypesCount());
bottomBarShadow.setVisibility(View.VISIBLE);
bottomBar.setVisibility(View.VISIBLE);
}
}
}
private void showDialog(final PoiCategory poiCategory, boolean selectAll) {
final int index = listView.getFirstVisiblePosition();
View v = listView.getChildAt(0);
final int top = (v == null) ? 0 : v.getTop();
final AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
final LinkedHashMap<String, String> subCategories = new LinkedHashMap<String, String>();
Set<String> acceptedCategories = filter.getAcceptedSubtypes(poiCategory);
if (acceptedCategories != null) {
for(String s : acceptedCategories) {
subCategories.put(s, Algorithms.capitalizeFirstLetterAndLowercase(s));
}
}
for(PoiType pt : poiCategory.getPoiTypes()) {
subCategories.put(pt.getKeyName(), pt.getTranslation());
}
final String[] array = subCategories.keySet().toArray(new String[0]);
final Collator cl = Collator.getInstance();
cl.setStrength(Collator.SECONDARY);
Arrays.sort(array, 0, array.length, new Comparator<String>() {
@Override
public int compare(String object1, String object2) {
String v1 = subCategories.get(object1);
String v2 = subCategories.get(object2);
return cl.compare(v1, v2);
}
});
final String[] visibleNames = new String[array.length];
final boolean[] selected = new boolean[array.length];
boolean allSelected = true;
for (int i = 0; i < array.length; i++) {
final String subcategory = array[i];
visibleNames[i] = subCategories.get(subcategory);
if (acceptedCategories == null || selectAll) {
selected[i] = true;
} else {
if (allSelected) {
allSelected = false;
}
selected[i] = acceptedCategories.contains(subcategory);
}
}
View titleView = LayoutInflater.from(getActivity())
.inflate(R.layout.subcategories_dialog_title, null);
TextView titleTextView = (TextView) titleView.findViewById(R.id.title);
titleTextView.setText(poiCategory.getTranslation());
SwitchCompat check = (SwitchCompat) titleView.findViewById(R.id.check);
check.setChecked(allSelected);
builder.setCustomTitle(titleView);
builder.setCancelable(true);
builder.setNegativeButton(getContext().getText(R.string.shared_string_cancel), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
listAdapter.notifyDataSetChanged();
}
});
builder.setPositiveButton(getContext().getText(R.string.shared_string_apply), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
LinkedHashSet<String> accepted = new LinkedHashSet<String>();
for (int i = 0; i < selected.length; i++) {
if(selected[i]){
accepted.add(array[i]);
}
}
if (subCategories.size() == accepted.size()) {
filter.selectSubTypesToAccept(poiCategory, null);
} else if(accepted.size() == 0){
filter.setTypeToAccept(poiCategory, false);
} else {
filter.selectSubTypesToAccept(poiCategory, accepted);
}
saveFilter();
listAdapter.notifyDataSetChanged();
listView.setSelectionFromTop(index, top);
}
});
builder.setMultiChoiceItems(visibleNames, selected, new DialogInterface.OnMultiChoiceClickListener() {
@Override
public void onClick(DialogInterface dialog, int item, boolean isChecked) {
selected[item] = isChecked;
}
});
final AlertDialog dialog = builder.show();
check.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
Arrays.fill(selected, true);
} else {
Arrays.fill(selected, false);
}
for (int i = 0; i < selected.length; i++) {
dialog.getListView().setItemChecked(i, selected[i]);
}
}
});
}
}