package org.mtransit.android.ui.view.map.impl;
import java.util.List;
import org.mtransit.android.commons.MTLog;
import org.mtransit.android.ui.view.map.Circle;
import org.mtransit.android.ui.view.map.CircleOptions;
import org.mtransit.android.ui.view.map.ClusteringSettings;
import org.mtransit.android.ui.view.map.ExtendedGoogleMap;
import org.mtransit.android.ui.view.map.ExtendedMarkerOptions;
import org.mtransit.android.ui.view.map.GroundOverlay;
import org.mtransit.android.ui.view.map.GroundOverlayOptions;
import org.mtransit.android.ui.view.map.IMarker;
import org.mtransit.android.ui.view.map.MTClusterOptionsProvider;
import org.mtransit.android.ui.view.map.Polygon;
import org.mtransit.android.ui.view.map.PolygonOptions;
import org.mtransit.android.ui.view.map.Polyline;
import org.mtransit.android.ui.view.map.PolylineOptions;
import org.mtransit.android.ui.view.map.TileOverlay;
import org.mtransit.android.ui.view.map.TileOverlayOptions;
import android.content.Context;
import android.graphics.Bitmap;
import android.view.View;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.LocationSource;
import com.google.android.gms.maps.Projection;
import com.google.android.gms.maps.UiSettings;
import com.google.android.gms.maps.model.CameraPosition;
// based on Maciej Górski's Android Maps Extensions library (Apache License, Version 2.0)
class DelegatingGoogleMap implements ExtendedGoogleMap, MTLog.Loggable {
private static final String TAG = DelegatingGoogleMap.class.getSimpleName();
@Override
public String getLogTag() {
return TAG;
}
private IGoogleMap real;
private Context context;
private InfoWindowAdapter infoWindowAdapter;
private OnCameraChangeListener onCameraChangeListener;
private OnMarkerDragListener onMarkerDragListener;
private MarkerManager markerManager;
private PolylineManager polylineManager;
private PolygonManager polygonManager;
private CircleManager circleManager;
private GroundOverlayManager groundOverlayManager;
private TileOverlayManager tileOverlayManager;
DelegatingGoogleMap(IGoogleMap real, Context context) {
this.real = real;
this.context = context;
createManagers();
assignMapListeners();
}
@Override
public Circle addCircle(CircleOptions circleOptions) {
return circleManager.addCircle(circleOptions);
}
@Override
public GroundOverlay addGroundOverlay(GroundOverlayOptions groundOverlayOptions) {
return groundOverlayManager.addGroundOverlay(groundOverlayOptions);
}
@Override
public IMarker addMarker(ExtendedMarkerOptions markerOptions) {
return markerManager.addMarker(markerOptions);
}
@Override
public Polygon addPolygon(PolygonOptions polygonOptions) {
return polygonManager.addPolygon(polygonOptions);
}
@Override
public Polyline addPolyline(PolylineOptions polylineOptions) {
return polylineManager.addPolyline(polylineOptions);
}
@Override
public TileOverlay addTileOverlay(TileOverlayOptions tileOverlayOptions) {
return tileOverlayManager.addTileOverlay(tileOverlayOptions);
}
@Override
public void animateCamera(CameraUpdate cameraUpdate, CancelableCallback cancelableCallback) {
real.animateCamera(cameraUpdate, cancelableCallback);
}
@Override
public void animateCamera(CameraUpdate cameraUpdate, int time, CancelableCallback cancelableCallback) {
real.animateCamera(cameraUpdate, time, cancelableCallback);
}
@Override
public void animateCamera(CameraUpdate cameraUpdate) {
real.animateCamera(cameraUpdate);
}
@Override
public void clear() {
real.clear();
clearManagers();
}
@Override
public CameraPosition getCameraPosition() {
return real.getCameraPosition();
}
@Override
public List<IMarker> getDisplayedMarkers() {
return markerManager.getDisplayedMarkers();
}
@Override
public int getMapType() {
return real.getMapType();
}
@Override
public List<Circle> getCircles() {
return circleManager.getCircles();
}
@Override
public List<GroundOverlay> getGroundOverlays() {
return groundOverlayManager.getGroundOverlays();
}
@Override
public List<IMarker> getMarkers() {
return markerManager.getMarkers();
}
@Override
public IMarker getMarkerShowingInfoWindow() {
return markerManager.getMarkerShowingInfoWindow();
}
@Override
public List<Polygon> getPolygons() {
return polygonManager.getPolygons();
}
@Override
public List<Polyline> getPolylines() {
return polylineManager.getPolylines();
}
@Override
public List<TileOverlay> getTileOverlays() {
return tileOverlayManager.getTileOverlays();
}
@Override
public float getMaxZoomLevel() {
return real.getMaxZoomLevel();
}
@Override
public float getMinZoomLevel() {
return real.getMinZoomLevel();
}
@Override
public float getMinZoomLevelNotClustered(IMarker marker) {
return markerManager.getMinZoomLevelNotClustered(marker);
}
@Override
public Projection getProjection() {
return real.getProjection().getProjection();
}
@Override
public UiSettings getUiSettings() {
return real.getUiSettings();
}
@Override
public boolean isBuildingsEnabled() {
return real.isBuildingsEnabled();
}
@Override
public boolean isIndoorEnabled() {
return real.isIndoorEnabled();
}
@Override
public boolean isMyLocationEnabled() {
return real.isMyLocationEnabled();
}
@Override
public boolean isTrafficEnabled() {
return real.isTrafficEnabled();
}
@Override
public void moveCamera(CameraUpdate cameraUpdate) {
real.moveCamera(cameraUpdate);
}
@Override
public void setBuildingsEnabled(boolean buildingsEnabled) {
real.setBuildingsEnabled(buildingsEnabled);
}
@Override
public void setClustering(ClusteringSettings clusteringSettings) {
if (clusteringSettings != null && clusteringSettings.isEnabled() && clusteringSettings.getClusterOptionsProvider() == null) {
clusteringSettings.clusterOptionsProvider(new MTClusterOptionsProvider(context));
}
markerManager.setClustering(clusteringSettings);
}
@Override
public boolean setIndoorEnabled(boolean indoorEnabled) {
return real.setIndoorEnabled(indoorEnabled);
}
@Override
public void setInfoWindowAdapter(final InfoWindowAdapter infoWindowAdapter) {
this.infoWindowAdapter = infoWindowAdapter;
}
@Override
public void setLocationSource(LocationSource locationSource) {
real.setLocationSource(locationSource);
}
@Override
public void setMapType(int mapType) {
real.setMapType(mapType);
}
@Override
public void setMyLocationEnabled(boolean myLocationEnabled) {
real.setMyLocationEnabled(myLocationEnabled);
}
@Override
public void setOnCameraChangeListener(OnCameraChangeListener onCameraChangeListener) {
this.onCameraChangeListener = onCameraChangeListener;
}
@Override
public void setOnInfoWindowClickListener(OnInfoWindowClickListener onInfoWindowClickListener) {
com.google.android.gms.maps.GoogleMap.OnInfoWindowClickListener realOnInfoWindowClickListener = null;
if (onInfoWindowClickListener != null) {
realOnInfoWindowClickListener = new DelegatingOnInfoWindowClickListener(onInfoWindowClickListener);
}
real.setOnInfoWindowClickListener(realOnInfoWindowClickListener);
}
@Override
public void setOnMapClickListener(OnMapClickListener onMapClickListener) {
real.setOnMapClickListener(onMapClickListener);
}
@Override
public void setOnMapLoadedCallback(OnMapLoadedCallback onMapLoadedCallback) {
real.setOnMapLoadedCallback(onMapLoadedCallback);
}
@Override
public void setOnMapLongClickListener(OnMapLongClickListener onMapLongClickListener) {
real.setOnMapLongClickListener(onMapLongClickListener);
}
@Override
public void setOnMarkerClickListener(OnMarkerClickListener onMarkerClickListener) {
com.google.android.gms.maps.GoogleMap.OnMarkerClickListener realOnMarkerClickListener = null;
if (onMarkerClickListener != null) {
realOnMarkerClickListener = new DelegatingOnMarkerClickListener(onMarkerClickListener);
}
real.setOnMarkerClickListener(realOnMarkerClickListener);
}
@Override
public void setOnMarkerDragListener(OnMarkerDragListener onMarkerDragListener) {
this.onMarkerDragListener = onMarkerDragListener;
}
@Override
public void setOnMyLocationButtonClickListener(OnMyLocationButtonClickListener listener) {
real.setOnMyLocationButtonClickListener(listener);
}
@Override
public void setPadding(int left, int top, int right, int bottom) {
real.setPadding(left, top, right, bottom);
}
@Override
public void setTrafficEnabled(boolean trafficEnabled) {
real.setTrafficEnabled(trafficEnabled);
}
@Override
public void snapshot(SnapshotReadyCallback callback) {
real.snapshot(callback);
}
@Override
public void snapshot(SnapshotReadyCallback callback, Bitmap bitmap) {
real.snapshot(callback, bitmap);
}
@Override
public void stopAnimation() {
real.stopAnimation();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof DelegatingGoogleMap)) {
return false;
}
DelegatingGoogleMap other = (DelegatingGoogleMap) o;
return real.equals(other.real);
}
@Override
public int hashCode() {
return real.hashCode();
}
@Override
public String toString() {
return real.toString();
}
private void createManagers() {
markerManager = new MarkerManager(this.real);
polylineManager = new PolylineManager(this.real);
polygonManager = new PolygonManager(this.real);
circleManager = new CircleManager(this.real);
groundOverlayManager = new GroundOverlayManager(this.real);
tileOverlayManager = new TileOverlayManager(this.real);
}
private void clearManagers() {
markerManager.clear();
polylineManager.clear();
polygonManager.clear();
circleManager.clear();
groundOverlayManager.clear();
tileOverlayManager.clear();
}
private void assignMapListeners() {
real.setInfoWindowAdapter(new DelegatingInfoWindowAdapter());
real.setOnCameraChangeListener(new DelegatingOnCameraChangeListener());
real.setOnMarkerDragListener(new DelegatingOnMarkerDragListener());
}
private class DelegatingOnCameraChangeListener implements com.google.android.gms.maps.GoogleMap.OnCameraChangeListener {
@Override
public void onCameraChange(CameraPosition cameraPosition) {
markerManager.onCameraChange(cameraPosition);
if (onCameraChangeListener != null) {
onCameraChangeListener.onCameraChange(cameraPosition);
}
}
}
private class DelegatingInfoWindowAdapter implements com.google.android.gms.maps.GoogleMap.InfoWindowAdapter, MTLog.Loggable {
private final String TAG = DelegatingGoogleMap.this.getLogTag() + ">" + DelegatingInfoWindowAdapter.class.getSimpleName();
@Override
public String getLogTag() {
return TAG;
}
@Override
public View getInfoWindow(com.google.android.gms.maps.model.Marker marker) {
IMarker mapped = markerManager.map(marker);
markerManager.setMarkerShowingInfoWindow(mapped);
if (infoWindowAdapter != null) {
return infoWindowAdapter.getInfoWindow(mapped);
}
return null;
}
@Override
public View getInfoContents(com.google.android.gms.maps.model.Marker marker) {
if (infoWindowAdapter != null) {
return infoWindowAdapter.getInfoContents(markerManager.map(marker));
}
return null;
}
}
private class DelegatingOnInfoWindowClickListener implements com.google.android.gms.maps.GoogleMap.OnInfoWindowClickListener, MTLog.Loggable {
private final String TAG = DelegatingGoogleMap.this.getLogTag() + ">" + DelegatingOnInfoWindowClickListener.class.getSimpleName();
@Override
public String getLogTag() {
return TAG;
}
private final OnInfoWindowClickListener onInfoWindowClickListener;
public DelegatingOnInfoWindowClickListener(OnInfoWindowClickListener onInfoWindowClickListener) {
this.onInfoWindowClickListener = onInfoWindowClickListener;
}
@Override
public void onInfoWindowClick(com.google.android.gms.maps.model.Marker marker) {
IMarker imarker = markerManager.map(marker);
onInfoWindowClickListener.onInfoWindowClick(imarker);
}
}
private class DelegatingOnMarkerClickListener implements com.google.android.gms.maps.GoogleMap.OnMarkerClickListener, MTLog.Loggable {
private final String TAG = DelegatingGoogleMap.this.getLogTag() + ">" + DelegatingOnMarkerClickListener.class.getSimpleName();
@Override
public String getLogTag() {
return TAG;
}
private final OnMarkerClickListener onMarkerClickListener;
public DelegatingOnMarkerClickListener(OnMarkerClickListener onMarkerClickListener) {
this.onMarkerClickListener = onMarkerClickListener;
}
@Override
public boolean onMarkerClick(com.google.android.gms.maps.model.Marker marker) {
return onMarkerClickListener.onMarkerClick(markerManager.map(marker));
}
}
private class DelegatingOnMarkerDragListener implements com.google.android.gms.maps.GoogleMap.OnMarkerDragListener {
@Override
public void onMarkerDragStart(com.google.android.gms.maps.model.Marker marker) {
DelegatingMarker delegating = markerManager.mapToDelegatingMarker(marker);
delegating.clearCachedPosition();
markerManager.onDragStart(delegating);
if (onMarkerDragListener != null) {
onMarkerDragListener.onMarkerDragStart(delegating);
}
}
@Override
public void onMarkerDrag(com.google.android.gms.maps.model.Marker marker) {
DelegatingMarker delegating = markerManager.mapToDelegatingMarker(marker);
delegating.clearCachedPosition();
if (onMarkerDragListener != null) {
onMarkerDragListener.onMarkerDrag(delegating);
}
}
@Override
public void onMarkerDragEnd(com.google.android.gms.maps.model.Marker marker) {
DelegatingMarker delegating = markerManager.mapToDelegatingMarker(marker);
delegating.clearCachedPosition();
markerManager.onPositionChange(delegating);
if (onMarkerDragListener != null) {
onMarkerDragListener.onMarkerDragEnd(delegating);
}
}
}
}