package net.osmand.plus.helpers;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.Shape;
import android.os.AsyncTask;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.PopupMenu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import net.osmand.AndroidUtils;
import net.osmand.Location;
import net.osmand.TspAnt;
import net.osmand.data.FavouritePoint;
import net.osmand.data.LatLon;
import net.osmand.data.LocationPoint;
import net.osmand.data.PointDescription;
import net.osmand.plus.GeocodingLookupService;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.TargetPointsHelper;
import net.osmand.plus.TargetPointsHelper.TargetPoint;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.activities.MapActivityLayers;
import net.osmand.plus.dialogs.DirectionsDialogs;
import net.osmand.plus.helpers.WaypointHelper.LocationPointWrapper;
import net.osmand.plus.poi.PoiUIFilter;
import net.osmand.plus.views.controls.DynamicListView.DragIcon;
import net.osmand.plus.views.controls.ListDividerShape;
import net.osmand.plus.views.controls.StableArrayAdapter;
import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
import java.util.ArrayList;
import java.util.List;
/**
*/
public class WaypointDialogHelper {
private MapActivity mapActivity;
private OsmandApplication app;
private WaypointHelper waypointHelper;
private WaypointDialogHelperCallbacks helperCallbacks;
private boolean flat;
private List<LocationPointWrapper> deletedPoints;
public interface WaypointDialogHelperCallbacks {
void reloadAdapter();
void deleteWaypoint(int position);
void exchangeWaypoints(int pos1, int pos2);
}
private static class RadiusItem {
int type;
public RadiusItem(int type) {
this.type = type;
}
}
public void setHelperCallbacks(WaypointDialogHelperCallbacks callbacks) {
this.helperCallbacks = callbacks;
}
public WaypointDialogHelper(MapActivity mapActivity) {
this.app = mapActivity.getMyApplication();
waypointHelper = this.app.getWaypointHelper();
this.mapActivity = mapActivity;
}
public static void updatePointInfoView(final OsmandApplication app, final Activity activity,
View localView, final LocationPointWrapper ps,
final boolean mapCenter, final boolean nightMode,
final boolean edit, final boolean topBar) {
WaypointHelper wh = app.getWaypointHelper();
final LocationPoint point = ps.getPoint();
TextView text = (TextView) localView.findViewById(R.id.waypoint_text);
if (!topBar) {
AndroidUtils.setTextPrimaryColor(activity, text, nightMode);
}
TextView textShadow = (TextView) localView.findViewById(R.id.waypoint_text_shadow);
if (!edit) {
localView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showOnMap(app, activity, point, mapCenter);
}
});
}
TextView textDist = (TextView) localView.findViewById(R.id.waypoint_dist);
((ImageView) localView.findViewById(R.id.waypoint_icon)).setImageDrawable(ps.getDrawable(activity, app, nightMode));
int dist = -1;
boolean startPoint = ps.type == WaypointHelper.TARGETS && ((TargetPoint) ps.point).start;
if (!startPoint) {
if (!wh.isRouteCalculated()) {
if (activity instanceof MapActivity) {
dist = (int) MapUtils.getDistance(((MapActivity) activity).getMapView().getLatitude(), ((MapActivity) activity)
.getMapView().getLongitude(), point.getLatitude(), point.getLongitude());
}
} else {
dist = wh.getRouteDistance(ps);
}
}
if (dist > 0) {
textDist.setText(OsmAndFormatter.getFormattedDistance(dist, app));
} else {
textDist.setText("");
}
TextView textDeviation = (TextView) localView.findViewById(R.id.waypoint_deviation);
if (textDeviation != null) {
if (dist > 0 && ps.deviationDistance > 0) {
String devStr = "+" + OsmAndFormatter.getFormattedDistance(ps.deviationDistance, app);
textDeviation.setText(devStr);
if (!topBar) {
int colorId = nightMode ? R.color.secondary_text_dark : R.color.secondary_text_light;
AndroidUtils.setTextSecondaryColor(activity, textDeviation, nightMode);
if (ps.deviationDirectionRight) {
textDeviation.setCompoundDrawablesWithIntrinsicBounds(
app.getIconsCache().getIcon(R.drawable.ic_small_turn_right, colorId),
null, null, null);
} else {
textDeviation.setCompoundDrawablesWithIntrinsicBounds(
app.getIconsCache().getIcon(R.drawable.ic_small_turn_left, colorId),
null, null, null);
}
}
textDeviation.setVisibility(View.VISIBLE);
} else {
textDeviation.setText("");
textDeviation.setVisibility(View.GONE);
}
}
String descr;
PointDescription pd = point.getPointDescription(app);
if (Algorithms.isEmpty(pd.getName())) {
descr = pd.getTypeName();
} else {
descr = pd.getName();
}
if (textShadow != null) {
textShadow.setText(descr);
}
text.setText(descr);
String pointDescription = "";
TextView descText = (TextView) localView.findViewById(R.id.waypoint_desc_text);
if (descText != null) {
AndroidUtils.setTextSecondaryColor(activity, descText, nightMode);
switch (ps.type) {
case WaypointHelper.TARGETS:
TargetPoint targetPoint = (TargetPoint) ps.point;
if (targetPoint.start) {
pointDescription = activity.getResources().getString(R.string.starting_point);
} else {
pointDescription = targetPoint.getPointDescription(activity).getTypeName();
}
break;
case WaypointHelper.FAVORITES:
FavouritePoint favPoint = (FavouritePoint) ps.point;
pointDescription = Algorithms.isEmpty(favPoint.getCategory()) ? activity.getResources().getString(R.string.shared_string_favorites) : favPoint.getCategory();
break;
}
}
if (Algorithms.objectEquals(descr, pointDescription)) {
pointDescription = "";
}
if (dist > 0 && !Algorithms.isEmpty(pointDescription)) {
pointDescription = " • " + pointDescription;
}
if (descText != null) {
descText.setText(pointDescription);
}
}
private List<Object> getPoints() {
final List<Object> points;
if (flat) {
points = new ArrayList<Object>(waypointHelper.getAllPoints());
} else {
points = getStandardPoints();
}
return points;
}
private List<Object> getActivePoints(List<Object> points) {
List<Object> activePoints = new ArrayList<>();
for (Object p : points) {
if (p instanceof LocationPointWrapper) {
LocationPointWrapper w = (LocationPointWrapper) p;
if (w.type == WaypointHelper.TARGETS && !((TargetPoint) w.point).start) {
activePoints.add(p);
}
}
}
return activePoints;
}
private List<Drawable> getCustomDividers(Context ctx, List<Object> points, boolean nightMode) {
int color;
int pointColor;
if (nightMode) {
color = ContextCompat.getColor(ctx, R.color.dashboard_divider_dark);
pointColor = ContextCompat.getColor(ctx, R.color.dashboard_divider_dark);
} else {
color = ContextCompat.getColor(ctx, R.color.dashboard_divider_light);
pointColor = ContextCompat.getColor(ctx, R.color.ctx_menu_info_divider_light);
}
Shape fullDividerShape = new ListDividerShape(color, 0);
Shape halfDividerShape = new ListDividerShape(color, AndroidUtils.dpToPx(ctx, 56f));
Shape halfPointDividerShape = new ListDividerShape(color, AndroidUtils.dpToPx(ctx, 56f),
pointColor, AndroidUtils.dpToPx(ctx, 1.5f), true);
Shape headerDividerShape = new ListDividerShape(color, AndroidUtils.dpToPx(ctx, 16f));
final ShapeDrawable fullDivider = new ShapeDrawable(fullDividerShape);
final ShapeDrawable halfDivider = new ShapeDrawable(halfDividerShape);
final ShapeDrawable halfPointDivider = new ShapeDrawable(halfPointDividerShape);
final ShapeDrawable headerDivider = new ShapeDrawable(headerDividerShape);
final Drawable startingPointDivider = app.getIconsCache().getIcon(R.drawable.bg_shadow_list_bottom);
int divHeight = AndroidUtils.dpToPx(ctx, 1f);
fullDivider.setIntrinsicHeight(divHeight);
halfDivider.setIntrinsicHeight(divHeight);
halfPointDivider.setIntrinsicHeight(divHeight);
headerDivider.setIntrinsicHeight(divHeight);
List<Drawable> res = new ArrayList<>();
for (int i = 0; i < points.size(); i++) {
Object obj = points.get(i);
Object objNext = i + 1 < points.size() ? points.get(i + 1) : null;
if (objNext == null) {
break;
}
boolean labelView = (obj instanceof Integer);
boolean bottomDividerViewNext = (objNext instanceof Boolean) && !((Boolean) objNext);
boolean locationPoint = (obj instanceof LocationPointWrapper);
boolean locationPointNext = (objNext instanceof LocationPointWrapper);
Drawable d = null;
if (locationPointNext) {
if (locationPoint) {
LocationPointWrapper w = (LocationPointWrapper) obj;
if (w.type == WaypointHelper.TARGETS && ((TargetPoint) w.point).start) {
d = startingPointDivider; // starting point divider
} else {
if (w.type == WaypointHelper.TARGETS) {
d = halfPointDivider;
} else {
d = halfDivider;
}
}
} else {
LocationPointWrapper w = (LocationPointWrapper) objNext;
if (w.type == WaypointHelper.TARGETS) {
if (!((TargetPoint) w.point).start) {
d = fullDivider;
}
} else {
d = fullDivider;
}
}
} else if (objNext instanceof RadiusItem && labelView) {
d = headerDivider;
} else if (locationPoint && !bottomDividerViewNext) {
d = fullDivider;
}
res.add(d);
}
return res;
}
public StableArrayAdapter getWaypointsDrawerAdapter(
final boolean edit, final List<LocationPointWrapper> deletedPoints,
final MapActivity ctx, final int[] running, final boolean flat, final boolean nightMode) {
this.flat = flat;
this.deletedPoints = deletedPoints;
final List<Object> points = getPoints();
List<Object> activePoints = getActivePoints(points);
final WaypointDialogHelper helper = this;
final StableArrayAdapter listAdapter = new StableArrayAdapter(ctx,
R.layout.waypoint_reached, R.id.title, points, activePoints) {
@Override
public void buildDividers() {
dividers = getCustomDividers(ctx, getObjects(), nightMode);
}
@Override
public boolean isEnabled(int position) {
Object obj = getItem(position);
boolean labelView = (obj instanceof Integer);
boolean topDividerView = (obj instanceof Boolean) && ((Boolean) obj);
boolean bottomDividerView = (obj instanceof Boolean) && !((Boolean) obj);
boolean enabled = !labelView && !topDividerView && !bottomDividerView;
if (enabled && obj instanceof RadiusItem) {
int type = ((RadiusItem) obj).type;
enabled = type != WaypointHelper.POI;
}
return enabled;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
// User super class to create the View
View v = convertView;
final ArrayAdapter<Object> thisAdapter = this;
Object obj = getItem(position);
boolean labelView = (obj instanceof Integer);
boolean topDividerView = (obj instanceof Boolean) && ((Boolean) obj);
boolean bottomDividerView = (obj instanceof Boolean) && !((Boolean) obj);
if (obj instanceof RadiusItem) {
final int type = ((RadiusItem) obj).type;
v = createItemForRadiusProximity(ctx, type, running, position, thisAdapter, nightMode);
//Drawable d = new ColorDrawable(mapActivity.getResources().getColor(R.color.dashboard_divider_light));
AndroidUtils.setListItemBackground(mapActivity, v, nightMode);
} else if (labelView) {
v = createItemForCategory(ctx, (Integer) obj, running, position, thisAdapter, nightMode);
AndroidUtils.setListItemBackground(mapActivity, v, nightMode);
} else if (topDividerView) {
v = ctx.getLayoutInflater().inflate(R.layout.card_top_divider, null);
AndroidUtils.setListBackground(mapActivity, v, nightMode);
} else if (bottomDividerView) {
v = ctx.getLayoutInflater().inflate(R.layout.card_bottom_divider, null);
AndroidUtils.setListBackground(mapActivity, v, nightMode);
} else if (obj instanceof LocationPointWrapper) {
LocationPointWrapper point = (LocationPointWrapper) obj;
v = updateWaypointItemView(edit, deletedPoints, app, ctx, helper, v, point, this,
nightMode, flat);
AndroidUtils.setListItemBackground(mapActivity, v, nightMode);
}
return v;
}
};
for (Object p : points) {
if (p instanceof LocationPointWrapper) {
LocationPointWrapper w = (LocationPointWrapper) p;
if (w.type == WaypointHelper.TARGETS) {
final TargetPoint t = (TargetPoint) w.point;
if (t.getOriginalPointDescription() != null
&& t.getOriginalPointDescription().isSearchingAddress(mapActivity)) {
GeocodingLookupService.AddressLookupRequest lookupRequest
= new GeocodingLookupService.AddressLookupRequest(t.point, new GeocodingLookupService.OnAddressLookupResult() {
@Override
public void geocodingDone(String address) {
if (helperCallbacks != null) {
helperCallbacks.reloadAdapter();
} else {
reloadListAdapter(listAdapter);
}
//updateRouteInfoMenu(ctx);
}
}, null);
app.getGeocodingLookupService().lookupAddress(lookupRequest);
}
}
}
}
return listAdapter;
}
public static View updateWaypointItemView(final boolean edit, final List<LocationPointWrapper> deletedPoints,
final OsmandApplication app, final Activity ctx,
final WaypointDialogHelper helper, View v,
final LocationPointWrapper point,
final ArrayAdapter adapter, final boolean nightMode,
final boolean flat) {
if (v == null || v.findViewById(R.id.info_close) == null) {
v = ctx.getLayoutInflater().inflate(R.layout.waypoint_reached, null);
}
updatePointInfoView(app, ctx, v, point, true, nightMode, edit, false);
final View more = v.findViewById(R.id.all_points);
final View move = v.findViewById(R.id.info_move);
final View remove = v.findViewById(R.id.info_close);
if (!edit) {
remove.setVisibility(View.GONE);
move.setVisibility(View.GONE);
more.setVisibility(View.GONE);
} else if (point.type == WaypointHelper.TARGETS && !flat) {
if (((TargetPoint) point.point).start) {
remove.setVisibility(View.GONE);
move.setVisibility(View.GONE);
more.setVisibility(View.VISIBLE);
((ImageButton) more).setImageDrawable(app.getIconsCache().getIcon(
R.drawable.map_overflow_menu_white, !nightMode));
more.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
boolean hasActivePoints = false;
if (adapter instanceof StableArrayAdapter) {
hasActivePoints = ((StableArrayAdapter) adapter).getActiveObjects().size() > 0;
}
final PopupMenu optionsMenu = new PopupMenu(ctx, more);
DirectionsDialogs.setupPopUpMenuIcon(optionsMenu);
final TargetPointsHelper targetPointsHelper = app.getTargetPointsHelper();
final TargetPoint start = targetPointsHelper.getPointToStart();
final TargetPoint finish = targetPointsHelper.getPointToNavigate();
MenuItem item;
if (hasActivePoints) {
item = optionsMenu.getMenu().add(
R.string.intermediate_items_sort_by_distance).setIcon(app.getIconsCache().
getThemedIcon(R.drawable.ic_sort_waypoint_dark));
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
// sort door-to-door
sortAllTargets(app, ctx, helper);
return true;
}
});
item = optionsMenu.getMenu().add(
R.string.switch_start_finish).setIcon(app.getIconsCache().
getThemedIcon(R.drawable.ic_action_undo_dark));
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switchStartAndFinish(targetPointsHelper, finish, ctx, start, app, helper);
return true;
}
});
if (start != null) {
if (targetPointsHelper.getIntermediatePoints().size() > 0) {
item = optionsMenu.getMenu().add(R.string.shared_string_move_down)
.setIcon(app.getIconsCache().getThemedIcon(R.drawable.ic_action_arrow_drop_down));
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switchStartAndFirstIntermediate(targetPointsHelper, ctx, start, helper);
return true;
}
});
}
item = optionsMenu.getMenu().add(R.string.shared_string_remove)
.setIcon(app.getIconsCache().getThemedIcon(R.drawable.ic_action_remove_dark));
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
targetPointsHelper.setStartPoint(null, true, null);
updateControls(ctx, helper);
return true;
}
});
}
}
if (optionsMenu.getMenu().size() > 0) {
optionsMenu.show();
}
}
});
} else {
remove.setVisibility(View.GONE);
move.setVisibility(View.VISIBLE);
more.setVisibility(View.GONE);
((ImageView) move).setImageDrawable(app.getIconsCache().getIcon(
R.drawable.ic_action_reorder, !nightMode));
if (app.accessibilityEnabled()) {
move.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
((DragIcon) view.getTag()).onClick();
}
});
}
move.setTag(new DragIcon() {
@Override
public void onClick() {
final PopupMenu optionsMenu = new PopupMenu(ctx, move);
DirectionsDialogs.setupPopUpMenuIcon(optionsMenu);
List<Object> activeObjects = ((StableArrayAdapter) adapter).getActiveObjects();
int count = activeObjects.size();
int t = -1;
for (int i = 0; i < activeObjects.size(); i++) {
Object o = activeObjects.get(i);
if (point == o) {
t = i;
break;
}
}
final int index = t;
MenuItem item;
final TargetPointsHelper targetPointsHelper = app.getTargetPointsHelper();
final TargetPoint start = targetPointsHelper.getPointToStart();
if (count > 1 && (index > 0 || start != null)) {
item = optionsMenu.getMenu().add(R.string.shared_string_move_up)
.setIcon(app.getIconsCache().getThemedIcon(R.drawable.ic_action_arrow_drop_up));
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
if (index == 0) {
switchStartAndFirstIntermediate(targetPointsHelper, ctx, start, helper);
} else if (helper != null && helper.helperCallbacks != null) {
helper.helperCallbacks.exchangeWaypoints(index, index - 1);
}
updateRouteInfoMenu(ctx);
return true;
}
});
}
if (index < count - 1 && count > 1) {
item = optionsMenu.getMenu().add(R.string.shared_string_move_down)
.setIcon(app.getIconsCache().getThemedIcon(R.drawable.ic_action_arrow_drop_down));
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
if (helper != null && helper.helperCallbacks != null) {
helper.helperCallbacks.exchangeWaypoints(index, index + 1);
}
updateRouteInfoMenu(ctx);
return true;
}
});
}
item = optionsMenu.getMenu().add(R.string.shared_string_remove)
.setIcon(app.getIconsCache().getThemedIcon(R.drawable.ic_action_remove_dark));
item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
deletePoint(app, ctx, adapter, helper, point, deletedPoints, true);
return true;
}
});
optionsMenu.show();
}
});
}
} else {
remove.setVisibility(View.VISIBLE);
move.setVisibility(View.GONE);
more.setVisibility(View.GONE);
((ImageButton) remove).setImageDrawable(app.getIconsCache().getIcon(
R.drawable.ic_action_remove_dark, !nightMode));
remove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
deletePoint(app, ctx, adapter, helper, point, deletedPoints, true);
}
});
}
return v;
}
private static void updateRouteInfoMenu(Activity ctx) {
if (ctx instanceof MapActivity) {
((MapActivity) ctx).getMapLayers().getMapControlsLayer().getMapRouteInfoMenu().updateMenu();
}
}
// switch start & finish
private static void switchStartAndFinish(TargetPointsHelper targetPointsHelper, TargetPoint finish,
Activity ctx, TargetPoint start, OsmandApplication app,
WaypointDialogHelper helper) {
targetPointsHelper.setStartPoint(new LatLon(finish.getLatitude(),
finish.getLongitude()), false, finish.getPointDescription(ctx));
if (start == null) {
Location loc = app.getLocationProvider().getLastKnownLocation();
if (loc != null) {
targetPointsHelper.navigateToPoint(new LatLon(loc.getLatitude(),
loc.getLongitude()), true, -1);
}
} else {
targetPointsHelper.navigateToPoint(new LatLon(start.getLatitude(),
start.getLongitude()), true, -1, start.getPointDescription(ctx));
}
updateControls(ctx, helper);
}
private static void updateControls(Activity ctx, WaypointDialogHelper helper) {
if (helper != null && helper.helperCallbacks != null) {
helper.helperCallbacks.reloadAdapter();
}
updateRouteInfoMenu(ctx);
}
// switch start & first intermediate point
private static void switchStartAndFirstIntermediate(TargetPointsHelper targetPointsHelper, Activity ctx,
TargetPoint start, WaypointDialogHelper helper) {
List<TargetPoint> intermediatePoints = targetPointsHelper.getIntermediatePointsWithTarget();
TargetPoint firstIntermediate = intermediatePoints.remove(0);
targetPointsHelper.setStartPoint(new LatLon(firstIntermediate.getLatitude(),
firstIntermediate.getLongitude()), false, firstIntermediate.getPointDescription(ctx));
TargetPoint destination = new TargetPoint(new LatLon(start.getLatitude(),
start.getLongitude()), start.getPointDescription(ctx));
intermediatePoints.add(0, destination);
targetPointsHelper.reorderAllTargetPoints(intermediatePoints, true);
updateControls(ctx, helper);
}
public static void deletePoint(final OsmandApplication app, Activity ctx,
final ArrayAdapter adapter,
final WaypointDialogHelper helper,
final Object item,
final List<LocationPointWrapper> deletedPoints,
final boolean needCallback) {
if (item instanceof LocationPointWrapper && adapter != null) {
LocationPointWrapper point = (LocationPointWrapper) item;
if (point.type == WaypointHelper.TARGETS && adapter instanceof StableArrayAdapter) {
StableArrayAdapter stableAdapter = (StableArrayAdapter) adapter;
if (helper != null && helper.helperCallbacks != null && needCallback) {
helper.helperCallbacks.deleteWaypoint(stableAdapter.getPosition(item));
}
updateRouteInfoMenu(ctx);
} else {
ArrayList<LocationPointWrapper> arr = new ArrayList<>();
arr.add(point);
app.getWaypointHelper().removeVisibleLocationPoint(arr);
deletedPoints.add(point);
adapter.setNotifyOnChange(false);
adapter.remove(point);
if (adapter instanceof StableArrayAdapter) {
StableArrayAdapter stableAdapter = (StableArrayAdapter) adapter;
stableAdapter.getObjects().remove(item);
stableAdapter.refreshData();
}
adapter.notifyDataSetChanged();
}
}
}
protected View createItemForRadiusProximity(final FragmentActivity ctx, final int type, final int[] running,
final int position, final ArrayAdapter<Object> thisAdapter, boolean nightMode) {
View v;
if (type == WaypointHelper.POI) {
v = ctx.getLayoutInflater().inflate(R.layout.drawer_list_radius_ex, null);
AndroidUtils.setTextPrimaryColor(mapActivity, (TextView) v.findViewById(R.id.titleEx), nightMode);
String descEx = app.getPoiFilters().isShowingAnyPoi() ? ctx.getString(R.string.poi) : app.getPoiFilters().getSelectedPoiFiltersName();
((TextView) v.findViewById(R.id.title)).setText(ctx.getString(R.string.search_radius_proximity) + ":");
((TextView) v.findViewById(R.id.titleEx)).setText(ctx.getString(R.string.shared_string_type) + ":");
final TextView radiusEx = (TextView) v.findViewById(R.id.descriptionEx);
radiusEx.setText(descEx);
v.findViewById(R.id.secondCellContainer).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
running[0] = position;
thisAdapter.notifyDataSetInvalidated();
MapActivity map = (MapActivity) ctx;
map.getMapLayers().showSingleChoicePoiFilterDialog(map.getMapView(),
new MapActivityLayers.DismissListener() {
@Override
public void dismiss() {
enableType(running, thisAdapter, type, true);
}
});
}
});
AndroidUtils.setTextPrimaryColor(mapActivity, (TextView) v.findViewById(R.id.title), nightMode);
final TextView radius = (TextView) v.findViewById(R.id.description);
radius.setText(OsmAndFormatter.getFormattedDistance(waypointHelper.getSearchDeviationRadius(type), app));
v.findViewById(R.id.firstCellContainer).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
selectDifferentRadius(type, running, position, thisAdapter, mapActivity);
}
});
} else {
v = ctx.getLayoutInflater().inflate(R.layout.drawer_list_radius, null);
((TextView) v.findViewById(R.id.title)).setText(ctx.getString(R.string.search_radius_proximity));
AndroidUtils.setTextPrimaryColor(mapActivity, (TextView) v.findViewById(R.id.title), nightMode);
final TextView radius = (TextView) v.findViewById(R.id.description);
radius.setText(OsmAndFormatter.getFormattedDistance(waypointHelper.getSearchDeviationRadius(type), app));
radius.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
selectDifferentRadius(type, running, position, thisAdapter, mapActivity);
}
});
}
return v;
}
protected View createItemForCategory(final FragmentActivity ctx, final int type, final int[] running,
final int position, final ArrayAdapter<Object> thisAdapter, boolean nightMode) {
View v;
v = ctx.getLayoutInflater().inflate(R.layout.waypoint_header, null);
final CompoundButton btn = (CompoundButton) v.findViewById(R.id.toggle_item);
btn.setVisibility(waypointHelper.isTypeConfigurable(type) ? View.VISIBLE : View.GONE);
btn.setOnCheckedChangeListener(null);
final boolean checked = waypointHelper.isTypeEnabled(type);
btn.setChecked(checked);
btn.setEnabled(running[0] == -1);
v.findViewById(R.id.ProgressBar).setVisibility(position == running[0] ? View.VISIBLE : View.GONE);
btn.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
running[0] = position;
thisAdapter.notifyDataSetInvalidated();
if (type == WaypointHelper.POI && isChecked) {
selectPoi(running, thisAdapter, type, isChecked, ctx);
} else {
enableType(running, thisAdapter, type, isChecked);
}
}
});
TextView tv = (TextView) v.findViewById(R.id.header_text);
AndroidUtils.setTextPrimaryColor(mapActivity, tv, nightMode);
tv.setText(getHeader(type, checked, ctx));
return v;
}
private void selectPoi(final int[] running, final ArrayAdapter<Object> listAdapter, final int type,
final boolean enable, Activity ctx) {
if (ctx instanceof MapActivity &&
!app.getPoiFilters().isPoiFilterSelected(PoiUIFilter.CUSTOM_FILTER_ID)) {
MapActivity map = (MapActivity) ctx;
map.getMapLayers().showSingleChoicePoiFilterDialog(map.getMapView(),
new MapActivityLayers.DismissListener() {
@Override
public void dismiss() {
if (app.getPoiFilters().isShowingAnyPoi()) {
enableType(running, listAdapter, type, enable);
}
}
});
} else {
enableType(running, listAdapter, type, enable);
}
}
private void enableType(final int[] running, final ArrayAdapter<Object> listAdapter, final int type,
final boolean enable) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
app.getWaypointHelper().enableWaypointType(type, enable);
return null;
}
protected void onPostExecute(Void result) {
running[0] = -1;
if (helperCallbacks != null) {
helperCallbacks.reloadAdapter();
} else {
reloadListAdapter(listAdapter);
}
}
}.execute((Void) null);
}
public AdapterView.OnItemClickListener getDrawerItemClickListener(final FragmentActivity ctx, final int[] running,
final ArrayAdapter<Object> listAdapter) {
return new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int item, long l) {
if (listAdapter.getItem(item) instanceof LocationPointWrapper) {
LocationPointWrapper ps = (LocationPointWrapper) listAdapter.getItem(item);
showOnMap(app, ctx, ps.getPoint(), false);
// } else if (new Integer(WaypointHelper.TARGETS).equals(listAdapter.getItem(item))) {
// IntermediatePointsDialog.openIntermediatePointsDialog(ctx, app, true);
} else if (listAdapter.getItem(item) instanceof RadiusItem) {
selectDifferentRadius(((RadiusItem) listAdapter.getItem(item)).type, running, item, listAdapter,
ctx);
}
}
};
}
protected void selectDifferentRadius(final int type, final int[] running, final int position,
final ArrayAdapter<Object> thisAdapter, Activity ctx) {
int length = WaypointHelper.SEARCH_RADIUS_VALUES.length;
String[] names = new String[length];
int selected = 0;
for (int i = 0; i < length; i++) {
names[i] = OsmAndFormatter.getFormattedDistance(WaypointHelper.SEARCH_RADIUS_VALUES[i], app);
if (WaypointHelper.SEARCH_RADIUS_VALUES[i] == waypointHelper.getSearchDeviationRadius(type)) {
selected = i;
}
}
new AlertDialog.Builder(ctx)
.setSingleChoiceItems(names, selected, new OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
int value = WaypointHelper.SEARCH_RADIUS_VALUES[i];
if (waypointHelper.getSearchDeviationRadius(type) != value) {
running[0] = position;
waypointHelper.setSearchDeviationRadius(type, value);
recalculatePoints(running, thisAdapter, type);
dialogInterface.dismiss();
thisAdapter.notifyDataSetInvalidated();
}
}
}).setTitle(app.getString(R.string.search_radius_proximity))
.setNegativeButton(R.string.shared_string_cancel, null)
.show();
}
private void recalculatePoints(final int[] running, final ArrayAdapter<Object> listAdapter, final int type) {
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
app.getWaypointHelper().recalculatePoints(type);
return null;
}
protected void onPostExecute(Void result) {
running[0] = -1;
if (helperCallbacks != null) {
helperCallbacks.reloadAdapter();
} else {
reloadListAdapter(listAdapter);
}
}
}.execute((Void) null);
}
public void reloadListAdapter(ArrayAdapter<Object> listAdapter) {
mapActivity.getMyApplication().getWaypointHelper().removeVisibleLocationPoint(deletedPoints);
listAdapter.setNotifyOnChange(false);
listAdapter.clear();
List<Object> points = getPoints();
for (Object point : points) {
listAdapter.add(point);
}
if (listAdapter instanceof StableArrayAdapter) {
((StableArrayAdapter) listAdapter).updateObjects(points, getActivePoints(points));
}
listAdapter.notifyDataSetChanged();
}
protected String getHeader(int type, boolean checked, Activity ctx) {
String str = ctx.getString(R.string.waypoints);
switch (type) {
case WaypointHelper.TARGETS:
str = ctx.getString(R.string.targets);
break;
case WaypointHelper.ALARMS:
str = ctx.getString(R.string.way_alarms);
break;
case WaypointHelper.FAVORITES:
str = ctx.getString(R.string.shared_string_my_favorites);
break;
case WaypointHelper.WAYPOINTS:
str = ctx.getString(R.string.waypoints);
break;
case WaypointHelper.POI:
str = ctx.getString(R.string.poi);
break;
}
return str;
}
protected List<Object> getStandardPoints() {
final List<Object> points = new ArrayList<>();
boolean rc = waypointHelper.isRouteCalculated();
for (int i = 0; i < WaypointHelper.MAX; i++) {
List<LocationPointWrapper> tp = waypointHelper.getWaypoints(i);
if ((rc || i == WaypointHelper.WAYPOINTS || i == WaypointHelper.TARGETS)
&& waypointHelper.isTypeVisible(i)) {
if (points.size() > 0) {
points.add(true);
}
points.add(i);
if (i == WaypointHelper.TARGETS) {
TargetPoint start = app.getTargetPointsHelper().getPointToStart();
if (start == null) {
LatLon latLon;
Location loc = app.getLocationProvider().getLastKnownLocation();
if (loc != null) {
latLon = new LatLon(loc.getLatitude(), loc.getLongitude());
} else {
latLon = new LatLon(mapActivity.getMapView().getLatitude(),
mapActivity.getMapView().getLongitude());
}
start = TargetPoint.createStartPoint(latLon,
new PointDescription(PointDescription.POINT_TYPE_MY_LOCATION,
mapActivity.getString(R.string.shared_string_my_location)));
} else {
String oname = start.getOnlyName().length() > 0 ? start.getOnlyName()
: (mapActivity.getString(R.string.route_descr_map_location)
+ " " + mapActivity.getString(R.string.route_descr_lat_lon, start.getLatitude(), start.getLongitude()));
start = TargetPoint.createStartPoint(new LatLon(start.getLatitude(), start.getLongitude()),
new PointDescription(PointDescription.POINT_TYPE_LOCATION,
oname));
}
points.add(new LocationPointWrapper(null, WaypointHelper.TARGETS, start, 0f, 0));
} else if ((i == WaypointHelper.POI || i == WaypointHelper.FAVORITES || i == WaypointHelper.WAYPOINTS)
&& rc) {
if (waypointHelper.isTypeEnabled(i)) {
points.add(new RadiusItem(i));
}
}
if (tp != null && tp.size() > 0) {
points.addAll(tp);
}
points.add(false);
}
}
return points;
}
public static void showOnMap(OsmandApplication app, Activity a, LocationPoint locationPoint, boolean center) {
if (!(a instanceof MapActivity)) {
return;
}
app.getSettings().setMapLocationToShow(locationPoint.getLatitude(), locationPoint.getLongitude(),
15, locationPoint.getPointDescription(a), false, locationPoint);
MapActivity.launchMapActivityMoveToTop(a);
}
public static void sortAllTargets(final OsmandApplication app, final Activity activity,
final WaypointDialogHelper helper) {
new AsyncTask<Void, Void, int[]>() {
ProgressDialog dlg = null;
long startDialogTime = 0;
List<TargetPoint> intermediates;
protected void onPreExecute() {
startDialogTime = System.currentTimeMillis();
dlg = new ProgressDialog(activity);
dlg.setTitle("");
dlg.setMessage(activity.getResources().getString(R.string.intermediate_items_sort_by_distance));
dlg.show();
}
protected int[] doInBackground(Void[] params) {
TargetPointsHelper targets = app.getTargetPointsHelper();
intermediates = targets.getIntermediatePointsWithTarget();
Location cll = app.getLocationProvider().getLastKnownLocation();
ArrayList<TargetPoint> lt = new ArrayList<>(intermediates);
TargetPoint start;
if (cll != null) {
LatLon ll = new LatLon(cll.getLatitude(), cll.getLongitude());
start = TargetPoint.create(ll, null);
} else if (app.getTargetPointsHelper().getPointToStart() != null) {
TargetPoint ps = app.getTargetPointsHelper().getPointToStart();
LatLon ll = new LatLon(ps.getLatitude(), ps.getLongitude());
start = TargetPoint.create(ll, null);
} else {
start = lt.get(0);
}
TargetPoint end = lt.remove(lt.size() - 1);
ArrayList<LatLon> al = new ArrayList<>();
for (TargetPoint p : lt) {
al.add(p.point);
}
return new TspAnt().readGraph(al, start.point, end.point).solve();
}
protected void onPostExecute(int[] result) {
if (dlg != null) {
long t = System.currentTimeMillis();
if (t - startDialogTime < 500) {
app.runInUIThread(new Runnable() {
@Override
public void run() {
dlg.dismiss();
}
}, 500 - (t - startDialogTime));
} else {
dlg.dismiss();
}
}
List<TargetPoint> alocs = new ArrayList<>();
for (int i : result) {
if (i > 0) {
TargetPoint loc = intermediates.get(i - 1);
alocs.add(loc);
}
}
intermediates.clear();
intermediates.addAll(alocs);
TargetPointsHelper targets = app.getTargetPointsHelper();
List<TargetPoint> cur = targets.getIntermediatePointsWithTarget();
boolean eq = true;
for (int j = 0; j < cur.size() && j < intermediates.size(); j++) {
if (cur.get(j) != intermediates.get(j)) {
eq = false;
break;
}
}
if (!eq) {
targets.reorderAllTargetPoints(intermediates, true);
}
if (helper.helperCallbacks != null) {
helper.helperCallbacks.reloadAdapter();
}
updateRouteInfoMenu(activity);
}
}.execute();
}
}