package net.osmand.plus.views.mapwidgets;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import net.osmand.Location;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.plus.IconsCache;
import net.osmand.plus.MapMarkersHelper;
import net.osmand.plus.MapMarkersHelper.MapMarker;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.R;
import net.osmand.plus.activities.MapActivity;
import net.osmand.plus.dashboard.DashLocationFragment;
import net.osmand.plus.dashboard.DashboardOnMap;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.plus.helpers.MapMarkerDialogHelper;
import net.osmand.plus.mapcontextmenu.other.MapRouteInfoMenu;
import net.osmand.plus.views.AnimateDraggingMapThread;
import net.osmand.plus.views.DirectionDrawable;
import net.osmand.plus.views.OsmandMapLayer.DrawSettings;
import net.osmand.plus.views.OsmandMapTileView;
import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
import java.util.List;
public class MapMarkersWidgetsFactory {
public static final int MIN_DIST_OK_VISIBLE = 40; // meters
public static final int MIN_DIST_2ND_ROW_SHOW = 150; // meters
private final MapActivity map;
private MapMarkersHelper helper;
private int screenOrientation;
private boolean portraitMode;
private View topBar;
private View addressTopBar;
private View topBar2nd;
private View rowView;
private View rowView2nd;
private ImageView arrowImg;
private ImageView arrowImg2nd;
private TextView distText;
private TextView distText2nd;
private TextView addressText;
private TextView addressText2nd;
private ImageButton okButton;
private ImageButton okButton2nd;
private ImageButton moreButton;
private ImageButton moreButton2nd;
private LatLon loc;
private LatLon lastKnownPosition;
public MapMarkersWidgetsFactory(final MapActivity map) {
this.map = map;
helper = map.getMyApplication().getMapMarkersHelper();
screenOrientation = DashLocationFragment.getScreenOrientation(map);
portraitMode = AndroidUiHelper.isOrientationPortrait(map);
addressTopBar = map.findViewById(R.id.map_top_bar);
topBar = map.findViewById(R.id.map_markers_top_bar);
topBar2nd = map.findViewById(R.id.map_markers_top_bar_2nd);
rowView = map.findViewById(R.id.map_marker_row);
rowView2nd = map.findViewById(R.id.map_marker_row_2nd);
arrowImg = (ImageView) map.findViewById(R.id.map_marker_arrow);
arrowImg2nd = (ImageView) map.findViewById(R.id.map_marker_arrow_2nd);
distText = (TextView) map.findViewById(R.id.map_marker_dist);
distText2nd = (TextView) map.findViewById(R.id.map_marker_dist_2nd);
addressText = (TextView) map.findViewById(R.id.map_marker_address);
addressText2nd = (TextView) map.findViewById(R.id.map_marker_address_2nd);
okButton = (ImageButton) map.findViewById(R.id.marker_btn_ok);
okButton2nd = (ImageButton) map.findViewById(R.id.marker_btn_ok_2dn);
moreButton = (ImageButton) map.findViewById(R.id.marker_btn_more);
moreButton2nd = (ImageButton) map.findViewById(R.id.marker_btn_more_2nd);
rowView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showMarkerOnMap(0);
}
});
rowView2nd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showMarkerOnMap(1);
}
});
IconsCache iconsCache = map.getMyApplication().getIconsCache();
if (isLandscapeLayout() && helper.getMapMarkers().size() > 1) {
moreButton.setVisibility(View.GONE);
} else {
moreButton.setImageDrawable(iconsCache.getIcon(R.drawable.ic_overflow_menu_white, R.color.marker_top_2nd_line_color));
moreButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MapActivity.clearPrevActivityIntent();
map.getDashboard().setDashboardVisibility(true, DashboardOnMap.DashboardType.MAP_MARKERS);
}
});
}
if (moreButton2nd != null) {
moreButton2nd.setImageDrawable(iconsCache.getIcon(R.drawable.ic_overflow_menu_white, R.color.marker_top_2nd_line_color));
moreButton2nd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
MapActivity.clearPrevActivityIntent();
map.getDashboard().setDashboardVisibility(true, DashboardOnMap.DashboardType.MAP_MARKERS);
}
});
}
okButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
removeMarker(0);
}
});
okButton2nd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
removeMarker(1);
}
});
updateVisibility(false);
}
private void removeMarker(int index) {
if (helper.getMapMarkers().size() > index) {
MapMarker marker = helper.getMapMarkers().get(index);
helper.removeMapMarker(marker.index);
helper.addMapMarkerHistory(marker);
}
}
private void showMarkerOnMap(int index) {
if (helper.getMapMarkers().size() > index) {
MapMarker marker = helper.getMapMarkers().get(index);
AnimateDraggingMapThread thread = map.getMapView().getAnimatedDraggingThread();
LatLon pointToNavigate = marker.point;
if (pointToNavigate != null) {
int fZoom = map.getMapView().getZoom() < 15 ? 15 : map.getMapView().getZoom();
thread.startMoving(pointToNavigate.getLatitude(), pointToNavigate.getLongitude(), fZoom, true);
}
//MapMarkerDialogHelper.showMarkerOnMap(map, marker);
}
}
public boolean updateVisibility(boolean visible) {
return updateVisibility(topBar, visible);
}
public boolean updateVisibility(View v, boolean visible) {
if (visible != (v.getVisibility() == View.VISIBLE)) {
if (visible) {
v.setVisibility(View.VISIBLE);
} else {
v.setVisibility(View.GONE);
}
v.invalidate();
return true;
}
return false;
}
public int getTopBarHeight() {
return topBar.getHeight();
}
public boolean isTopBarVisible() {
return topBar.getVisibility() == View.VISIBLE
&& map.findViewById(R.id.MapHudButtonsOverlay).getVisibility() == View.VISIBLE;
}
public void updateInfo(LatLon customLocation, int zoom) {
if (!map.getMyApplication().getSettings().USE_MAP_MARKERS.get()) {
return;
}
if (customLocation != null) {
loc = customLocation;
} else {
Location l = map.getMapViewTrackingUtilities().getMyLocation();
if (l != null) {
loc = new LatLon(l.getLatitude(), l.getLongitude());
lastKnownPosition = loc;
} else {
loc = lastKnownPosition;
}
}
List<MapMarker> markers = helper.getMapMarkers();
if (zoom < 3 || markers.size() == 0
|| !map.getMyApplication().getSettings().MAP_MARKERS_MODE.get().isToolbar()
|| map.getMyApplication().getRoutingHelper().isFollowingMode()
|| map.getMyApplication().getRoutingHelper().isRoutePlanningMode()
|| MapRouteInfoMenu.isVisible()
|| addressTopBar.getVisibility() == View.VISIBLE
|| map.isTopToolbarActive()) {
updateVisibility(false);
return;
}
Float heading = map.getMapViewTrackingUtilities().getHeading();
MapMarker marker = markers.get(0);
updateUI(loc, heading, marker, arrowImg, distText, okButton, addressText, true, customLocation != null);
if (markers.size() > 1) {
marker = markers.get(1);
if (loc != null && customLocation == null) {
for (int i = 1; i < markers.size(); i++) {
MapMarker m = markers.get(i);
m.dist = (int) (MapUtils.getDistance(m.getLatitude(), m.getLongitude(),
loc.getLatitude(), loc.getLongitude()));
if (m.dist < MIN_DIST_2ND_ROW_SHOW && marker.dist > m.dist) {
marker = m;
}
}
}
updateUI(loc, heading, marker, arrowImg2nd, distText2nd, okButton2nd, addressText2nd, false, customLocation != null);
updateVisibility(topBar2nd, true);
} else {
updateVisibility(topBar2nd, false);
}
updateVisibility(true);
}
private void updateUI(LatLon loc, Float heading, MapMarker marker, ImageView arrowImg,
TextView distText, ImageButton okButton, TextView addressText,
boolean firstLine, boolean customLocation) {
float[] mes = new float[2];
if (loc != null && marker.point != null) {
Location.distanceBetween(marker.getLatitude(), marker.getLongitude(), loc.getLatitude(), loc.getLongitude(), mes);
}
if (customLocation) {
heading = 0f;
}
boolean newImage = false;
DirectionDrawable dd;
if (!(arrowImg.getDrawable() instanceof DirectionDrawable)) {
newImage = true;
dd = new DirectionDrawable(map, arrowImg.getWidth(), arrowImg.getHeight());
} else {
dd = (DirectionDrawable) arrowImg.getDrawable();
}
dd.setImage(R.drawable.ic_arrow_marker_diretion, MapMarkerDialogHelper.getMapMarkerColorId(marker.colorIndex));
if (heading != null && loc != null) {
dd.setAngle(mes[1] - heading + 180 + screenOrientation);
}
if (newImage) {
arrowImg.setImageDrawable(dd);
}
arrowImg.invalidate();
int dist = (int) mes[0];
String txt;
if (loc != null) {
txt = OsmAndFormatter.getFormattedDistance(dist, map.getMyApplication());
} else {
txt = "—";
}
if (txt != null) {
distText.setText(txt);
}
updateVisibility(okButton, !customLocation && loc != null && dist < MIN_DIST_OK_VISIBLE);
String descr;
PointDescription pd = marker.getPointDescription(map);
if (Algorithms.isEmpty(pd.getName())) {
descr = pd.getTypeName();
} else {
descr = pd.getName();
}
if (!firstLine && !isLandscapeLayout()) {
descr = " • " + descr;
}
addressText.setText(descr);
}
public TextInfoWidget createMapMarkerControl(final MapActivity map, final boolean firstMarker) {
return new DistanceToMapMarkerControl(map, firstMarker) {
@Override
public LatLon getLatLon() {
return loc;
}
@Override
protected void click(OsmandMapTileView view) {
showMarkerOnMap(firstMarker ? 0 : 1);
}
};
}
public boolean isLandscapeLayout() {
return !portraitMode;
}
public abstract static class DistanceToMapMarkerControl extends TextInfoWidget {
private boolean firstMarker;
private final OsmandMapTileView view;
private MapActivity map;
private MapMarkersHelper helper;
private float[] calculations = new float[1];
private int cachedMeters;
private int cachedMarkerColorIndex = -1;
private Boolean cachedNightMode = null;
public DistanceToMapMarkerControl(MapActivity map, boolean firstMarker) {
super(map);
this.map = map;
this.firstMarker = firstMarker;
this.view = map.getMapView();
helper = map.getMyApplication().getMapMarkersHelper();
setText(null, null);
setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
click(view);
}
});
}
protected abstract void click(OsmandMapTileView view);
public abstract LatLon getLatLon();
@Override
public boolean updateInfo(DrawSettings drawSettings) {
MapMarker marker = getMarker();
if (marker == null
|| map.getMyApplication().getRoutingHelper().isRoutePlanningMode()
|| map.getMyApplication().getRoutingHelper().isFollowingMode()) {
cachedMeters = 0;
setText(null, null);
return false;
}
boolean res = false;
int d = getDistance();
if (cachedMeters != d) {
cachedMeters = d;
String ds = OsmAndFormatter.getFormattedDistance(cachedMeters, view.getApplication());
int ls = ds.lastIndexOf(' ');
if (ls == -1) {
setText(ds, null);
} else {
setText(ds.substring(0, ls), ds.substring(ls + 1));
}
res = true;
}
if (marker.colorIndex != -1) {
if (marker.colorIndex != cachedMarkerColorIndex
|| cachedNightMode == null || cachedNightMode != isNight()) {
setImageDrawable(map.getMyApplication().getIconsCache()
.getIcon(isNight() ? R.drawable.widget_marker_night : R.drawable.widget_marker_day,
R.drawable.widget_marker_triangle,
MapMarkerDialogHelper.getMapMarkerColorId(marker.colorIndex)));
cachedMarkerColorIndex = marker.colorIndex;
cachedNightMode = isNight();
res = true;
}
}
return res;
}
public LatLon getPointToNavigate() {
MapMarker marker = getMarker();
if (marker != null) {
return marker.point;
}
return null;
}
private MapMarker getMarker() {
List<MapMarker> markers = helper.getMapMarkers();
if (firstMarker) {
if (markers.size() > 0) {
return markers.get(0);
}
} else {
if (markers.size() > 1) {
return markers.get(1);
}
}
return null;
}
public int getDistance() {
int d = 0;
LatLon l = getPointToNavigate();
if (l != null) {
LatLon loc = getLatLon();
if (loc == null) {
Location.distanceBetween(view.getLatitude(), view.getLongitude(), l.getLatitude(), l.getLongitude(), calculations);
} else {
Location.distanceBetween(loc.getLatitude(), loc.getLongitude(), l.getLatitude(), l.getLongitude(), calculations);
}
d = (int) calculations[0];
}
return d;
}
}
}