package net.osmand.core.samples.android.sample1.mapcontextmenu;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.View;
import android.widget.LinearLayout;
import net.osmand.core.samples.android.sample1.MainActivity;
import net.osmand.core.samples.android.sample1.data.PointDescription;
import net.osmand.core.samples.android.sample1.mapcontextmenu.MenuController.MenuState;
import net.osmand.core.samples.android.sample1.mapcontextmenu.MenuController.MenuType;
import net.osmand.data.LatLon;
import net.osmand.util.MapUtils;
import java.lang.ref.WeakReference;
public class MapContextMenu extends MenuTitleController {
private MainActivity mainActivity;
private MapMultiSelectionMenu mapMultiSelectionMenu;
private boolean active;
private LatLon latLon;
private PointDescription pointDescription;
private Object object;
private MenuController menuController;
private LatLon mapCenter;
private boolean centerMarker;
private int mapZoom;
private LatLon myLocation;
private Float heading;
private boolean inLocationUpdate = false;
private boolean autoHide;
private MenuAction searchDoneAction;
public MapContextMenu() {
}
@Override
public MainActivity getMainActivity() {
return mainActivity;
}
public void setMainActivity(MainActivity mainActivity) {
this.mainActivity = mainActivity;
if (mapMultiSelectionMenu == null) {
mapMultiSelectionMenu = new MapMultiSelectionMenu(mainActivity);
} else {
mapMultiSelectionMenu.setMainActivity(mainActivity);
}
if (active) {
acquireMenuController(false);
if (menuController != null) {
menuController.addPlainMenuItems(typeStr, this.pointDescription, this.latLon);
}
if (searchDoneAction != null && searchDoneAction.dlg != null && searchDoneAction.dlg.getOwnerActivity() != mainActivity) {
searchDoneAction.dlg = buildSearchActionDialog();
searchDoneAction.dlg.show();
}
} else {
menuController = null;
}
}
public MapMultiSelectionMenu getMultiSelectionMenu() {
return mapMultiSelectionMenu;
}
public boolean isActive() {
return active;
}
public boolean isVisible() {
return findMenuFragment() != null;
}
public void hideMenues() {
if (isVisible()) {
hide();
} else if (mapMultiSelectionMenu.isVisible()) {
mapMultiSelectionMenu.hide();
}
}
@Override
public LatLon getLatLon() {
return latLon;
}
public LatLon getMapCenter() {
return mapCenter;
}
public void setMapCenter(LatLon mapCenter) {
this.mapCenter = mapCenter;
}
public void setCenterMarker(boolean centerMarker) {
this.centerMarker = centerMarker;
}
public int getMapZoom() {
return mapZoom;
}
public void setMapZoom(int mapZoom) {
this.mapZoom = mapZoom;
}
public void updateMapCenter(LatLon mapCenter) {
WeakReference<MapContextMenuFragment> fragmentRef = findMenuFragment();
if (fragmentRef != null) {
fragmentRef.get().updateMapCenter(mapCenter);
}
}
@Override
public PointDescription getPointDescription() {
return pointDescription;
}
@Override
public Object getObject() {
return object;
}
public boolean isExtended() {
return menuController != null;
}
@Override
public MenuController getMenuController() {
return menuController;
}
public boolean init(@NonNull LatLon latLon,
@Nullable PointDescription pointDescription,
@Nullable Object object) {
return init(latLon, pointDescription, object, false, false);
}
public boolean init(@NonNull LatLon latLon,
@Nullable PointDescription pointDescription,
@Nullable Object object,
boolean update, boolean restorePrevious) {
if (myLocation == null) {
myLocation = mainActivity.getMyApplication().getLocationProvider().getLastKnownLocationLatLon();
}
if (!update && isVisible()) {
if (this.object == null || !this.object.equals(object)) {
hide();
} else {
return false;
}
}
if (pointDescription == null) {
this.pointDescription = new PointDescription(latLon.getLatitude(), latLon.getLongitude());
} else {
this.pointDescription = pointDescription;
}
boolean needAcquireMenuController = menuController == null
|| !update
|| this.object == null && object != null
|| this.object != null && object == null
|| (this.object != null && object != null && !this.object.getClass().equals(object.getClass()));
this.latLon = latLon;
this.object = object;
active = true;
if (needAcquireMenuController) {
acquireMenuController(restorePrevious);
} else {
menuController.update(pointDescription, object);
}
initTitle();
if (menuController != null) {
menuController.clearPlainMenuItems();
menuController.addPlainMenuItems(typeStr, this.pointDescription, this.latLon);
}
mainActivity.refreshMap();
return true;
}
public void show() {
if (!isVisible()) {
if (!MapContextMenuFragment.showInstance(this, mainActivity, true)) {
active = false;
}
} else {
WeakReference<MapContextMenuFragment> fragmentRef = findMenuFragment();
if (fragmentRef != null) {
fragmentRef.get().centerMarkerLocation();
}
}
}
public void show(@NonNull LatLon latLon,
@Nullable PointDescription pointDescription,
@Nullable Object object) {
if (init(latLon, pointDescription, object)) {
showInternal();
}
}
private void showInternal() {
if (!MapContextMenuFragment.showInstance(this, mainActivity, centerMarker)) {
active = false;
} else {
mainActivity.showContextMarker(latLon);
if (menuController != null) {
menuController.onShow();
}
}
centerMarker = false;
autoHide = false;
}
public void update(LatLon latLon, PointDescription pointDescription, Object object) {
WeakReference<MapContextMenuFragment> fragmentRef = findMenuFragment();
init(latLon, pointDescription, object, true, false);
if (fragmentRef != null) {
fragmentRef.get().rebuildMenu();
}
}
public void showOrUpdate(LatLon latLon, PointDescription pointDescription, Object object) {
if (isVisible() && this.object != null && this.object.equals(object)) {
update(latLon, pointDescription, object);
} else {
show(latLon, pointDescription, object);
}
}
public void showMinimized(LatLon latLon, PointDescription pointDescription, Object object) {
init(latLon, pointDescription, object);
}
public void close() {
if (active) {
active = false;
if (menuController != null) {
menuController.onClose();
}
hide();
if (menuController != null) {
menuController.setActive(false);
}
mainActivity.hideContextMarker();
mainActivity.refreshMap();
}
}
public void hide() {
if (menuController != null) {
menuController.onHide();
}
WeakReference<MapContextMenuFragment> fragmentRef = findMenuFragment();
if (fragmentRef != null) {
fragmentRef.get().dismissMenu();
}
}
// timeout in msec
public void hideWithTimeout(long timeout) {
autoHide = true;
mainActivity.getMyApplication().runInUIThread(new Runnable() {
@Override
public void run() {
if (autoHide) {
hide();
}
}
}, timeout);
}
public void updateMenuUI() {
WeakReference<MapContextMenuFragment> fragmentRef = findMenuFragment();
if (fragmentRef != null) {
fragmentRef.get().updateMenu();
}
}
private void updateTitle(String address) {
nameStr = address;
pointDescription.setName(address);
WeakReference<MapContextMenuFragment> fragmentRef = findMenuFragment();
if (fragmentRef != null)
fragmentRef.get().refreshTitle();
}
private void acquireMenuController(boolean restorePrevious) {
if (menuController != null) {
menuController.onAcquireNewController(pointDescription, object);
}
menuController = MenuController.getMenuController(mainActivity, latLon, pointDescription, object, MenuType.STANDARD);
menuController.setActive(true);
}
public void onSingleTapOnMap() {
if (menuController == null || !menuController.handleSingleTapOnMap()) {
hide();
}
}
@Override
public void onSearchAddressDone() {
WeakReference<MapContextMenuFragment> fragmentRef = findMenuFragment();
if (fragmentRef != null)
fragmentRef.get().refreshTitle();
if (searchDoneAction != null) {
if (searchDoneAction.dlg != null) {
try {
searchDoneAction.dlg.dismiss();
} catch (Exception e) {
// ignore
} finally {
searchDoneAction.dlg = null;
}
}
searchDoneAction.run();
searchDoneAction = null;
}
}
public WeakReference<MapContextMenuFragment> findMenuFragment() {
Fragment fragment = mainActivity.getSupportFragmentManager().findFragmentByTag(MapContextMenuFragment.TAG);
if (fragment != null && !fragment.isDetached()) {
return new WeakReference<>((MapContextMenuFragment) fragment);
} else {
return null;
}
}
private void callMenuAction(boolean waitForAddressLookup, MenuAction menuAction) {
if (searchingAddress() && waitForAddressLookup) {
menuAction.dlg = buildSearchActionDialog();
menuAction.dlg.show();
searchDoneAction = menuAction;
} else {
menuAction.run();
}
}
private ProgressDialog buildSearchActionDialog() {
ProgressDialog dlg = new ProgressDialog(mainActivity);
dlg.setTitle("");
dlg.setMessage(searchAddressStr);
dlg.setButton(Dialog.BUTTON_NEGATIVE, mainActivity.getMyApplication().getString("shared_string_skip"), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
cancelSearchAddress();
}
});
return dlg;
}
public void setBaseFragmentVisibility(boolean visible) {
WeakReference<MapContextMenuFragment> fragmentRef = findMenuFragment();
if (fragmentRef != null) {
fragmentRef.get().setFragmentVisibility(visible);
}
}
public boolean isLandscapeLayout() {
return menuController != null && menuController.isLandscapeLayout();
}
public int getLandscapeWidthPx() {
if (menuController != null) {
return menuController.getLandscapeWidthPx();
} else {
return 0;
}
}
public void openMenuFullScreen() {
WeakReference<MapContextMenuFragment> fragmentRef = findMenuFragment();
if (fragmentRef != null)
fragmentRef.get().openMenuFullScreen();
}
public boolean slideUp() {
return menuController != null && menuController.slideUp();
}
public boolean slideDown() {
return menuController != null && menuController.slideDown();
}
public void build(View rootView) {
if (menuController != null) {
menuController.build(rootView);
}
}
public int getCurrentMenuState() {
if (menuController != null) {
return menuController.getCurrentMenuState();
} else {
return MenuState.HEADER_ONLY;
}
}
public float getHalfScreenMaxHeightKoef() {
if (menuController != null) {
return menuController.getHalfScreenMaxHeightKoef();
} else {
return 0f;
}
}
public int getSlideInAnimation() {
if (menuController != null) {
return menuController.getSlideInAnimation();
} else {
return 0;
}
}
public int getSlideOutAnimation() {
if (menuController != null) {
return menuController.getSlideOutAnimation();
} else {
return 0;
}
}
public MenuController.TitleButtonController getLeftTitleButtonController() {
if (menuController != null) {
return menuController.getLeftTitleButtonController();
} else {
return null;
}
}
public MenuController.TitleButtonController getRightTitleButtonController() {
if (menuController != null) {
return menuController.getRightTitleButtonController();
} else {
return null;
}
}
public MenuController.TitleButtonController getTopRightTitleButtonController() {
if (menuController != null) {
return menuController.getTopRightTitleButtonController();
} else {
return null;
}
}
public boolean supportZoomIn() {
return menuController == null || menuController.supportZoomIn();
}
public boolean fabVisible() {
return menuController == null || menuController.fabVisible();
}
public boolean buttonsVisible() {
return menuController == null || menuController.buttonsVisible();
}
public boolean displayDistanceDirection() {
return menuController != null && menuController.displayDistanceDirection();
}
public boolean hasCustomAddressLine() {
return menuController != null && menuController.hasCustomAddressLine();
}
public void buildCustomAddressLine(LinearLayout ll) {
if (menuController != null) {
menuController.buildCustomAddressLine(ll);
}
}
public boolean isNightMode() {
if (menuController != null) {
return !menuController.isLight();
} else {
return false;
}
}
public boolean hasHiddenBottomInfo() {
return getCurrentMenuState() == MenuState.HEADER_ONLY;
}
public LatLon getMyLocation() {
return myLocation;
}
public Float getHeading() {
return heading;
}
public void updateMyLocation(net.osmand.Location location) {
if (location != null && active && displayDistanceDirection()) {
myLocation = new LatLon(location.getLatitude(), location.getLongitude());
updateLocation(false, true, false);
}
}
public void updateCompassValue(float value) {
if (active && displayDistanceDirection()) {
// 99 in next line used to one-time initialize arrows (with reference vs. fixed-north direction)
// on non-compass devices
float lastHeading = heading != null ? heading : 99;
heading = value;
if (Math.abs(MapUtils.degreesDiff(lastHeading, heading)) > 5) {
updateLocation(false, false, true);
} else {
heading = lastHeading;
}
}
}
public void updateLocation(final boolean centerChanged, final boolean locationChanged,
final boolean compassChanged) {
if (inLocationUpdate) {
return;
}
inLocationUpdate = true;
mainActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
inLocationUpdate = false;
WeakReference<MapContextMenuFragment> fragmentRef = findMenuFragment();
if (fragmentRef != null) {
fragmentRef.get().updateLocation(centerChanged, locationChanged, compassChanged);
}
}
});
}
private abstract class MenuAction implements Runnable {
protected ProgressDialog dlg;
}
}