package org.pyneo.tabulae.poi;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import org.pyneo.thinstore.StoreObject;
import java.util.ArrayList;
import java.util.List;
import org.mapsforge.core.graphics.Bitmap;
import org.mapsforge.core.model.BoundingBox;
import org.mapsforge.core.model.LatLong;
import org.mapsforge.core.model.MapPosition;
import org.mapsforge.core.model.Point;
import org.mapsforge.core.util.LatLongUtils;
import org.mapsforge.map.android.graphics.AndroidGraphicFactory;
import org.mapsforge.map.layer.overlay.Marker;
import org.mapsforge.map.view.MapView;
import org.pyneo.tabulae.Base;
import org.pyneo.tabulae.R;
import org.pyneo.tabulae.Tabulae;
import static org.pyneo.tabulae.poi.Constants.*;
public class Poi extends Base {
protected List<PointAd> pointsAd = new ArrayList<>();
@Override
public void onCreate(Bundle bundle) {
if (DEBUG) Log.d(TAG, "Poi.onCreate");
super.onCreate(bundle);
}
@Override
public void onResume() {
super.onResume();
if (DEBUG) Log.d(TAG, "Poi.onResume");
//MapView mapView = ((Tabulae)getActivity()).getMapView();
try {
try (final SQLiteDatabase db = ((Tabulae)getActivity()).getReadableDatabase()) {
for (StoreObject item: StoreObject.query(db, PoiItem.class).where("visible").equal(true).fetchAll()) {
PoiItem poiItem = (PoiItem)item;
Log.d(TAG, "Poi.onResume poiItem=" + poiItem);
pointsAd.add(new PointAd(poiItem));
}
}
}
catch (Exception e) {
Log.e(TAG, "Poi.onResume e=" + e, e);
}
}
@Override
public void onPause() {
super.onPause();
if (DEBUG) Log.d(TAG, "Poi.onPause");
for (PointAd pointAd : pointsAd) {
pointAd.onDestroy();
}
pointsAd.clear();
}
class PointAd {
protected PoiItem poiItem;
protected Marker marker;
protected Bitmap bitmap;
PointAd(final PoiItem poiItem) {
this.poiItem = poiItem;
MapView mapView = ((Tabulae) getActivity()).getMapView();
if (marker != null) {
bitmap.decrementRefCount();
mapView.getLayerManager().getLayers().remove(marker);
marker.onDestroy();
marker = null;
}
LatLong latLong = new LatLong(poiItem.getLatitude(), poiItem.getLongitude());
bitmap = AndroidGraphicFactory.convertToBitmap(getResources().getDrawable(R.drawable.poi_black, null));
bitmap.incrementRefCount();
marker = new Marker(latLong, bitmap, 0, -bitmap.getHeight() / 2) {
@Override
public boolean onTap(LatLong geoPoint, Point viewPosition, Point tapPoint) {
if (contains(viewPosition, tapPoint)) {
Toast.makeText(getActivity(), String.format("%s: '%s'", poiItem.getName(), poiItem.getDescription()), Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
};
mapView.getLayerManager().getLayers().add(marker);
}
void onDestroy() {
if (DEBUG) Log.d(TAG, "Poi.PointAd.onDestroy");
MapView mapView = ((Tabulae) getActivity()).getMapView();
if (marker != null) {
bitmap.decrementRefCount();
mapView.getLayerManager().getLayers().remove(marker);
marker.onDestroy();
marker = null;
}
poiItem.setVisible(false);
try {
try (final SQLiteDatabase db = ((Tabulae)getActivity()).getWritableDatabase()) {
poiItem.insert(db);
}
}
catch (Exception e) {
Log.e(TAG, "Poi.PointAd.onDestroy e=" + e, e);
}
}
}
static public long storePointPosition(Tabulae activity, String name, String description, double latitude, double longitude, boolean visible) {
//noinspection UnusedAssignment
PoiItem poiItem = null;
try {
List<StoreObject> items = null;
try (final SQLiteDatabase db = activity.getReadableDatabase()) {
items = StoreObject.query(db, PoiItem.class).where("name").equal(name).fetchAll();
}
switch (items.size()) {
case 0:
if (DEBUG) Log.d(TAG, "Poi.storePointPosition new poiItem name=" + name);
poiItem = new PoiItem(name, description, latitude, longitude, visible);
break;
case 1:
if (DEBUG) Log.d(TAG, "Poi.storePointPosition update poiItem name=" + name);
poiItem = (PoiItem)items.get(0);
poiItem.setDescription(description);
poiItem.setLatitude(latitude);
poiItem.setLongitude(longitude);
poiItem.setVisible(visible);
break;
default:
Log.e(TAG, "Poi.storePointPosition poiItem not unique! name=" + name);
throw new RuntimeException("Not unique by name");
}
try (final SQLiteDatabase db = activity.getWritableDatabase()) {
return poiItem.insert(db).getId();
}
}
catch (Exception e) {
Log.e(TAG, "Poi.storePointPosition e=" + e, e);
}
return -1L;
}
void hideAll() {
for (PointAd pointAd : pointsAd) {
pointAd.onDestroy();
}
pointsAd.clear();
}
void center() {
MapView mapView = ((Tabulae) getActivity()).getMapView();
Bundle extra = new Bundle();
extra.putBoolean("autofollow", false);
((Tabulae) getActivity()).inform(R.id.event_do_autofollow, extra);
LatLong latLong = mapView.getModel().mapViewPosition.getMapPosition().latLong;
BoundingBox bb = new BoundingBox(latLong.latitude, latLong.longitude, latLong.latitude, latLong.longitude);
for (PointAd pointAd : pointsAd) {
PoiItem poiItem = pointAd.poiItem;
latLong = new LatLong(poiItem.getLatitude(), poiItem.getLongitude());
bb = bb.extendCoordinates(latLong);
}
try {
byte zoom = LatLongUtils.zoomForBounds(mapView.getModel().mapViewDimension.getDimension(), bb, mapView.getModel().displayModel.getTileSize());
if (zoom > MAX_ZOOM) {
zoom = MAX_ZOOM;
}
mapView.getModel().mapViewPosition.setMapPosition(new MapPosition(bb.getCenterPoint(), zoom));
}
catch (Exception e) {
mapView.getModel().mapViewPosition.setCenter(latLong);
}
}
public void inform(int event, Bundle extra) {
switch (event) {
case R.id.event_do_poi_new: {
if (DEBUG) Log.d(TAG, "Poi.inform event=event_poi_new, extra=" + extra);
storePointPosition((Tabulae) getActivity(),
extra.getString("name"),
extra.getString("description"),
extra.getDouble("latitude"),
extra.getDouble("longitude"),
true);
center();
}
break;
case R.id.event_do_poi_list: {
if (DEBUG) Log.d(TAG, "Poi.inform event=event_poi_list, extra=" + extra);
hideAll();
}
break;
}
}
}