package cgeo.geocaching.apps;
import cgeo.geocaching.Geocache;
import cgeo.geocaching.R;
import cgeo.geocaching.Waypoint;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.enumerations.CacheSize;
import cgeo.geocaching.enumerations.CacheType;
import cgeo.geocaching.enumerations.WaypointType;
import menion.android.locus.addon.publiclib.DisplayData;
import menion.android.locus.addon.publiclib.LocusUtils;
import menion.android.locus.addon.publiclib.geoData.Point;
import menion.android.locus.addon.publiclib.geoData.PointGeocachingData;
import menion.android.locus.addon.publiclib.geoData.PointGeocachingDataWaypoint;
import menion.android.locus.addon.publiclib.geoData.PointsData;
import android.app.Activity;
import android.content.Intent;
import android.location.Location;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
/**
* for the Locus API:
*
* @see Locus forum
*/
public abstract class AbstractLocusApp extends AbstractApp {
private static final String INTENT = Intent.ACTION_VIEW;
private static final SimpleDateFormat ISO8601DATE = new SimpleDateFormat("yyyy-MM-dd'T'", Locale.US);
protected AbstractLocusApp() {
super(getString(R.string.caches_map_locus), INTENT);
}
protected AbstractLocusApp(final String text, final String intent) {
super(text, intent);
}
@Override
public boolean isInstalled() {
return LocusUtils.isLocusAvailable(cgeoapplication.getInstance());
}
/**
* Display a list of caches / waypoints in Locus
*
* @param objectsToShow
* which caches/waypoints to show
* @param withCacheWaypoints
* Whether to give waypoints of caches to Locus or not
* @param activity
*/
protected static boolean showInLocus(final List> objectsToShow, final boolean withCacheWaypoints, final boolean export,
final Activity activity) {
if (objectsToShow == null || objectsToShow.isEmpty()) {
return false;
}
final boolean withCacheDetails = objectsToShow.size() < 200;
final PointsData pd = new PointsData("c:geo");
for (Object o : objectsToShow) {
Point p = null;
// get icon and Point
if (o instanceof Geocache) {
p = getCachePoint((Geocache) o, withCacheWaypoints, withCacheDetails);
} else if (o instanceof Waypoint) {
p = getWaypointPoint((Waypoint) o);
}
if (p != null) {
pd.addPoint(p);
}
}
if (pd.getPoints().isEmpty()) {
return false;
}
if (pd.getPoints().size() <= 1000) {
DisplayData.sendData(activity, pd, export);
} else {
final ArrayList data = new ArrayList();
data.add(pd);
DisplayData.sendDataCursor(activity, data,
"content://" + LocusDataStorageProvider.class.getCanonicalName().toLowerCase(Locale.US),
export);
}
return true;
}
/**
* This method constructs a Point for displaying in Locus
*
* @param cache
* @param withWaypoints
* whether to give waypoints to Locus or not
* @param withCacheDetails
* whether to give cache details (description, hint) to Locus or not
* should be false for all if more then 200 Caches are transferred
* @return null, when the Point could not be constructed
*/
private static Point getCachePoint(Geocache cache, boolean withWaypoints, boolean withCacheDetails) {
if (cache == null || cache.getCoords() == null) {
return null;
}
// create one simple point with location
final Location loc = new Location("cgeo");
loc.setLatitude(cache.getCoords().getLatitude());
loc.setLongitude(cache.getCoords().getLongitude());
final Point p = new Point(cache.getName(), loc);
final PointGeocachingData pg = new PointGeocachingData();
p.setGeocachingData(pg);
// set data in Locus' cache
pg.cacheID = cache.getGeocode();
pg.available = !cache.isDisabled();
pg.archived = cache.isArchived();
pg.premiumOnly = cache.isPremiumMembersOnly();
pg.name = cache.getName();
pg.placedBy = cache.getOwnerDisplayName();
if (cache.getHiddenDate() != null) {
pg.hidden = ISO8601DATE.format(cache.getHiddenDate().getTime());
}
int locusId = toLocusType(cache.getType());
if (locusId != NO_LOCUS_ID) {
pg.type = locusId;
}
locusId = toLocusSize(cache.getSize());
if (locusId != NO_LOCUS_ID) {
pg.container = locusId;
}
if (cache.getDifficulty() > 0) {
pg.difficulty = cache.getDifficulty();
}
if (cache.getTerrain() > 0) {
pg.terrain = cache.getTerrain();
}
pg.found = cache.isFound();
if (withWaypoints && cache.hasWaypoints()) {
pg.waypoints = new ArrayList();
for (Waypoint waypoint : cache.getWaypoints()) {
if (waypoint == null || waypoint.getCoords() == null) {
continue;
}
PointGeocachingDataWaypoint wp = new PointGeocachingDataWaypoint();
wp.code = waypoint.getGeocode();
wp.name = waypoint.getName();
String locusWpId = toLocusWaypoint(waypoint.getWaypointType());
if (locusWpId != null) {
wp.type = locusWpId;
}
wp.lat = waypoint.getCoords().getLatitude();
wp.lon = waypoint.getCoords().getLongitude();
pg.waypoints.add(wp);
}
}
// Other properties of caches. When there are many caches to be displayed
// in Locus, using these properties can lead to Exceptions in Locus.
// Should not be used if caches count > 200
if (withCacheDetails) {
pg.shortDescription = cache.getShortDescription();
pg.longDescription = cache.getDescription();
pg.encodedHints = cache.getHint();
}
return p;
}
/**
* This method constructs a Point for displaying in Locus
*
* @param waypoint
* @return null, when the Point could not be constructed
*/
private static Point getWaypointPoint(Waypoint waypoint) {
if (waypoint == null || waypoint.getCoords() == null) {
return null;
}
// create one simple point with location
final Location loc = new Location("cgeo");
loc.setLatitude(waypoint.getCoords().getLatitude());
loc.setLongitude(waypoint.getCoords().getLongitude());
final Point p = new Point(waypoint.getName(), loc);
p.setDescription(""
+ waypoint.getGeocode() + "");
return p;
}
private static final int NO_LOCUS_ID = -1;
private static int toLocusType(final CacheType ct) {
switch (ct) {
case TRADITIONAL:
return PointGeocachingData.CACHE_TYPE_TRADITIONAL;
case MULTI:
return PointGeocachingData.CACHE_TYPE_MULTI;
case MYSTERY:
return PointGeocachingData.CACHE_TYPE_MYSTERY;
case LETTERBOX:
return PointGeocachingData.CACHE_TYPE_LETTERBOX;
case EVENT:
return PointGeocachingData.CACHE_TYPE_EVENT;
case MEGA_EVENT:
return PointGeocachingData.CACHE_TYPE_MEGA_EVENT;
case EARTH:
return PointGeocachingData.CACHE_TYPE_EARTH;
case CITO:
return PointGeocachingData.CACHE_TYPE_CACHE_IN_TRASH_OUT;
case WEBCAM:
return PointGeocachingData.CACHE_TYPE_WEBCAM;
case VIRTUAL:
return PointGeocachingData.CACHE_TYPE_VIRTUAL;
case WHERIGO:
return PointGeocachingData.CACHE_TYPE_WHERIGO;
case PROJECT_APE:
return PointGeocachingData.CACHE_TYPE_PROJECT_APE;
case GPS_EXHIBIT:
return PointGeocachingData.CACHE_TYPE_GPS_ADVENTURE;
default:
return NO_LOCUS_ID;
}
}
private static int toLocusSize(final CacheSize cs) {
switch (cs) {
case MICRO:
return PointGeocachingData.CACHE_SIZE_MICRO;
case SMALL:
return PointGeocachingData.CACHE_SIZE_SMALL;
case REGULAR:
return PointGeocachingData.CACHE_SIZE_REGULAR;
case LARGE:
return PointGeocachingData.CACHE_SIZE_LARGE;
case NOT_CHOSEN:
return PointGeocachingData.CACHE_SIZE_NOT_CHOSEN;
case OTHER:
return PointGeocachingData.CACHE_SIZE_OTHER;
default:
return NO_LOCUS_ID;
}
}
private static String toLocusWaypoint(final WaypointType wt) {
switch (wt) {
case FINAL:
return PointGeocachingData.CACHE_WAYPOINT_TYPE_FINAL;
case OWN:
return PointGeocachingData.CACHE_WAYPOINT_TYPE_STAGES;
case PARKING:
return PointGeocachingData.CACHE_WAYPOINT_TYPE_PARKING;
case PUZZLE:
return PointGeocachingData.CACHE_WAYPOINT_TYPE_QUESTION;
case STAGE:
return PointGeocachingData.CACHE_WAYPOINT_TYPE_STAGES;
case TRAILHEAD:
return PointGeocachingData.CACHE_WAYPOINT_TYPE_TRAILHEAD;
case WAYPOINT:
return PointGeocachingData.CACHE_WAYPOINT_TYPE_STAGES;
default:
return null;
}
}
}