package cgeo.geocaching.maps.mapsforge.v6.caches; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import cgeo.geocaching.SearchResult; import cgeo.geocaching.enumerations.WaypointType; import cgeo.geocaching.location.Geopoint; import cgeo.geocaching.maps.mapsforge.v6.MapHandlers; import cgeo.geocaching.maps.mapsforge.v6.MfMapView; public class CachesBundle { private static final int BASE_SEPARATOR = 0; private static final int STORED_SEPARATOR = 1; private static final int LIVE_SEPARATOR = 2; private static final int BASE_OVERLAY_ID = 0; private static final int STORED_OVERLAY_ID = 1; private static final int LIVE_OVERLAY_ID = 2; private final MfMapView mapView; private final MapHandlers mapHandlers; private static final int INITIAL_ENTRY_COUNT = 200; private final Set<GeoEntry> geoEntries = Collections.synchronizedSet(new HashSet<GeoEntry>(INITIAL_ENTRY_COUNT)); private AbstractCachesOverlay baseOverlay; private AbstractCachesOverlay storedOverlay; private LiveCachesOverlay liveOverlay; private final List<SeparatorLayer> separators = new ArrayList<>(); /** * Base initialization without any caches up-front * * @param mapView * the map view this bundle is displayed on * @param mapHandlers * the handlers of the map to send events to */ public CachesBundle(final MfMapView mapView, final MapHandlers mapHandlers) { this.mapView = mapView; this.mapHandlers = mapHandlers; // prepare separators final SeparatorLayer separator1 = new SeparatorLayer(); this.separators.add(separator1); this.mapView.getLayerManager().getLayers().add(separator1); final SeparatorLayer separator2 = new SeparatorLayer(); this.separators.add(separator2); this.mapView.getLayerManager().getLayers().add(separator2); final SeparatorLayer separator3 = new SeparatorLayer(); this.separators.add(separator3); this.mapView.getLayerManager().getLayers().add(separator3); } /** * Initialization with search result (nearby, list) * * @param search * the SearchResult to display through this bundle * @param mapView * the map view this bundle is displayed on * @param mapHandlers * the handlers of the map to send events to */ public CachesBundle(final SearchResult search, final MfMapView mapView, final MapHandlers mapHandlers) { this(mapView, mapHandlers); this.baseOverlay = new CachesOverlay(search, BASE_OVERLAY_ID, this.geoEntries, this.mapView, separators.get(BASE_SEPARATOR), this.mapHandlers); } /** * Initialization with single cache * * @param geocode * the geocode for single cache display through this bundle * @param mapView * the map view this bundle is displayed on * @param mapHandlers * the handlers of the map to send events to */ public CachesBundle(final String geocode, final MfMapView mapView, final MapHandlers mapHandlers) { this(mapView, mapHandlers); this.baseOverlay = new CachesOverlay(geocode, BASE_OVERLAY_ID, this.geoEntries, this.mapView, separators.get(BASE_SEPARATOR), this.mapHandlers); } /** * Initialization with single waypoint * * @param coords * coordinates for single waypoint to display through this bundle * @param waypointType * type for single waypoint to display through this bundle * @param mapView * the map view this bundle is displayed on * @param mapHandlers * the handlers of the map to send events to */ public CachesBundle(final Geopoint coords, final WaypointType waypointType, final MfMapView mapView, final MapHandlers mapHandlers) { this(mapView, mapHandlers); this.baseOverlay = new SinglePointOverlay(coords, waypointType, BASE_OVERLAY_ID, this.geoEntries, this.mapView, separators.get(BASE_SEPARATOR), this.mapHandlers); } public void handleLiveLayers(final boolean enable) { if (enable) { if (this.liveOverlay == null) { final SeparatorLayer separator2 = this.separators.get(LIVE_SEPARATOR); this.liveOverlay = new LiveCachesOverlay(LIVE_OVERLAY_ID, this.geoEntries, this.mapView, separator2, this.mapHandlers); } } else { // Disable only download, keep stored caches if (this.liveOverlay != null) { this.liveOverlay.onDestroy(); this.liveOverlay = null; } } } /** * Enables the stored cache layer. No disabling again! * @param enable * true - enable stored layer, false - leave untouched */ public void enableStoredLayers(final boolean enable) { if (!enable || this.storedOverlay != null) { return; } final SeparatorLayer separator1 = this.separators.get(STORED_SEPARATOR); this.storedOverlay = new StoredCachesOverlay(STORED_OVERLAY_ID, this.geoEntries, this.mapView, separator1, this.mapHandlers); } public void onDestroy() { if (this.baseOverlay != null) { this.baseOverlay.onDestroy(); this.baseOverlay = null; } if (this.storedOverlay != null) { this.storedOverlay.onDestroy(); this.storedOverlay = null; } if (this.liveOverlay != null) { this.liveOverlay.onDestroy(); this.liveOverlay = null; } for (final SeparatorLayer layer : this.separators) { this.mapView.getLayerManager().getLayers().remove(layer); } this.separators.clear(); } public int getVisibleItemsCount() { int result = 0; if (this.baseOverlay != null) { result += this.baseOverlay.getVisibleItemsCount(); } if (this.storedOverlay != null) { result += this.storedOverlay.getVisibleItemsCount(); } if (this.liveOverlay != null) { result += this.liveOverlay.getVisibleItemsCount(); } return result; } public Set<String> getVisibleGeocodes() { final Set<String> result = new HashSet<>(); if (this.baseOverlay != null) { result.addAll(this.baseOverlay.getVisibleGeocodes()); } if (this.liveOverlay != null) { result.addAll(this.liveOverlay.getVisibleGeocodes()); } if (this.storedOverlay != null) { result.addAll(this.storedOverlay.getVisibleGeocodes()); } return result; } public int getItemsCount() { int result = 0; if (baseOverlay != null) { result += baseOverlay.getItemsCount(); } if (storedOverlay != null) { result += storedOverlay.getItemsCount(); } if (liveOverlay != null) { result += liveOverlay.getItemsCount(); } return result; } public void invalidate() { if (storedOverlay != null) { storedOverlay.invalidate(); } if (liveOverlay != null) { liveOverlay.invalidate(); } } public void invalidate(final Collection<String> geocodes) { if (storedOverlay != null) { storedOverlay.invalidate(geocodes); } if (liveOverlay != null) { liveOverlay.invalidate(geocodes); } } public boolean isDownloading() { return liveOverlay != null && liveOverlay.isDownloading(); } }