package net.osmand.plus.mapcontextmenu.controllers;
import android.view.View;
import net.osmand.data.Amenity;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.data.QuadRect;
import net.osmand.data.TransportRoute;
import net.osmand.data.TransportStop;
import net.osmand.osm.PoiCategory;
import net.osmand.osm.PoiFilter;
import net.osmand.osm.PoiType;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.mapcontextmenu.MapContextMenu;
import net.osmand.plus.mapcontextmenu.MenuBuilder;
import net.osmand.plus.mapcontextmenu.MenuController;
import net.osmand.plus.mapcontextmenu.builders.AmenityMenuBuilder;
import net.osmand.plus.mapcontextmenu.controllers.TransportStopController.TransportStopRoute;
import net.osmand.plus.render.RenderingIcons;
import net.osmand.plus.resources.TransportIndexRepository;
import net.osmand.plus.views.TransportStopsLayer;
import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class AmenityMenuController extends MenuController {
private Amenity amenity;
private List<TransportStopRoute> routes = new ArrayList<>();
public AmenityMenuController(MapActivity mapActivity, PointDescription pointDescription, Amenity amenity) {
super(new AmenityMenuBuilder(mapActivity, amenity), pointDescription, mapActivity);
this.amenity = amenity;
if (amenity.getType().getKeyName().equals("transportation")) {
boolean showTransportStops = false;
PoiFilter f = amenity.getType().getPoiFilterByName("public_transport");
if (f != null) {
for (PoiType t : f.getPoiTypes()) {
if (t.getKeyName().equals(amenity.getSubType())) {
showTransportStops = true;
break;
}
}
}
if (showTransportStops) {
processTransportStop();
}
}
}
@Override
protected void setObject(Object object) {
if (object instanceof Amenity) {
this.amenity = (Amenity) object;
}
}
@Override
protected Object getObject() {
return amenity;
}
@Override
public boolean needStreetName() {
if (amenity.getSubType() != null && amenity.getType() != null) {
PoiType pt = amenity.getType().getPoiTypeByKeyName(amenity.getSubType());
if (pt != null && pt.getOsmTag() != null && pt.getOsmTag().equals("place")) {
return false;
}
}
return true;
}
@Override
public int getLeftIconId() {
return getLeftIconId(amenity);
}
public static int getLeftIconId(Amenity amenity) {
String id = null;
PoiType st = amenity.getType().getPoiTypeByKeyName(amenity.getSubType());
if (st != null) {
if (RenderingIcons.containsBigIcon(st.getIconKeyName())) {
id = st.getIconKeyName();
} else if (RenderingIcons.containsBigIcon(st.getOsmTag() + "_" + st.getOsmValue())) {
id = st.getOsmTag() + "_" + st.getOsmValue();
}
}
if (id != null) {
return RenderingIcons.getBigIconResourceId(id);
}
return 0;
}
@Override
public boolean displayDistanceDirection() {
return true;
}
@Override
public String getTypeStr() {
return getTypeStr(amenity);
}
public static String getTypeStr(Amenity amenity) {
PoiCategory pc = amenity.getType();
PoiType pt = pc.getPoiTypeByKeyName(amenity.getSubType());
String typeStr = amenity.getSubType();
if (pt != null) {
typeStr = pt.getTranslation();
} else if (typeStr != null) {
typeStr = Algorithms.capitalizeFirstLetterAndLowercase(typeStr.replace('_', ' '));
}
return typeStr;
}
@Override
public String getCommonTypeStr() {
PoiCategory pc = amenity.getType();
return pc.getTranslation();
}
@Override
public void addPlainMenuItems(String typeStr, PointDescription pointDescription, LatLon latLon) {
addPlainMenuItems(amenity, typeStr, builder);
for (final TransportStopRoute r : routes) {
View.OnClickListener listener = new View.OnClickListener() {
@Override
public void onClick(View arg0) {
MapContextMenu mm = getMapActivity().getContextMenu();
PointDescription pd = new PointDescription(PointDescription.POINT_TYPE_TRANSPORT_ROUTE,
r.getDescription(getMapActivity().getMyApplication(), false));
mm.show(amenity.getLocation(), pd, r);
TransportStopsLayer stopsLayer = getMapActivity().getMapLayers().getTransportStopsLayer();
stopsLayer.setRoute(r.route);
int cz = r.calculateZoom(0, getMapActivity().getMapView().getCurrentRotatedTileBox());
getMapActivity().changeZoom(cz - getMapActivity().getMapView().getZoom());
}
};
if (r.type == null) {
builder.addPlainMenuItem(R.drawable.ic_action_polygom_dark, r.getDescription(getMapActivity().getMyApplication(), true),
false, false, listener);
} else {
builder.addPlainMenuItem(r.type.getResourceId(), r.getDescription(getMapActivity().getMyApplication(), true),
false, false, listener);
}
}
}
public static void addPlainMenuItems(Amenity amenity, String typeStr, MenuBuilder builder) {
if (!Algorithms.isEmpty(typeStr)) {
int resId = getLeftIconId(amenity);
if (resId == 0) {
PoiCategory pc = amenity.getType();
resId = RenderingIcons.getBigIconResourceId(pc.getIconKeyName());
}
if (resId == 0) {
resId = R.drawable.ic_action_folder_stroke;
}
builder.addPlainMenuItem(resId, typeStr, false, false, null);
}
}
private void processTransportStop() {
routes = new ArrayList<>();
List<TransportIndexRepository> reps = getMapActivity().getMyApplication()
.getResourceManager().searchTransportRepositories(amenity.getLocation().getLatitude(),
amenity.getLocation().getLongitude());
boolean useEnglishNames = getMapActivity().getMyApplication().getSettings().usingEnglishNames();
for (TransportIndexRepository t : reps) {
ArrayList<TransportStop> ls = new ArrayList<>();
QuadRect ll = MapUtils.calculateLatLonBbox(amenity.getLocation().getLatitude(), amenity.getLocation().getLongitude(), 150);
t.searchTransportStops(ll.top, ll.left, ll.bottom, ll.right, -1, ls, null);
for (TransportStop tstop : ls) {
addRoutes(useEnglishNames, t, tstop,
(int) MapUtils.getDistance(tstop.getLocation(), amenity.getLocation()));
}
}
Collections.sort(routes, new Comparator<TransportStopRoute>() {
@Override
public int compare(TransportStopRoute o1, TransportStopRoute o2) {
if (o1.distance != o2.distance) {
return Algorithms.compare(o1.distance, o2.distance);
}
int i1 = Algorithms.extractFirstIntegerNumber(o1.desc);
int i2 = Algorithms.extractFirstIntegerNumber(o2.desc);
if (i1 != i2) {
return Algorithms.compare(i1, i2);
}
return o1.desc.compareTo(o2.desc);
}
});
}
private void addRoutes(boolean useEnglishNames, TransportIndexRepository t, TransportStop s, int dist) {
Collection<TransportRoute> rts = t.getRouteForStop(s);
if (rts != null) {
for (TransportRoute rs : rts) {
TransportStopController.TransportStopType type = TransportStopController.TransportStopType.findType(rs.getType());
TransportStopRoute r = new TransportStopRoute();
r.type = type;
r.desc = rs.getRef() + " " + (useEnglishNames ? rs.getEnName(true) : rs.getName());
r.route = rs;
r.stop = s;
r.distance = dist;
this.routes.add(r);
}
}
}
}