package carnero.cgeo.original;
import carnero.cgeo.original.libs.App;
import carnero.cgeo.original.models.Waypoint;
import carnero.cgeo.original.models.Cache;
import carnero.cgeo.original.models.Coord;
import carnero.cgeo.original.models.Trackable;
import carnero.cgeo.original.libs.Settings;
import carnero.cgeo.original.libs.Base;
import carnero.cgeo.original.models.CacheLog;
import carnero.cgeo.original.libs.UpdateLoc;
import carnero.cgeo.original.libs.HtmlImg;
import carnero.cgeo.original.libs.Geo;
import carnero.cgeo.original.libs.Warning;
import java.util.ArrayList;
import java.util.HashMap;
import android.os.Handler;
import android.os.Message;
import android.os.Bundle;
import android.util.Log;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ContentValues;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.view.ContextMenu;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.view.LayoutInflater;
import android.widget.ScrollView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.ImageView;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Parcelable;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.SubMenu;
import android.widget.Button;
import com.google.android.apps.analytics.GoogleAnalyticsTracker;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Locale;
import java.util.Map.Entry;
public class cacheDetail extends Activity {
private static final int TAB_DTS = 1;
private static final int TAB_DSC = 2;
private static final int TAB_WPT = 3;
private static final int TAB_LOG = 4;
private static final int TAB_INV = 5;
private static final int TAB_ATR = 6;
public Long searchId = null;
public Cache cache = null;
public String geocode = null;
public String name = null;
public String guid = null;
private GoogleAnalyticsTracker tracker = null;
private Resources res = null;
private Activity activity = null;
private ViewPager pager = null;
private TextView indicatorCurrent;
private TextView indicatorPrev;
private TextView indicatorNext;
private int lastUsedTab = 0;
private ArrayList<Integer> tabOrder;
private ScrollView viewDetails;
private ScrollView viewDescriptions;
private ScrollView viewWaypoints;
private ScrollView viewLogs;
private ScrollView viewInventory;
private ScrollView viewAttributes;
private LayoutInflater inflater = null;
private App app = null;
private Settings settings = null;
private Base base = null;
private Warning warning = null;
private Geo geo = null;
private UpdateLoc geoUpdate = new update();
private TextView cacheDistance = null;
private String contextMenuUser = null;
private ProgressDialog waitDialog = null;
private ProgressDialog descDialog = null;
private Spanned longDesc = null;
private boolean longDescDisplayed = false;
private loadCache threadCache = null;
private loadLongDesc threadLongDesc = null;
private Thread storeThread = null;
private Thread refreshThread = null;
private HashMap<String, Integer> gcIcons = new HashMap<String, Integer>();
private ProgressDialog storeDialog = null;
private ProgressDialog refreshDialog = null;
private ProgressDialog dropDialog = null;
private HashMap<Integer, String> calendars = new HashMap<Integer, String>();
private Handler storeCacheHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
storeThread = null;
try {
cache = app.getCache(searchId); // reload cache details
} catch (Exception e) {
warning.showToast(res.getString(R.string.err_store_failed));
Log.e(Settings.tag, "cgeodetail.storeCacheHandler: " + e.toString());
}
load();
}
};
private Handler refreshCacheHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
refreshThread = null;
try {
cache = app.getCache(searchId); // reload cache details
} catch (Exception e) {
warning.showToast(res.getString(R.string.err_refresh_failed));
Log.e(Settings.tag, "cgeodetail.refreshCacheHandler: " + e.toString());
}
load();
}
};
private Handler dropCacheHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
try {
cache = app.getCache(searchId); // reload cache details
} catch (Exception e) {
warning.showToast(res.getString(R.string.err_drop_failed));
Log.e(Settings.tag, "cgeodetail.dropCacheHandler: " + e.toString());
}
load();
}
};
private Handler loadCacheHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (searchId == null || searchId <= 0) {
warning.showToast(res.getString(R.string.err_dwld_details_failed));
finish();
return;
}
if (app.getError(searchId) != null) {
warning.showToast(res.getString(R.string.err_dwld_details_failed_reason) + " " + app.getError(searchId) + ".");
finish();
return;
}
load();
}
};
private final LoadDescriptionHandler loadDescriptionHandler = new LoadDescriptionHandler();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// init
activity = this;
res = this.getResources();
app = (App) this.getApplication();
settings = new Settings(this, getSharedPreferences(Settings.preferences, 0));
base = new Base(app, settings, getSharedPreferences(Settings.preferences, 0));
warning = new Warning(this);
// set layout
if (settings.skin == 1) {
setTheme(R.style.light);
} else {
setTheme(R.style.dark);
}
setContentView(R.layout.detail);
base.setTitle(activity, res.getString(R.string.cache));
init();
// get parameters
final Bundle extras = getIntent().getExtras();
final Uri uri = getIntent().getData();
// try to get data from extras
if (geocode == null && extras != null) {
geocode = extras.getString("geocode");
name = extras.getString("name");
guid = extras.getString("guid");
}
// try to get data from URI
if (geocode == null && guid == null && uri != null) {
String uriHost = uri.getHost().toLowerCase();
String uriPath = uri.getPath().toLowerCase();
String uriQuery = uri.getQuery();
if (uriQuery != null) {
Log.i(Settings.tag, "Opening URI: " + uriHost + uriPath + "?" + uriQuery);
} else {
Log.i(Settings.tag, "Opening URI: " + uriHost + uriPath);
}
if (uriHost.contains("geocaching.com") == true) {
geocode = uri.getQueryParameter("wp");
guid = uri.getQueryParameter("guid");
if (geocode != null && geocode.length() > 0) {
geocode = geocode.toUpperCase();
guid = null;
} else if (guid != null && guid.length() > 0) {
geocode = null;
guid = guid.toLowerCase();
} else {
warning.showToast(res.getString(R.string.err_detail_open));
finish();
return;
}
} else if (uriHost.contains("coord.info") == true) {
if (uriPath != null && uriPath.startsWith("/gc") == true) {
geocode = uriPath.substring(1).toUpperCase();
} else {
warning.showToast(res.getString(R.string.err_detail_open));
finish();
return;
}
}
}
// google analytics
tracker = GoogleAnalyticsTracker.getInstance();
tracker.start(Settings.analytics, this);
tracker.dispatch();
if (geocode != null) {
base.sendAnal(activity, tracker, "/cache/detail#" + geocode);
}
// no given data
if (geocode == null && guid == null) {
warning.showToast(res.getString(R.string.err_detail_cache));
finish();
return;
}
app.setAction(geocode);
try {
if (name != null && name.length() > 0) {
waitDialog = ProgressDialog.show(this, name, res.getString(R.string.cache_dialog_loading_details), true);
} else if (geocode != null && geocode.length() > 0) {
waitDialog = ProgressDialog.show(this, geocode.toUpperCase(), res.getString(R.string.cache_dialog_loading_details), true);
} else {
waitDialog = ProgressDialog.show(this, res.getString(R.string.cache), res.getString(R.string.cache_dialog_loading_details), true);
}
waitDialog.setCancelable(true);
} catch (Exception e) {
// nothing, we lost the window
}
threadCache = new loadCache(loadCacheHandler, geocode, guid);
threadCache.start();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
load();
}
@Override
public void onResume() {
super.onResume();
settings.load();
if (geo == null) {
geo = app.startGeo(activity, geoUpdate, base, settings, warning, 0, 0);
}
load();
}
@Override
public void onDestroy() {
if (geo != null) {
geo = app.removeGeo();
}
if (tracker != null) {
tracker.stop();
}
super.onDestroy();
}
@Override
public void onStop() {
if (geo != null) {
geo = app.removeGeo();
}
super.onStop();
}
@Override
public void onPause() {
if (geo != null) {
geo = app.removeGeo();
}
super.onPause();
}
@Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo info) {
super.onCreateContextMenu(menu, view, info);
final int viewId = view.getId();
if (viewId == R.id.author || viewId == R.id.value) {
if (viewId == R.id.author) { // Author of a log entry
contextMenuUser = ((TextView) view).getText().toString();
} else if (viewId == R.id.value) { // The owner of the cache
if (cache.ownerReal != null && cache.ownerReal.length() > 0) {
contextMenuUser = cache.ownerReal;
} else {
contextMenuUser = cache.owner;
}
}
menu.setHeaderTitle(res.getString(R.string.user_menu_title) + " " + contextMenuUser);
menu.add(viewId, 1, 0, res.getString(R.string.user_menu_view_hidden));
menu.add(viewId, 2, 0, res.getString(R.string.user_menu_view_found));
menu.add(viewId, 3, 0, res.getString(R.string.user_menu_open_browser));
}
}
@Override
public boolean onContextItemSelected(MenuItem item) {
final int group = item.getGroupId();
if (group == R.id.author || group == R.id.value) {
final int id = item.getItemId();
if (id == 1) {
final Intent cachesIntent = new Intent(activity, cacheList.class);
cachesIntent.putExtra("type", "owner");
cachesIntent.putExtra("username", contextMenuUser);
cachesIntent.putExtra("cachetype", settings.cacheType);
activity.startActivity(cachesIntent);
return true;
} else if (id == 2) {
final Intent cachesIntent = new Intent(activity, cacheList.class);
cachesIntent.putExtra("type", "username");
cachesIntent.putExtra("username", contextMenuUser);
cachesIntent.putExtra("cachetype", settings.cacheType);
activity.startActivity(cachesIntent);
return true;
} else if (id == 3) {
activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/profile/?u=" + URLEncoder.encode(contextMenuUser))));
return true;
}
}
return false;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (cache != null && cache.latitude != null && cache.longitude != null) {
menu.add(0, 2, 0, res.getString(R.string.cache_menu_compass)).setIcon(android.R.drawable.ic_menu_compass); // compass
SubMenu subMenu = menu.addSubMenu(1, 0, 0, res.getString(R.string.cache_menu_navigate)).setIcon(android.R.drawable.ic_menu_more);
subMenu.add(0, 8, 0, res.getString(R.string.cache_menu_radar)); // radar
if (cache != null && cache.reason >= 1 && settings.storeOfflineMaps == 1) {
subMenu.add(1, 6, 0, res.getString(R.string.cache_menu_map_static)); // static maps
}
subMenu.add(0, 1, 0, res.getString(R.string.cache_menu_map)); // c:geo map
if (base.isLocus(activity)) {
subMenu.add(0, 20, 0, res.getString(R.string.cache_menu_locus)); // ext.: locus
}
if (base.isRmaps(activity)) {
subMenu.add(0, 21, 0, res.getString(R.string.cache_menu_rmaps)); // ext.: rmaps
}
subMenu.add(0, 23, 0, res.getString(R.string.cache_menu_map_ext)); // ext.: other
subMenu.add(0, 9, 0, res.getString(R.string.cache_menu_tbt)); // turn-by-turn
}
if (cache != null && cache.hidden != null && (cache.type.equalsIgnoreCase("event") == true || cache.type.equalsIgnoreCase("mega") == true || cache.type.equalsIgnoreCase("cito") == true)) {
menu.add(1, 11, 0, res.getString(R.string.cache_menu_event)).setIcon(android.R.drawable.ic_menu_agenda); // add event to calendar
}
if (settings.isLogin() == true) {
menu.add(1, 3, 0, res.getString(R.string.cache_menu_visit)).setIcon(android.R.drawable.ic_menu_agenda); // log cacheLog
}
if (cache != null && cache.spoilers != null && cache.spoilers.size() > 0) {
menu.add(1, 5, 0, res.getString(R.string.cache_menu_spoilers)).setIcon(android.R.drawable.ic_menu_gallery); // spoiler images
}
if (cache != null && cache.latitude != null && cache.longitude != null) {
menu.add(0, 10, 0, res.getString(R.string.cache_menu_around)).setIcon(android.R.drawable.ic_menu_rotate); // cacheList around
}
menu.add(1, 7, 0, res.getString(R.string.cache_menu_browser)).setIcon(android.R.drawable.ic_menu_info_details); // browser
menu.add(0, 12, 0, res.getString(R.string.cache_menu_share)).setIcon(android.R.drawable.ic_menu_share); // share cache
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
final int menuItem = item.getItemId();
if (menuItem == 1) {
showOnMap();
return true;
} else if (menuItem == 2) {
navigateTo();
return true;
} else if (menuItem == 3) {
logVisit();
return true;
} else if (menuItem == 5) {
showSpoilers();
return true;
} else if (menuItem == 6) {
showSmaps();
return true;
} else if (menuItem == 7) {
activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.geocaching.com/seek/cache_details.aspx?wp=" + cache.geocode)));
return true;
} else if (menuItem == 8) {
radarTo();
return true;
} else if (menuItem == 9) {
if (geo != null) {
base.runNavigation(activity, res, settings, warning, tracker, cache.latitude, cache.longitude, geo.latitudeNow, geo.longitudeNow);
} else {
base.runNavigation(activity, res, settings, warning, tracker, cache.latitude, cache.longitude);
}
return true;
} else if (menuItem == 10) {
cachesAround();
return true;
} else if (menuItem == 11) {
addToCalendar();
return true;
} else if (menuItem == 12) {
shareCache();
return true;
} else if (menuItem == 20) {
base.runExternalMap(Base.mapAppLocus, activity, res, warning, tracker, cache); // locus
return true;
} else if (menuItem == 21) {
base.runExternalMap(Base.mapAppRmaps, activity, res, warning, tracker, cache); // rmaps
return true;
} else if (menuItem == 23) {
base.runExternalMap(Base.mapAppAny, activity, res, warning, tracker, cache); // rmaps
return true;
}
return false;
}
private void init() {
if (inflater == null) {
inflater = activity.getLayoutInflater();
}
if (geo == null) {
geo = app.startGeo(activity, geoUpdate, base, settings, warning, 0, 0);
}
if (searchId != null && searchId > 0) {
cache = app.getCache(searchId);
if (cache != null && cache.geocode != null) {
geocode = cache.geocode;
}
}
if (geocode != null && geocode.length() > 0) {
app.setAction(geocode);
}
}
private class Adapter extends PagerAdapter {
@Override
public Object instantiateItem(View collection, int position) {
if (tabOrder == null) {
fillTabOrder();
}
final int tab = tabOrder.get(position);
ScrollView view;
switch (tab) {
case TAB_DTS:
view = viewDetails();
break;
case TAB_DSC:
view = viewDescriptions();
break;
case TAB_WPT:
view = viewWaypoints();
break;
case TAB_LOG:
view = viewLogs();
break;
case TAB_INV:
view = viewInventory();
break;
case TAB_ATR:
view = viewAttributes();
break;
default:
view = null;
}
((ViewPager) collection).addView(view);
return view;
}
@Override
public int getCount() {
if (tabOrder == null) {
fillTabOrder();
}
return tabOrder.size();
}
@Override
public void destroyItem(View collection, int position, Object view) {
((ViewPager) collection).removeView((View) view);
}
@Override
public boolean isViewFromObject(View view, Object object) {
if (view == object) {
return true;
}
return false;
}
@Override
public void finishUpdate(View arg0) {
// nothing
}
@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
// nothing
}
@Override
public Parcelable saveState() {
return null;
}
@Override
public void startUpdate(View arg0) {
// nothing
}
}
private class Indicator implements ViewPager.OnPageChangeListener {
@Override
public void onPageScrollStateChanged(int state) {
// nothing
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// nothing
}
@Override
public void onPageSelected(int position) {
if (tabOrder == null) {
fillTabOrder();
}
if (indicatorPrev == null) {
indicatorPrev = (TextView) findViewById(R.id.indicator_prev);
}
if (indicatorCurrent == null) {
indicatorCurrent = (TextView) findViewById(R.id.indicator_current);
}
if (indicatorNext == null) {
indicatorNext = (TextView) findViewById(R.id.indicator_next);
}
final int tabCurrent = tabOrder.get(position);
indicatorCurrent.setText(getTabTitle(tabCurrent));
if (position > 0) {
final int tabPrev = tabOrder.get(position - 1);
indicatorPrev.setText("« " + getTabTitle(tabPrev).toLowerCase(Locale.getDefault()));
indicatorPrev.setVisibility(View.VISIBLE);
} else {
indicatorPrev.setVisibility(View.GONE);
}
if (position < (tabOrder.size() - 1)) {
final int tabNext = tabOrder.get(position + 1);
indicatorNext.setText(getTabTitle(tabNext).toLowerCase(Locale.getDefault()) + " »");
indicatorNext.setVisibility(View.VISIBLE);
} else {
indicatorNext.setVisibility(View.GONE);
}
lastUsedTab = position;
}
}
private String getTabTitle(int tab) {
String title;
switch (tab) {
case TAB_DTS:
title = getString(R.string.tab_details);
break;
case TAB_DSC:
title = getString(R.string.tab_descriptions);
break;
case TAB_WPT:
title = getString(R.string.tab_waypoints);
break;
case TAB_LOG:
title = getString(R.string.tab_logs);
break;
case TAB_INV:
title = getString(R.string.tab_inventory);
break;
case TAB_ATR:
title = getString(R.string.tab_attributes);
break;
default:
title = "";
}
return title;
}
private void load() {
if (searchId == null) {
return;
}
cache = app.getCache(searchId);
if (cache == null) {
if (waitDialog != null && waitDialog.isShowing()) {
waitDialog.dismiss();
}
if (geocode != null && geocode.length() > 0) {
warning.showToast(res.getString(R.string.err_detail_cache_find) + " " + geocode + ".");
} else {
geocode = null;
warning.showToast(res.getString(R.string.err_detail_cache_find_some));
}
finish();
return;
}
final ViewPager.OnPageChangeListener pagerListener = new Indicator();
pagerListener.onPageSelected(lastUsedTab);
pager = (ViewPager) findViewById(R.id.pager);
pager.setOnPageChangeListener(pagerListener);
pager.setAdapter(new Adapter());
fillTabOrder();
if (cache.reason >= 1) {
base.sendAnal(activity, tracker, "/cache/detail/stored");
} else {
base.sendAnal(activity, tracker, "/cache/detail/online");
}
try {
if (gcIcons == null || gcIcons.isEmpty()) {
gcIcons.put("ape", R.drawable.type_ape);
gcIcons.put("cito", R.drawable.type_cito);
gcIcons.put("earth", R.drawable.type_earth);
gcIcons.put("event", R.drawable.type_event);
gcIcons.put("letterbox", R.drawable.type_letterbox);
gcIcons.put("locationless", R.drawable.type_locationless);
gcIcons.put("mega", R.drawable.type_mega);
gcIcons.put("multi", R.drawable.type_multi);
gcIcons.put("traditional", R.drawable.type_traditional);
gcIcons.put("virtual", R.drawable.type_virtual);
gcIcons.put("webcam", R.drawable.type_webcam);
gcIcons.put("wherigo", R.drawable.type_wherigo);
gcIcons.put("gchq", R.drawable.type_hq);
gcIcons.put("mystery", R.drawable.type_mystery);
}
if (cache.name != null && cache.name.length() > 0) {
base.setTitle(activity, cache.name);
} else {
base.setTitle(activity, geocode.toUpperCase());
}
inflater = activity.getLayoutInflater();
geocode = cache.geocode.toUpperCase();
// actionbar icon
if (cache.type != null && gcIcons.containsKey(cache.type) == true) { // cache icon
((TextView) findViewById(R.id.actionbar_title)).setCompoundDrawablesWithIntrinsicBounds((Drawable) activity.getResources().getDrawable(gcIcons.get(cache.type)), null, null, null);
} else { // unknown cache type, "mystery" icon
((TextView) findViewById(R.id.actionbar_title)).setCompoundDrawablesWithIntrinsicBounds((Drawable) activity.getResources().getDrawable(gcIcons.get("mystery")), null, null, null);
}
if (geo != null && geo.latitudeNow != null && geo.longitudeNow != null && cache != null && cache.latitude != null && cache.longitude != null) {
cacheDistance.setText(base.getHumanDistance(Base.getDistance(geo.latitudeNow, geo.longitudeNow, cache.latitude, cache.longitude)));
cacheDistance.bringToFront();
}
} catch (Exception e) {
Log.e(Settings.tag, "cgeodetail.setView: " + e.toString());
}
if (pager != null) {
pager.setVisibility(View.VISIBLE);
pager.getAdapter().notifyDataSetChanged();
}
if (waitDialog != null && waitDialog.isShowing()) {
waitDialog.dismiss();
}
if (storeDialog != null && storeDialog.isShowing()) {
storeDialog.dismiss();
}
if (dropDialog != null && dropDialog.isShowing()) {
dropDialog.dismiss();
}
if (refreshDialog != null && refreshDialog.isShowing()) {
refreshDialog.dismiss();
}
if (geo != null) {
geoUpdate.updateLoc(geo);
}
}
private void fillTabOrder() {
if (tabOrder == null) {
tabOrder = new ArrayList<Integer>();
} else {
tabOrder.clear();
}
tabOrder.add(TAB_DTS);
tabOrder.add(TAB_DSC);
tabOrder.add(TAB_WPT);
if (cache.logs != null && !cache.logs.isEmpty()) {
tabOrder.add(TAB_LOG);
}
if (cache.inventory != null && !cache.inventory.isEmpty()) {
tabOrder.add(TAB_INV);
}
if (cache.attributes != null && !cache.attributes.isEmpty()) {
tabOrder.add(TAB_ATR);
}
}
private ScrollView viewDetails() {
if (cache == null) {
return null;
}
final ScrollView view;
if (viewDetails == null) {
view = (ScrollView) inflater.inflate(R.layout.detail_details, null);
viewDetails = view;
} else {
view = viewDetails;
}
RelativeLayout itemLayout;
TextView itemName;
TextView itemValue;
// cache details
LinearLayout detailsList = (LinearLayout) view.findViewById(R.id.details_list);
detailsList.removeAllViews();
// cache name (full name)
itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null);
itemName = (TextView) itemLayout.findViewById(R.id.name);
itemValue = (TextView) itemLayout.findViewById(R.id.value);
itemName.setText(res.getString(R.string.cache_name));
itemValue.setText(Html.fromHtml(cache.name).toString());
detailsList.addView(itemLayout);
// cache type
itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null);
itemName = (TextView) itemLayout.findViewById(R.id.name);
itemValue = (TextView) itemLayout.findViewById(R.id.value);
itemName.setText(res.getString(R.string.cache_type));
String size = null;
if (cache.size != null && cache.size.length() > 0) {
size = " (" + cache.size + ")";
} else {
size = "";
}
if (Base.cacheTypesInv.containsKey(cache.type) == true) { // cache icon
itemValue.setText(Base.cacheTypesInv.get(cache.type) + size);
} else {
itemValue.setText(Base.cacheTypesInv.get("mystery") + size);
}
detailsList.addView(itemLayout);
// gc-code
itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null);
itemName = (TextView) itemLayout.findViewById(R.id.name);
itemValue = (TextView) itemLayout.findViewById(R.id.value);
itemName.setText(res.getString(R.string.cache_geocode));
itemValue.setText(cache.geocode.toUpperCase());
detailsList.addView(itemLayout);
// cache state
if (cache.logOffline == true || cache.archived == true || cache.disabled == true || cache.members == true || cache.found == true) {
itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null);
itemName = (TextView) itemLayout.findViewById(R.id.name);
itemValue = (TextView) itemLayout.findViewById(R.id.value);
itemName.setText(res.getString(R.string.cache_status));
StringBuilder state = new StringBuilder();
if (cache.logOffline == true) {
if (state.length() > 0) {
state.append(", ");
}
state.append(res.getString(R.string.cache_status_offline_log));
}
if (cache.found == true) {
if (state.length() > 0) {
state.append(", ");
}
state.append(res.getString(R.string.cache_status_found));
}
if (cache.archived == true) {
if (state.length() > 0) {
state.append(", ");
}
state.append(res.getString(R.string.cache_status_archived));
}
if (cache.disabled == true) {
if (state.length() > 0) {
state.append(", ");
}
state.append(res.getString(R.string.cache_status_disabled));
}
if (cache.members == true) {
if (state.length() > 0) {
state.append(", ");
}
state.append(res.getString(R.string.cache_status_premium));
}
itemValue.setText(state.toString());
detailsList.addView(itemLayout);
state = null;
}
// distance
itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null);
itemName = (TextView) itemLayout.findViewById(R.id.name);
itemValue = (TextView) itemLayout.findViewById(R.id.value);
itemName.setText(res.getString(R.string.cache_distance));
if (cache.distance != null) {
itemValue.setText("~" + base.getHumanDistance(cache.distance));
} else {
itemValue.setText("--");
}
detailsList.addView(itemLayout);
cacheDistance = itemValue;
// difficulty
if (cache.difficulty != null && cache.difficulty > 0) {
addStarRating(detailsList, res.getString(R.string.cache_difficulty), cache.difficulty);
}
// terrain
if (cache.terrain != null && cache.terrain > 0) {
addStarRating(detailsList, res.getString(R.string.cache_terrain), cache.terrain);
}
// favourite count
if (cache.favouriteCnt != null) {
itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null);
itemName = (TextView) itemLayout.findViewById(R.id.name);
itemValue = (TextView) itemLayout.findViewById(R.id.value);
itemName.setText(res.getString(R.string.cache_favourite));
itemValue.setText(String.format("%d", cache.favouriteCnt) + "×");
detailsList.addView(itemLayout);
}
// cache author
if ((cache.owner != null && cache.owner.length() > 0) || (cache.ownerReal != null && cache.ownerReal.length() > 0)) {
itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null);
itemName = (TextView) itemLayout.findViewById(R.id.name);
itemValue = (TextView) itemLayout.findViewById(R.id.value);
itemName.setText(res.getString(R.string.cache_owner));
if (cache.owner != null && cache.owner.length() > 0) {
itemValue.setText(Html.fromHtml(cache.owner), TextView.BufferType.SPANNABLE);
} else if (cache.ownerReal != null && cache.ownerReal.length() > 0) {
itemValue.setText(Html.fromHtml(cache.ownerReal), TextView.BufferType.SPANNABLE);
}
itemValue.setOnClickListener(new userActions());
detailsList.addView(itemLayout);
}
// cache hidden
if (cache.hidden != null && cache.hidden.getTime() > 0) {
itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null);
itemName = (TextView) itemLayout.findViewById(R.id.name);
itemValue = (TextView) itemLayout.findViewById(R.id.value);
if (cache.type != null && (cache.type.equalsIgnoreCase("event") == true || cache.type.equalsIgnoreCase("mega") == true || cache.type.equalsIgnoreCase("cito") == true)) {
itemName.setText(res.getString(R.string.cache_event));
} else {
itemName.setText(res.getString(R.string.cache_hidden));
}
itemValue.setText(Base.dateOut.format(cache.hidden));
detailsList.addView(itemLayout);
}
// cache location
if (cache.location != null && cache.location.length() > 0) {
itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null);
itemName = (TextView) itemLayout.findViewById(R.id.name);
itemValue = (TextView) itemLayout.findViewById(R.id.value);
itemName.setText(res.getString(R.string.cache_location));
itemValue.setText(cache.location);
detailsList.addView(itemLayout);
}
// cache coordinates
if (cache.latitude != null && cache.longitude != null) {
itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_item, null);
itemName = (TextView) itemLayout.findViewById(R.id.name);
itemValue = (TextView) itemLayout.findViewById(R.id.value);
itemName.setText(res.getString(R.string.cache_coordinates));
itemValue.setText(cache.latitudeString + " | " + cache.longitudeString);
detailsList.addView(itemLayout);
}
// offline use
final TextView offlineText = (TextView) view.findViewById(R.id.offline_text);
final Button offlineRefresh = (Button) view.findViewById(R.id.offline_refresh);
final Button offlineStore = (Button) view.findViewById(R.id.offline_store);
if (cache.reason >= 1) {
Long diff = (System.currentTimeMillis() / (60 * 1000)) - (cache.detailedUpdate / (60 * 1000)); // minutes
String ago = "";
if (diff < 15) {
ago = res.getString(R.string.cache_offline_time_mins_few);
} else if (diff < 50) {
ago = res.getString(R.string.cache_offline_time_about) + " " + diff + " " + res.getString(R.string.cache_offline_time_mins);
} else if (diff < 90) {
ago = res.getString(R.string.cache_offline_time_about) + " " + res.getString(R.string.cache_offline_time_hour);
} else if (diff < (48 * 60)) {
ago = res.getString(R.string.cache_offline_time_about) + " " + (diff / 60) + " " + res.getString(R.string.cache_offline_time_hours);
} else {
ago = res.getString(R.string.cache_offline_time_about) + " " + (diff / (24 * 60)) + " " + res.getString(R.string.cache_offline_time_days);
}
offlineText.setText(res.getString(R.string.cache_offline_stored) + "\n" + ago);
offlineRefresh.setVisibility(View.VISIBLE);
offlineRefresh.setClickable(true);
offlineRefresh.setOnClickListener(new storeCache());
offlineStore.setText(res.getString(R.string.cache_offline_drop));
offlineStore.setClickable(true);
offlineStore.setOnClickListener(new dropCache());
} else {
offlineText.setText(res.getString(R.string.cache_offline_not_ready));
offlineRefresh.setVisibility(View.VISIBLE);
offlineRefresh.setClickable(true);
offlineRefresh.setOnClickListener(new refreshCache());
offlineStore.setText(res.getString(R.string.cache_offline_store));
offlineStore.setClickable(true);
offlineStore.setOnClickListener(new storeCache());
}
// cache hint
if (cache.hint != null && cache.hint.length() > 0) {
((LinearLayout) view.findViewById(R.id.hint_box)).setVisibility(View.VISIBLE);
TextView hintView = ((TextView) view.findViewById(R.id.hint));
hintView.setText(Base.rot13(cache.hint.trim()));
hintView.setClickable(true);
hintView.setOnClickListener(new codeHint());
} else {
((LinearLayout) view.findViewById(R.id.hint_box)).setVisibility(View.GONE);
TextView hintView = ((TextView) view.findViewById(R.id.hint));
hintView.setClickable(false);
hintView.setOnClickListener(null);
}
return view;
}
private ScrollView viewDescriptions() {
if (cache == null) {
return null;
}
final ScrollView view;
if (viewDescriptions == null) {
view = (ScrollView) inflater.inflate(R.layout.detail_descriptions, null);
viewDescriptions = view;
} else {
view = viewDescriptions;
}
// cache short desc
if (cache.shortdesc != null && cache.shortdesc.length() > 0) {
TextView descView = (TextView) view.findViewById(R.id.shortdesc);
descView.setVisibility(View.VISIBLE);
descView.setText(Html.fromHtml(cache.shortdesc.trim(), new HtmlImg(activity, settings, geocode, true, cache.reason, false), null), TextView.BufferType.SPANNABLE);
descView.setMovementMethod(LinkMovementMethod.getInstance());
}
// cache long desc
if (longDescDisplayed == true) {
if (longDesc == null && cache != null && cache.description != null) {
longDesc = Html.fromHtml(cache.description.trim(), new HtmlImg(activity, settings, geocode, true, cache.reason, false), null);
}
if (longDesc != null && longDesc.length() > 0) {
TextView descView = (TextView) view.findViewById(R.id.description);
descView.setVisibility(View.VISIBLE);
descView.setText(longDesc, TextView.BufferType.SPANNABLE);
descView.setMovementMethod(LinkMovementMethod.getInstance());
Button showDesc = (Button) view.findViewById(R.id.show_description);
showDesc.setVisibility(View.GONE);
showDesc.setOnTouchListener(null);
showDesc.setOnClickListener(null);
}
} else if (longDescDisplayed == false && cache.description != null && cache.description.length() > 0) {
loadLongDesc(view);
}
return view;
}
private ScrollView viewWaypoints() {
if (cache == null) {
return null;
}
final ScrollView view;
if (viewWaypoints == null) {
view = (ScrollView) inflater.inflate(R.layout.detail_waypoints, null);
viewWaypoints = view;
} else {
view = viewWaypoints;
}
// waypoints
LinearLayout waypoints = (LinearLayout) view.findViewById(R.id.waypoints);
waypoints.removeAllViews();
if (cache.waypoints != null && cache.waypoints.size() > 0) {
LinearLayout waypointView;
// sort waypoints: PP, Sx, FI, OWN
ArrayList<Waypoint> sortedWaypoints = new ArrayList<Waypoint>(cache.waypoints);
Collections.sort(sortedWaypoints, new Comparator<Waypoint>() {
@Override
public int compare(Waypoint wayPoint1, Waypoint wayPoint2) {
return order(wayPoint1) - order(wayPoint2);
}
private int order(Waypoint waypoint) {
if (waypoint.prefix == null || waypoint.prefix.length() == 0) {
return 0;
}
// check only the first character. sometimes there are inconsistencies like FI or FN for the FINAL
char firstLetter = Character.toUpperCase(waypoint.prefix.charAt(0));
switch (firstLetter) {
case 'P':
return -100; // parking
case 'S': { // stage N
try {
Integer stageNumber = Integer.valueOf(waypoint.prefix.substring(1));
return stageNumber;
} catch (NumberFormatException e) {
// nothing
}
return 0;
}
case 'F':
return 1000; // final
case 'O':
return 10000; // own
}
return 0;
}
});
for (Waypoint wpt : sortedWaypoints) {
waypointView = (LinearLayout) inflater.inflate(R.layout.waypoint_item, null);
final TextView identification = (TextView) waypointView.findViewById(R.id.identification);
((TextView) waypointView.findViewById(R.id.type)).setText(Base.waypointTypes.get(wpt.type));
if (wpt.prefix.equalsIgnoreCase("OWN") == false) {
identification.setText(wpt.prefix.trim() + "/" + wpt.lookup.trim());
} else {
identification.setText(res.getString(R.string.waypoint_custom));
}
if (wpt.name.trim().length() == 0) {
((TextView) waypointView.findViewById(R.id.name)).setText(base.formatCoordinate(wpt.latitude, "lat", true) + " | " + base.formatCoordinate(wpt.longitude, "lon", true));
} else {
// avoid HTML parsing
if (wpt.name.indexOf('<') >= 0 || wpt.name.indexOf('&') >= 0) {
((TextView) waypointView.findViewById(R.id.name)).setText(Html.fromHtml(wpt.name.trim()), TextView.BufferType.SPANNABLE);
} else {
((TextView) waypointView.findViewById(R.id.name)).setText(wpt.name.trim());
}
}
// avoid HTML parsing
if (wpt.note.indexOf('<') >= 0 || wpt.note.indexOf('&') >= 0) {
((TextView) waypointView.findViewById(R.id.note)).setText(Html.fromHtml(wpt.note.trim()), TextView.BufferType.SPANNABLE);
} else {
((TextView) waypointView.findViewById(R.id.note)).setText(wpt.note.trim());
}
waypointView.setOnClickListener(new waypointInfo(wpt.id));
waypoints.addView(waypointView);
}
}
Button addWaypoint = (Button) view.findViewById(R.id.add_waypoint);
addWaypoint.setClickable(true);
addWaypoint.setOnClickListener(new addWaypoint());
return view;
}
private ScrollView viewInventory() {
if (cache == null) {
return null;
}
final ScrollView view;
if (viewInventory == null) {
view = (ScrollView) inflater.inflate(R.layout.detail_inventory, null);
viewInventory = view;
} else {
view = viewInventory;
}
// cache inventory
if (cache.inventory != null && cache.inventory.size() > 0) {
final LinearLayout inventBox = (LinearLayout) view.findViewById(R.id.inventory_box);
LinearLayout oneTbPre = null;
for (Trackable trackable : cache.inventory) {
oneTbPre = (LinearLayout) inflater.inflate(R.layout.trackable_button, null);
Button oneTb = (Button) oneTbPre.findViewById(R.id.button);
if (trackable.name != null) {
oneTb.setText(Html.fromHtml(trackable.name).toString());
} else {
oneTb.setText("some trackable");
}
oneTb.setClickable(true);
oneTb.setOnClickListener(new tbButtonListener(trackable.guid, trackable.geocode, trackable.name));
inventBox.addView(oneTbPre);
}
}
return view;
}
private ScrollView viewLogs() {
if (cache == null) {
return null;
}
final ScrollView view;
if (viewLogs == null) {
view = (ScrollView) inflater.inflate(R.layout.detail_logs, null);
viewLogs = view;
} else {
view = viewLogs;
}
// cache logs
TextView textView = (TextView) view.findViewById(R.id.logcount);
int logCounter = 0;
if (cache != null && cache.logCounts != null) {
final StringBuffer buff = new StringBuffer();
buff.append(res.getString(R.string.cache_log_types));
buff.append(": ");
// sort the log counts by type id ascending. that way the FOUND, DNF log types are the first and most visible ones
ArrayList<Entry<Integer, Integer>> sortedLogCounts = new ArrayList<Entry<Integer, Integer>>();
sortedLogCounts.addAll(cache.logCounts.entrySet());
Collections.sort(sortedLogCounts, new Comparator<Entry<Integer, Integer>>() {
@Override
public int compare(Entry<Integer, Integer> logCountItem1,
Entry<Integer, Integer> logCountItem2) {
return logCountItem1.getKey().compareTo(logCountItem2.getKey());
}
});
for (Entry<Integer, Integer> pair : sortedLogCounts) {
int logTypeId = pair.getKey().intValue();
String logTypeLabel = Base.logTypes1.get(logTypeId);
// it may happen that the label is unknown -> then avoid any output for this type
if (logTypeLabel != null) {
if (logCounter > 0) {
buff.append(", ");
}
buff.append(pair.getValue().intValue());
buff.append("× ");
buff.append(logTypeLabel);
}
logCounter++;
}
textView.setText(buff.toString());
}
// it may happen, that the logCounts map is available, but every log type has zero counts,
// therefore check again for the number of counted logs
if (logCounter > 0) {
textView.setVisibility(View.VISIBLE);
} else {
textView.setVisibility(View.GONE);
}
// cache logs
LinearLayout listView = (LinearLayout) view.findViewById(R.id.log_list);
listView.removeAllViews();
RelativeLayout rowView;
if (cache != null && cache.logs != null && !cache.logs.isEmpty()) {
for (CacheLog log : cache.logs) {
rowView = (RelativeLayout) inflater.inflate(R.layout.log_item, null);
if (log.date > 0) {
final Date logDate = new Date(log.date);
((TextView) rowView.findViewById(R.id.added)).setText(Base.dateOutShort.format(logDate));
}
if (Base.logTypes1.containsKey(log.type) == true) {
((TextView) rowView.findViewById(R.id.type)).setText(Base.logTypes1.get(log.type));
} else {
((TextView) rowView.findViewById(R.id.type)).setText(Base.logTypes1.get(4)); // note if type is unknown
}
// avoid parsing HTML if not necessary
if (log.author.indexOf('<') >= 0 || log.author.indexOf('&') >= 0) {
((TextView) rowView.findViewById(R.id.author)).setText(Html.fromHtml(log.author), TextView.BufferType.SPANNABLE);
} else {
((TextView) rowView.findViewById(R.id.author)).setText(log.author);
}
if (log.found == -1) {
((TextView) rowView.findViewById(R.id.count)).setVisibility(View.GONE);
} else if (log.found == 0) {
((TextView) rowView.findViewById(R.id.count)).setText(res.getString(R.string.cache_count_no));
} else if (log.found == 1) {
((TextView) rowView.findViewById(R.id.count)).setText(res.getString(R.string.cache_count_one));
} else {
((TextView) rowView.findViewById(R.id.count)).setText(log.found + " " + res.getString(R.string.cache_count_more));
}
// avoid parsing HTML if not necessary
if (log.log.indexOf('<') >= 0 || log.log.indexOf('&') >= 0) {
((TextView) rowView.findViewById(R.id.log)).setText(Html.fromHtml(log.log, new HtmlImg(activity, settings, null, false, cache.reason, false), null), TextView.BufferType.SPANNABLE);
} else {
((TextView) rowView.findViewById(R.id.log)).setText(log.log);
}
final ImageView markFound = (ImageView) rowView.findViewById(R.id.found_mark);
final ImageView markDNF = (ImageView) rowView.findViewById(R.id.dnf_mark);
final ImageView markDisabled = (ImageView) rowView.findViewById(R.id.disabled_mark);
if (log.type == 2 || log.type == 9 || log.type == 10) { // found, will attend, attended
markFound.setVisibility(View.VISIBLE);
markDNF.setVisibility(View.GONE);
markDisabled.setVisibility(View.GONE);
} else if (log.type == 3) { // did not find
markFound.setVisibility(View.GONE);
markDNF.setVisibility(View.VISIBLE);
markDisabled.setVisibility(View.GONE);
} else if (log.type == 7 || log.type == 8) { // disabled, archived
markFound.setVisibility(View.GONE);
markDNF.setVisibility(View.GONE);
markDisabled.setVisibility(View.VISIBLE);
} else {
markFound.setVisibility(View.GONE);
markDNF.setVisibility(View.GONE);
markDisabled.setVisibility(View.GONE);
}
((TextView) rowView.findViewById(R.id.author)).setOnClickListener(new userActions());
((TextView) rowView.findViewById(R.id.log)).setOnClickListener(new decryptLog());
listView.addView(rowView);
}
}
return view;
}
private ScrollView viewAttributes() {
if (cache == null) {
return null;
}
final ScrollView view;
if (viewAttributes == null) {
view = (ScrollView) inflater.inflate(R.layout.detail_attributes, null);
viewAttributes = view;
} else {
view = viewAttributes;
}
// cache attributes
if (cache.attributes != null && !cache.attributes.isEmpty()) {
final TextView attribView = (TextView) view.findViewById(R.id.attributes);
StringBuilder buffer = new StringBuilder();
String attribute;
for (int i = 0; i < cache.attributes.size(); i++) {
attribute = cache.attributes.get(i);
// dynamically search for a translation of the attribute
int id = res.getIdentifier("attribute_" + attribute, "string", base.context.getPackageName());
if (id > 0) {
String translated = res.getString(id);
if (translated != null && translated.length() > 0) {
attribute = translated;
}
}
if (buffer.length() > 0) {
buffer.append('\n');
}
buffer.append(attribute);
}
attribView.setText(buffer);
}
return view;
}
private class tbButtonListener implements View.OnClickListener {
private String guid = null;
private String geocode = null;
private String name = null;
public tbButtonListener(String guidIn, String geocodeIn, String nameIn) {
guid = guidIn;
geocode = geocodeIn;
name = nameIn;
}
public void onClick(View arg0) {
Intent trackableIntent = new Intent(activity, trackableDetail.class);
trackableIntent.putExtra("guid", guid);
trackableIntent.putExtra("geocode", geocode);
trackableIntent.putExtra("name", name);
activity.startActivity(trackableIntent);
finish();
return;
}
}
private RelativeLayout addStarRating(final LinearLayout detailsList, final String name, final float value) {
RelativeLayout itemLayout = (RelativeLayout) inflater.inflate(R.layout.cache_layout, null);
TextView itemName = (TextView) itemLayout.findViewById(R.id.name);
TextView itemValue = (TextView) itemLayout.findViewById(R.id.value);
LinearLayout itemStars = (LinearLayout) itemLayout.findViewById(R.id.stars);
itemName.setText(name);
itemValue.setText(String.format(Locale.getDefault(), "%.1f", value) + ' ' + res.getString(R.string.cache_rating_of) + " 5");
for (int i = 0; i <= 4; i++) {
ImageView star = (ImageView) inflater.inflate(R.layout.star, null);
if ((value - i) >= 1.0) {
star.setImageResource(R.drawable.star_on);
} else if ((value - i) > 0.0) {
star.setImageResource(R.drawable.star_half);
} else {
star.setImageResource(R.drawable.star_off);
}
itemStars.addView(star, (1 + i));
}
detailsList.addView(itemLayout);
return itemLayout;
}
private class loadCache extends Thread {
private Handler handler = null;
private String geocode = null;
private String guid = null;
public loadCache(Handler handlerIn, String geocodeIn, String guidIn) {
handler = handlerIn;
geocode = geocodeIn;
guid = guidIn;
if (geocode == null && guid == null) {
warning.showToast(res.getString(R.string.err_detail_cache_forgot));
finish();
return;
}
}
@Override
public void run() {
HashMap<String, String> params = new HashMap<String, String>();
if (geocode != null && geocode.length() > 0) {
params.put("geocode", geocode);
} else if (guid != null && guid.length() > 0) {
params.put("guid", guid);
} else {
return;
}
searchId = base.searchByGeocode(params, 0, false);
handler.sendMessage(new Message());
}
}
public void loadLongDesc(ScrollView view) {
if (activity != null && (waitDialog == null || waitDialog.isShowing() == false)) {
descDialog = ProgressDialog.show(activity, null, res.getString(R.string.cache_dialog_loading_description), true);
descDialog.setCancelable(true);
}
loadDescriptionHandler.setView(view);
threadLongDesc = new loadLongDesc(loadDescriptionHandler);
threadLongDesc.start();
}
private class loadLongDesc extends Thread {
private Handler handler = null;
public loadLongDesc(Handler handlerIn) {
handler = handlerIn;
}
@Override
public void run() {
if (cache == null || cache.description == null || handler == null) {
return;
}
longDesc = Html.fromHtml(cache.description.trim(), new HtmlImg(activity, settings, geocode, true, cache.reason, false), null);
handler.sendMessage(new Message());
}
}
private class LoadDescriptionHandler extends Handler {
ScrollView view;
@Override
public void handleMessage(Message msg) {
if (longDesc == null && cache != null && cache.description != null) {
longDesc = Html.fromHtml(cache.description.trim(), new HtmlImg(activity, settings, geocode, true, cache.reason, false), null);
}
if (view == null) {
if (descDialog != null && descDialog.isShowing()) {
descDialog.dismiss();
}
return;
}
if (longDesc != null) {
TextView descView = (TextView) view.findViewById(R.id.description);
if (cache.description.length() > 0) {
descView.setVisibility(View.VISIBLE);
descView.setText(longDesc, TextView.BufferType.SPANNABLE);
descView.setMovementMethod(LinkMovementMethod.getInstance());
} else {
descView.setVisibility(View.GONE);
}
Button showDesc = (Button) view.findViewById(R.id.show_description);
showDesc.setVisibility(View.GONE);
showDesc.setOnTouchListener(null);
showDesc.setOnClickListener(null);
} else {
warning.showToast(res.getString(R.string.err_load_descr_failed));
}
if (descDialog != null && descDialog.isShowing()) {
descDialog.dismiss();
}
if (waitDialog != null && waitDialog.isShowing()) {
waitDialog.dismiss();
}
longDescDisplayed = true;
}
public void setView(ScrollView v) {
view = v;
}
}
public ArrayList<Coord> getCoordinates() {
Coord coords = null;
ArrayList<Coord> coordinates = new ArrayList<Coord>();
try {
// cache
coords = new Coord();
coords.type = "cache";
if (name != null && name.length() > 0) {
coords.name = name;
} else {
coords.name = geocode.toUpperCase();
}
coords.latitude = cache.latitude;
coords.longitude = cache.longitude;
coordinates.add(coords);
} catch (Exception e) {
Log.e(Settings.tag, "cgeodetail.getCoordinates (cache): " + e.toString());
}
try {
// waypoints
for (Waypoint waypoint : cache.waypoints) {
if (waypoint.latitude == null || waypoint.longitude == null) {
continue;
}
coords = new Coord();
coords.type = "waypoint";
coords.name = waypoint.name;
coords.latitude = waypoint.latitude;
coords.longitude = waypoint.longitude;
coordinates.add(coords);
}
} catch (Exception e) {
Log.e(Settings.tag, "cgeodetail.getCoordinates (waypoint): " + e.toString());
}
return coordinates;
}
private void showOnMap() {
Intent mapIntent = new Intent(activity, settings.getMapFactory().getMapClass());
mapIntent.putExtra("detail", true);
mapIntent.putExtra("searchid", searchId);
activity.startActivity(mapIntent);
}
private void cachesAround() {
cacheList cachesActivity = new cacheList();
Intent cachesIntent = new Intent(activity, cachesActivity.getClass());
cachesIntent.putExtra("type", "coordinate");
cachesIntent.putExtra("latitude", cache.latitude);
cachesIntent.putExtra("longitude", cache.longitude);
cachesIntent.putExtra("cachetype", settings.cacheType);
activity.startActivity(cachesIntent);
finish();
}
private void addToCalendar() {
String[] projection = new String[]{"_id", "displayName"};
Uri calendarProvider = null;
final int sdk = new Integer(Build.VERSION.SDK).intValue();
if (sdk >= 8) {
calendarProvider = Uri.parse("content://com.android.calendar/calendars");
} else {
calendarProvider = Uri.parse("content://calendar/calendars");
}
Cursor cursor = managedQuery(calendarProvider, projection, "selected=1", null, null);
calendars.clear();
int cnt = 0;
if (cursor != null) {
cnt = cursor.getCount();
if (cnt > 0) {
cursor.moveToFirst();
int calId = 0;
String calIdPre = null;
String calName = null;
int calIdIn = cursor.getColumnIndex("_id");
int calNameIn = cursor.getColumnIndex("displayName");
do {
calIdPre = cursor.getString(calIdIn);
if (calIdPre != null) {
calId = new Integer(calIdPre);
}
calName = cursor.getString(calNameIn);
if (calId > 0 && calName != null) {
calendars.put(calId, calName);
}
} while (cursor.moveToNext() == true);
}
}
final CharSequence[] items = calendars.values().toArray(new CharSequence[calendars.size()]);
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle(R.string.cache_calendars);
builder.setItems(items, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
addToCalendarFn(item);
}
});
AlertDialog alert = builder.create();
alert.show();
}
private void addToCalendarFn(int index) {
if (calendars == null || calendars.isEmpty() == true) {
return;
}
try {
Uri calendarProvider = null;
final int sdk = new Integer(Build.VERSION.SDK).intValue();
if (sdk >= 8) {
calendarProvider = Uri.parse("content://com.android.calendar/events");
} else {
calendarProvider = Uri.parse("content://calendar/events");
}
final Integer[] keys = calendars.keySet().toArray(new Integer[calendars.size()]);
final Integer calId = keys[index];
final Date eventDate = cache.hidden;
eventDate.setHours(0);
eventDate.setMinutes(0);
eventDate.setSeconds(0);
StringBuilder description = new StringBuilder();
description.append("http://coord.info/");
description.append(cache.geocode.toUpperCase());
description.append("\n\n");
if (cache.shortdesc != null && cache.shortdesc.length() > 0) {
description.append(Html.fromHtml(cache.shortdesc).toString());
}
ContentValues event = new ContentValues();
event.put("calendar_id", calId);
event.put("dtstart", eventDate.getTime() + 43200000); // noon
event.put("dtend", eventDate.getTime() + 43200000 + 3600000); // + one hour
event.put("eventTimezone", "UTC");
event.put("title", Html.fromHtml(cache.name).toString());
event.put("description", description.toString());
String location = "";
if (cache.latitudeString != null && cache.latitudeString.length() > 0 && cache.longitudeString != null && cache.longitudeString.length() > 0) {
location += cache.latitudeString + " " + cache.longitudeString;
}
if (cache.location != null && cache.location.length() > 0) {
boolean addParenteses = false;
if (location.length() > 0) {
addParenteses = true;
location += " (";
}
location += Html.fromHtml(cache.location).toString();
if (addParenteses) {
location += ")";
}
}
if (location.length() > 0) {
event.put("eventLocation", location);
}
event.put("allDay", 1);
event.put("hasAlarm", 0);
getContentResolver().insert(calendarProvider, event);
warning.showToast(res.getString(R.string.event_success));
} catch (Exception e) {
warning.showToast(res.getString(R.string.event_fail));
Log.e(Settings.tag, "cgeodetail.addToCalendarFn: " + e.toString());
}
}
private void navigateTo() {
if (cache == null || cache.latitude == null || cache.longitude == null) {
warning.showToast(res.getString(R.string.err_location_unknown));
}
navigate navigateActivity = new navigate();
Intent navigateIntent = new Intent(activity, navigateActivity.getClass());
navigateIntent.putExtra("latitude", cache.latitude);
navigateIntent.putExtra("longitude", cache.longitude);
navigateIntent.putExtra("geocode", cache.geocode.toUpperCase());
navigateIntent.putExtra("name", cache.name);
if (navigate.coordinates != null) {
navigate.coordinates.clear();
}
navigate.coordinates = getCoordinates();
activity.startActivity(navigateIntent);
}
private void radarTo() {
try {
if (Base.isIntentAvailable(activity, "com.google.android.radar.SHOW_RADAR") == true) {
Intent radarIntent = new Intent("com.google.android.radar.SHOW_RADAR");
radarIntent.putExtra("latitude", new Float(cache.latitude));
radarIntent.putExtra("longitude", new Float(cache.longitude));
activity.startActivity(radarIntent);
} else {
AlertDialog.Builder dialog = new AlertDialog.Builder(activity);
dialog.setTitle(res.getString(R.string.err_radar_title));
dialog.setMessage(res.getString(R.string.err_radar_message));
dialog.setCancelable(true);
dialog.setPositiveButton("yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
try {
activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=pname:com.eclipsim.gpsstatus2")));
dialog.cancel();
} catch (Exception e) {
warning.showToast(res.getString(R.string.err_radar_market));
Log.e(Settings.tag, "cgeodetail.radarTo.onClick: " + e.toString());
}
}
});
dialog.setNegativeButton("no", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = dialog.create();
alert.show();
}
} catch (Exception e) {
warning.showToast(res.getString(R.string.err_radar_generic));
Log.e(Settings.tag, "cgeodetail.radarTo: " + e.toString());
}
}
public void shareCache() {
if (geocode == null && cache == null) {
return;
}
final Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
if (cache != null && cache.geocode != null) {
String subject = cache.geocode.toUpperCase();
if (cache.name != null && cache.name.length() > 0) {
subject = subject + " - " + cache.name;
}
intent.putExtra(Intent.EXTRA_SUBJECT, "Geocache " + subject);
intent.putExtra(Intent.EXTRA_TEXT, "http://coord.info/" + cache.geocode.toUpperCase());
} else if (geocode != null) {
intent.putExtra(Intent.EXTRA_SUBJECT, "Geocache " + geocode.toUpperCase());
intent.putExtra(Intent.EXTRA_TEXT, "http://coord.info/" + geocode.toUpperCase());
}
startActivity(Intent.createChooser(intent, res.getText(R.string.action_bar_share_title)));
}
private class waypointInfo implements View.OnClickListener {
private int id = -1;
public waypointInfo(int idIn) {
id = idIn;
}
public void onClick(View arg0) {
Intent waypointIntent = new Intent(activity, waypointDetail.class);
waypointIntent.putExtra("waypoint", id);
waypointIntent.putExtra("geocode", cache.geocode);
activity.startActivity(waypointIntent);
}
}
private void logVisit() {
Intent logVisitIntent = new Intent(activity, cacheLog.class);
logVisitIntent.putExtra("id", cache.cacheid);
logVisitIntent.putExtra("geocode", cache.geocode.toUpperCase());
logVisitIntent.putExtra("type", cache.type.toLowerCase());
logVisitIntent.putExtra("found", cache.found);
activity.startActivity(logVisitIntent);
}
private void showSpoilers() {
if (cache == null || cache.spoilers == null || cache.spoilers.isEmpty() == true) {
warning.showToast(res.getString(R.string.err_detail_no_spoiler));
}
Intent spoilersIntent = new Intent(activity, spoilers.class);
spoilersIntent.putExtra("geocode", geocode.toUpperCase());
activity.startActivity(spoilersIntent);
}
private void showSmaps() {
if (cache == null || cache.reason == 0) {
warning.showToast(res.getString(R.string.err_detail_no_map_static));
}
Intent smapsIntent = new Intent(activity, mapStatic.class);
smapsIntent.putExtra("geocode", geocode.toUpperCase());
activity.startActivity(smapsIntent);
}
public class codeHint implements View.OnClickListener {
public void onClick(View arg0) {
// code hint
TextView hintView = ((TextView) findViewById(R.id.hint));
hintView.setText(Base.rot13(hintView.getText().toString()));
}
}
private class update extends UpdateLoc {
@Override
public void updateLoc(Geo geo) {
if (geo == null) {
return;
}
try {
StringBuilder dist = new StringBuilder();
if (geo.latitudeNow != null && geo.longitudeNow != null && cache != null && cache.latitude != null && cache.longitude != null) {
dist.append(base.getHumanDistance(Base.getDistance(geo.latitudeNow, geo.longitudeNow, cache.latitude, cache.longitude)));
}
if (cache.elevation != null) {
Double diff = null;
if (geo.altitudeNow != null) {
diff = (cache.elevation - geo.altitudeNow);
}
if (diff != null && diff >= 0) {
dist.append(" ↗");
if (settings.units == Settings.unitsImperial) {
dist.append(String.format(Locale.getDefault(), "%.0f", (Math.abs(diff) * 3.2808399)));
dist.append(" ft");
} else {
dist.append(String.format(Locale.getDefault(), "%.0f", (Math.abs(diff))));
dist.append(" m");
}
} else if (diff != null && diff < 0) {
dist.append(" ↘");
if (settings.units == Settings.unitsImperial) {
dist.append(String.format(Locale.getDefault(), "%.0f", (Math.abs(diff) * 3.2808399)));
dist.append(" ft");
} else {
dist.append(String.format(Locale.getDefault(), "%.0f", (Math.abs(diff))));
dist.append(" m");
}
}
}
cacheDistance.setText(dist.toString());
cacheDistance.bringToFront();
} catch (Exception e) {
Log.w(Settings.tag, "Failed to update location.");
}
}
}
private class storeCache implements View.OnClickListener {
public void onClick(View arg0) {
if (dropDialog != null && dropDialog.isShowing() == true) {
warning.showToast(res.getString(R.string.err_detail_still_removing));
return;
}
if (refreshDialog != null && refreshDialog.isShowing() == true) {
warning.showToast(res.getString(R.string.err_detail_still_refreshing));
return;
}
storeDialog = ProgressDialog.show(activity, res.getString(R.string.cache_dialog_offline_save_title), res.getString(R.string.cache_dialog_offline_save_message), true);
storeDialog.setCancelable(true);
if (storeThread != null) {
storeThread.interrupt();
}
storeThread = new storeCacheThread(storeCacheHandler);
storeThread.start();
}
}
private class refreshCache implements View.OnClickListener {
public void onClick(View arg0) {
if (dropDialog != null && dropDialog.isShowing() == true) {
warning.showToast(res.getString(R.string.err_detail_still_removing));
return;
}
if (storeDialog != null && storeDialog.isShowing() == true) {
warning.showToast(res.getString(R.string.err_detail_still_saving));
return;
}
refreshDialog = ProgressDialog.show(activity, res.getString(R.string.cache_dialog_refresh_title), res.getString(R.string.cache_dialog_refresh_message), true);
refreshDialog.setCancelable(true);
if (refreshThread != null) {
refreshThread.interrupt();
}
refreshThread = new refreshCacheThread(refreshCacheHandler);
refreshThread.start();
}
}
private class storeCacheThread extends Thread {
private Handler handler = null;
public storeCacheThread(Handler handlerIn) {
handler = handlerIn;
}
@Override
public void run() {
int reason = 1;
if (cache.reason > 1) {
reason = cache.reason;
}
base.storeCache(app, activity, cache, null, reason, handler);
}
}
private class refreshCacheThread extends Thread {
private Handler handler = null;
public refreshCacheThread(Handler handlerIn) {
handler = handlerIn;
}
@Override
public void run() {
app.removeCacheFromCache(geocode);
final HashMap<String, String> params = new HashMap<String, String>();
params.put("geocode", cache.geocode);
searchId = base.searchByGeocode(params, 0, true);
handler.sendEmptyMessage(0);
}
}
private class dropCache implements View.OnClickListener {
public void onClick(View arg0) {
if (storeDialog != null && storeDialog.isShowing() == true) {
warning.showToast(res.getString(R.string.err_detail_still_saving));
return;
}
if (refreshDialog != null && refreshDialog.isShowing() == true) {
warning.showToast(res.getString(R.string.err_detail_still_refreshing));
return;
}
dropDialog = ProgressDialog.show(activity, res.getString(R.string.cache_dialog_offline_drop_title), res.getString(R.string.cache_dialog_offline_drop_message), true);
dropDialog.setCancelable(false);
Thread thread = new dropCacheThread(dropCacheHandler);
thread.start();
}
}
private class dropCacheThread extends Thread {
private Handler handler = null;
public dropCacheThread(Handler handlerIn) {
handler = handlerIn;
}
@Override
public void run() {
base.dropCache(app, activity, cache, handler);
}
}
private class addWaypoint implements View.OnClickListener {
public void onClick(View view) {
Intent addWptIntent = new Intent(activity, waypointNew.class);
addWptIntent.putExtra("geocode", geocode);
int wpCount = 0;
if (cache.waypoints != null) {
wpCount = cache.waypoints.size();
}
addWptIntent.putExtra("count", wpCount);
activity.startActivity(addWptIntent);
}
}
private class decryptLog implements View.OnClickListener {
public void onClick(View view) {
if (view == null) {
return;
}
try {
final TextView logView = (TextView) view;
Spannable span = (Spannable) logView.getText();
// I needed to re-implement the base.rot13() encryption here because we must work on
// a SpannableStringBuilder instead of the pure text and we must replace each character inline.
// Otherwise we loose all the images, colors and so on...
SpannableStringBuilder buffer = new SpannableStringBuilder(span);
boolean plaintext = false;
int length = span.length();
for (int index = 0; index < length; index++) {
int c = span.charAt(index);
if (c == '[') {
plaintext = true;
} else if (c == ']') {
plaintext = false;
} else if (!plaintext) {
int capitalized = c & 32;
c &= ~capitalized;
c = ((c >= 'A') && (c <= 'Z') ? ((c - 'A' + 13) % 26 + 'A') : c)
| capitalized;
}
buffer.replace(index, index + 1, String.valueOf((char) c));
}
logView.setText(buffer);
} catch (Exception e) {
// nothing
}
}
}
private class userActions implements View.OnClickListener {
public void onClick(View view) {
if (view == null) {
return;
}
try {
registerForContextMenu(view);
openContextMenu(view);
} catch (Exception e) {
// nothing
}
}
}
public void goHome(View view) {
base.goHome(activity);
}
public void goCompass(View view) {
if (cache == null || cache.latitude == null || cache.longitude == null) {
warning.showToast(res.getString(R.string.cache_coordinates_no));
return;
}
Intent navigateIntent = new Intent(activity, navigate.class);
navigateIntent.putExtra("latitude", cache.latitude);
navigateIntent.putExtra("longitude", cache.longitude);
navigateIntent.putExtra("geocode", cache.geocode.toUpperCase());
navigateIntent.putExtra("name", cache.name);
if (navigate.coordinates != null) {
navigate.coordinates.clear();
}
navigate.coordinates = getCoordinates();
activity.startActivity(navigateIntent);
}
}