package carnero.cgeo.original;
import carnero.cgeo.original.libs.App;
import carnero.cgeo.original.models.Cache;
import carnero.cgeo.original.libs.LogForm;
import carnero.cgeo.original.libs.Settings;
import carnero.cgeo.original.libs.Base;
import carnero.cgeo.original.models.TrackableLog;
import carnero.cgeo.original.models.CacheLog;
import carnero.cgeo.original.libs.Warning;
import android.os.Bundle;
import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
public class cacheLog extends LogForm {
private App app = null;
private Activity activity = null;
private Resources res = null;
private LayoutInflater inflater = null;
private Base base = null;
private Settings settings = null;
private Warning warning = null;
private Cache cache = null;
private ArrayList<Integer> types = new ArrayList<Integer>();
private ProgressDialog waitDialog = null;
private String cacheid = null;
private String geocode = null;
private String text = null;
private boolean alreadyFound = false;
private String viewstate = null;
private String viewstate1 = null;
private Boolean gettingViewstate = true;
private ArrayList<TrackableLog> trackables = null;
private Calendar date = Calendar.getInstance();
private int typeSelected = 1;
private int attempts = 0;
private boolean progressBar = false;
private Button post = null;
private Button save = null;
private Button clear = null;
private boolean tbChanged = false;
// constants
private final static int LOG_SIGNATURE = 0x1;
private final static int LOG_TIME = 0x2;
private final static int LOG_DATE = 0x4;
private final static int LOG_DATE_TIME = 0x6;
private final static int LOG_SIGNATURE_DATE_TIME = 0x7;
// handlers
private Handler showProgressHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (progressBar == true) {
base.showProgress(activity, true);
}
}
};
private Handler loadDataHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (types.contains(typeSelected) == false) {
typeSelected = types.get(0);
setType(typeSelected);
warning.showToast(res.getString(R.string.info_log_type_changed));
}
if ((viewstate == null || viewstate.length() == 0) && attempts < 2) {
warning.showToast(res.getString(R.string.err_log_load_data_again));
loadData thread;
thread = new loadData(cacheid);
thread.start();
return;
} else if ((viewstate == null || viewstate.length() == 0) && attempts >= 2) {
warning.showToast(res.getString(R.string.err_log_load_data));
base.showProgress(activity, false);
return;
}
gettingViewstate = false; // we're done, user can post log
if (post == null) {
post = (Button) findViewById(R.id.post);
}
post.setEnabled(true);
post.setOnClickListener(new postListener());
// add trackables
if (trackables != null && trackables.isEmpty() == false) {
if (inflater == null) {
inflater = activity.getLayoutInflater();
}
final LinearLayout inventoryView = (LinearLayout) findViewById(R.id.inventory);
inventoryView.removeAllViews();
for (TrackableLog tb : trackables) {
LinearLayout inventoryItem = (LinearLayout) inflater.inflate(R.layout.visit_trackable, null);
((TextView) inventoryItem.findViewById(R.id.trackcode)).setText(tb.trackCode);
((TextView) inventoryItem.findViewById(R.id.name)).setText(tb.name);
((TextView) inventoryItem.findViewById(R.id.action)).setText(Base.logTypesTrackable.get(0));
inventoryItem.setId(tb.id);
final String tbCode = tb.trackCode;
inventoryItem.setClickable(true);
registerForContextMenu(inventoryItem);
inventoryItem.findViewById(R.id.info).setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
final Intent trackablesIntent = new Intent(activity, trackableDetail.class);
trackablesIntent.putExtra("geocode", tbCode);
activity.startActivity(trackablesIntent);
}
});
inventoryItem.findViewById(R.id.action).setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
openContextMenu(view);
}
});
inventoryView.addView(inventoryItem);
}
if (inventoryView.getChildCount() > 0) {
((LinearLayout) findViewById(R.id.inventory_box)).setVisibility(View.VISIBLE);
}
if (inventoryView.getChildCount() > 1 && inventoryView.getChildCount() <= 20) {
final LinearLayout inventoryChangeAllView = (LinearLayout) findViewById(R.id.inventory_changeall);
Button changeButton = (Button) inventoryChangeAllView.findViewById(R.id.changebutton);
registerForContextMenu(changeButton);
changeButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
openContextMenu(view);
}
});
((LinearLayout) findViewById(R.id.inventory_changeall)).setVisibility(View.VISIBLE);
}
}
base.showProgress(activity, false);
}
};
private Handler postLogHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg.what == 1) {
warning.showToast(res.getString(R.string.info_log_posted));
if (waitDialog != null) {
waitDialog.dismiss();
}
finish();
return;
} else if (msg.what == 2) {
warning.showToast(res.getString(R.string.info_log_saved));
if (waitDialog != null) {
waitDialog.dismiss();
}
finish();
return;
} else if (msg.what >= 1000) {
if (msg.what == 1001) {
warning.showToast(res.getString(R.string.warn_log_text_fill));
} else if (msg.what == 1002) {
warning.showToast(res.getString(R.string.err_log_failed_server));
} else {
warning.showToast(res.getString(R.string.err_log_post_failed));
}
} else {
if (Base.errorRetrieve.get(msg.what) != null) {
warning.showToast(res.getString(R.string.err_log_post_failed_because) + " " + Base.errorRetrieve.get(msg.what) + ".");
} else {
warning.showToast(res.getString(R.string.err_log_post_failed));
}
}
if (waitDialog != null) {
waitDialog.dismiss();
}
}
};
@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.visit);
base.setTitle(activity, res.getString(R.string.log_new_log));
// google analytics
base.sendAnal(activity, "/visit");
// get parameters
Bundle extras = getIntent().getExtras();
if (extras != null) {
cacheid = extras.getString("id");
geocode = extras.getString("geocode");
text = extras.getString("text");
alreadyFound = extras.getBoolean("found");
}
if ((cacheid == null || cacheid.length() == 0) && geocode != null && geocode.length() > 0) {
cacheid = app.getCacheid(geocode);
}
if ((geocode == null || geocode.length() == 0) && cacheid != null && cacheid.length() > 0) {
geocode = app.getGeocode(cacheid);
}
cache = app.getCacheByGeocode(geocode);
if (cache.name != null && cache.name.length() > 0) {
base.setTitle(activity, res.getString(R.string.log_new_log) + " " + cache.name);
} else {
base.setTitle(activity, res.getString(R.string.log_new_log) + " " + cache.geocode.toUpperCase());
}
app.setAction(geocode);
if (cache == null) {
warning.showToast(res.getString(R.string.err_detail_cache_forgot_visit));
finish();
return;
}
init();
}
@Override
public void onResume() {
super.onResume();
settings.load();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
init();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
SubMenu subMenu = null;
subMenu = menu.addSubMenu(0, 0, 0, res.getString(R.string.log_add)).setIcon(android.R.drawable.ic_menu_add);
subMenu.add(0, LOG_DATE_TIME, 0, res.getString(R.string.log_date_time));
subMenu.add(0, LOG_DATE, 0, res.getString(R.string.log_date));
subMenu.add(0, LOG_TIME, 0, res.getString(R.string.log_time));
subMenu.add(0, LOG_SIGNATURE, 0, res.getString(R.string.init_signature));
subMenu.add(0, LOG_SIGNATURE_DATE_TIME, 0, res.getString(R.string.log_date_time) + " & " + res.getString(R.string.init_signature));
return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if (settings.getSignature() == null) {
menu.findItem(LOG_SIGNATURE).setVisible(false);
menu.findItem(LOG_SIGNATURE_DATE_TIME).setVisible(false);
} else {
menu.findItem(LOG_SIGNATURE).setVisible(true);
menu.findItem(LOG_SIGNATURE_DATE_TIME).setVisible(true);
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if ((id >= LOG_SIGNATURE && id <= LOG_SIGNATURE_DATE_TIME)) {
addSignature(id);
return true;
}
return false;
}
public void addSignature(int id) {
EditText text = null;
String textContent = null;
String dateString = null;
String timeString = null;
StringBuilder addText = new StringBuilder();
text = (EditText) findViewById(R.id.log);
textContent = text.getText().toString();
dateString = Base.dateOut.format(new Date());
timeString = Base.timeOut.format(new Date());
if ((id & LOG_DATE) == LOG_DATE) {
addText.append(dateString);
if ((id & LOG_TIME) == LOG_TIME) {
addText.append(" | ");
}
}
if ((id & LOG_TIME) == LOG_TIME) {
addText.append(timeString);
}
if ((id & LOG_SIGNATURE) == LOG_SIGNATURE && settings.getSignature() != null) {
String findCount = "";
if (addText.length() > 0) {
addText.append("\n");
}
if (settings.getSignature().contains("[NUMBER]") == true) {
final HashMap<String, String> params = new HashMap<String, String>();
final String page = base.request(false, "www.geocaching.com", "/my/", "GET", params, false, false, false).getData();
int current = base.parseFindCount(page);
if (current >= 0) {
findCount = "" + (current + 1);
}
}
String signature = settings.getSignature()
.replaceAll("\\[DATE\\]", dateString)
.replaceAll("\\[TIME\\]", timeString)
.replaceAll("\\[USER\\]", settings.getUsername())
.replaceAll("\\[NUMBER\\]", findCount);
addText.append(signature);
}
final String addTextDone;
if (textContent.length() > 0 && addText.length() > 0 ) {
addTextDone = textContent + "\n" + addText.toString();
} else {
addTextDone = textContent + addText.toString();
}
text.setText(addTextDone, TextView.BufferType.NORMAL);
text.setSelection(text.getText().toString().length());
}
@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.type) {
for (final int typeOne : types) {
menu.add(viewId, typeOne, 0, Base.logTypes2.get(typeOne));
Log.w(Settings.tag, "Addig " + typeOne + " " + Base.logTypes2.get(typeOne));
}
} else if (viewId == R.id.changebutton) {
final int textId = ((TextView) findViewById(viewId)).getId();
menu.setHeaderTitle(res.getString(R.string.log_tb_changeall));
for (final int logTbAction : Base.logTypesTrackable.keySet()) {
menu.add(textId, logTbAction, 0, Base.logTypesTrackable.get(logTbAction));
}
} else {
final int realViewId = ((LinearLayout) findViewById(viewId)).getId();
for (final TrackableLog tb : trackables) {
if (tb.id == realViewId) {
menu.setHeaderTitle(tb.name);
}
}
for (final int logTbAction : Base.logTypesTrackable.keySet()) {
menu.add(realViewId, logTbAction, 0, Base.logTypesTrackable.get(logTbAction));
}
}
}
@Override
public boolean onContextItemSelected(MenuItem item) {
final int group = item.getGroupId();
final int id = item.getItemId();
if (group == R.id.type) {
setType(id);
return true;
} else if (group == R.id.changebutton) {
try {
final String logTbAction = Base.logTypesTrackable.get(id);
if (logTbAction != null) {
final LinearLayout inventView = (LinearLayout) findViewById(R.id.inventory);
for (int count = 0; count < inventView.getChildCount(); count++) {
final LinearLayout tbView = (LinearLayout) inventView.getChildAt(count);
if (tbView == null) {
return false;
}
final TextView tbText = (TextView) tbView.findViewById(R.id.action);
if (tbText == null) {
return false;
}
tbText.setText(logTbAction);
}
for (TrackableLog tb : trackables) {
tb.action = id;
}
tbChanged = true;
return true;
}
} catch (Exception e) {
Log.e(Settings.tag, "cgeovisit.onContextItemSelected: " + e.toString());
}
} else {
try {
final String logTbAction = Base.logTypesTrackable.get(id);
if (logTbAction != null) {
final LinearLayout tbView = (LinearLayout) findViewById(group);
if (tbView == null) {
return false;
}
final TextView tbText = (TextView) tbView.findViewById(R.id.action);
if (tbText == null) {
return false;
}
for (TrackableLog tb : trackables) {
if (tb.id == group) {
tbChanged = true;
tb.action = id;
tbText.setText(logTbAction);
Log.i(Settings.tag, "Trackable " + tb.trackCode + " (" + tb.name + ") has new action: #" + id);
}
}
return true;
}
} catch (Exception e) {
Log.e(Settings.tag, "cgeovisit.onContextItemSelected: " + e.toString());
}
}
return false;
}
public void init() {
if (geocode != null) {
app.setAction(geocode);
}
types.clear();
if (cache.type.equals("event") || cache.type.equals("mega") || cache.type.equals("cito") || cache.type.equals("lostfound")) {
types.add(Base.LOG_WILL_ATTEND);
types.add(Base.LOG_NOTE);
types.add(Base.LOG_ATTENDED);
types.add(Base.LOG_NEEDS_ARCHIVE);
} else if (cache.type.equals("earth")) {
types.add(Base.LOG_FOUND_IT);
types.add(Base.LOG_DIDNT_FIND_IT);
types.add(Base.LOG_NOTE);
types.add(Base.LOG_NEEDS_MAINTENANCE);
types.add(Base.LOG_NEEDS_ARCHIVE);
} else if (cache.type.equals("webcam")) {
types.add(Base.LOG_WEBCAM_PHOTO_TAKEN);
types.add(Base.LOG_DIDNT_FIND_IT);
types.add(Base.LOG_NOTE);
types.add(Base.LOG_NEEDS_ARCHIVE);
types.add(Base.LOG_NEEDS_MAINTENANCE);
} else {
types.add(Base.LOG_FOUND_IT);
types.add(Base.LOG_DIDNT_FIND_IT);
types.add(Base.LOG_NOTE);
types.add(Base.LOG_NEEDS_ARCHIVE);
types.add(Base.LOG_NEEDS_MAINTENANCE);
}
if (cache.owner.equalsIgnoreCase(settings.getUsername()) == true) {
types.add(Base.LOG_OWNER_MAINTENANCE);
types.add(Base.LOG_TEMP_DISABLE_LISTING);
types.add(Base.LOG_ENABLE_LISTING);
types.add(Base.LOG_ARCHIVE);
types.remove(new Integer(Base.LOG_UPDATE_COORDINATES));
if (cache.type.equals("event") || cache.type.equals("mega") || cache.type.equals("cito") || cache.type.equals("lostfound")) {
types.add(Base.LOG_ANNOUNCEMENT);
}
}
final CacheLog log = app.loadLogOffline(geocode);
if (log != null) {
typeSelected = log.type;
date.setTime(new Date(log.date));
text = log.log;
} else if (settings.getSignature() != null && settings.getSignature().length() > 0) {
addSignature(LOG_SIGNATURE);
}
if (types.contains(typeSelected) == false) {
if (alreadyFound == true) {
typeSelected = Base.LOG_NOTE;
} else {
typeSelected = types.get(0);
}
setType(typeSelected);
}
Button typeButton = (Button) findViewById(R.id.type);
registerForContextMenu(typeButton);
typeButton.setText(Base.logTypes2.get(typeSelected));
typeButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
openContextMenu(view);
}
});
Button dateButton = (Button) findViewById(R.id.date);
dateButton.setText(Base.dateOutShort.format(date.getTime()));
dateButton.setOnClickListener(new cgeovisitDateListener());
EditText logView = (EditText) findViewById(R.id.log);
if (logView.getText().length() == 0 && text != null && text.length() > 0) {
logView.setText(text);
}
if (post == null) {
post = (Button) findViewById(R.id.post);
}
if (viewstate == null || viewstate.length() == 0) {
post.setEnabled(false);
post.setOnTouchListener(null);
post.setOnClickListener(null);
loadData thread;
thread = new loadData(cacheid);
thread.start();
} else {
post.setEnabled(true);
post.setOnClickListener(new postListener());
}
if (save == null) {
save = (Button) findViewById(R.id.save);
}
save.setOnClickListener(new saveListener());
if (clear == null) {
clear = (Button) findViewById(R.id.clear);
}
clear.setOnClickListener(new clearListener());
}
@Override
public void setDate(Calendar dateIn) {
date = dateIn;
final Button dateButton = (Button) findViewById(R.id.date);
dateButton.setText(Base.dateOutShort.format(date.getTime()));
}
public void setType(int type) {
final Button typeButton = (Button) findViewById(R.id.type);
if (Base.logTypes2.get(type) != null) {
typeSelected = type;
}
if (Base.logTypes2.get(typeSelected) == null) {
typeSelected = 1;
}
typeButton.setText(Base.logTypes2.get(typeSelected));
if (type == 2 && tbChanged == false) {
// TODO: change action
} else if (type != 2 && tbChanged == false) {
// TODO: change action
}
if (post == null) {
post = (Button) findViewById(R.id.post);
}
}
private class cgeovisitDateListener implements View.OnClickListener {
public void onClick(View arg0) {
Dialog dateDialog = new date(activity, (cacheLog) activity, date);
dateDialog.setCancelable(true);
dateDialog.show();
}
}
private class postListener implements View.OnClickListener {
public void onClick(View arg0) {
if (gettingViewstate == false) {
waitDialog = ProgressDialog.show(activity, null, res.getString(R.string.log_saving), true);
waitDialog.setCancelable(true);
String log = ((EditText) findViewById(R.id.log)).getText().toString();
Thread thread = new postLog(postLogHandler, log);
thread.start();
} else {
warning.showToast(res.getString(R.string.err_log_load_data_still));
}
}
}
private class saveListener implements View.OnClickListener {
public void onClick(View arg0) {
String log = ((EditText) findViewById(R.id.log)).getText().toString();
final boolean status = app.saveLogOffline(geocode, date.getTime(), typeSelected, log);
if (save == null) {
save = (Button) findViewById(R.id.save);
}
save.setOnClickListener(new saveListener());
if (status == true) {
warning.showToast(res.getString(R.string.info_log_saved));
app.saveVisitDate(geocode);
} else {
warning.showToast(res.getString(R.string.err_log_post_failed));
}
}
}
private class clearListener implements View.OnClickListener {
public void onClick(View arg0) {
app.clearLogOffline(geocode);
if (alreadyFound == true) {
typeSelected = Base.LOG_NOTE;
} else {
typeSelected = types.get(0);
}
date.setTime(new Date());
text = null;
setType(typeSelected);
Button dateButton = (Button) findViewById(R.id.date);
dateButton.setText(Base.dateOutShort.format(date.getTime()));
dateButton.setOnClickListener(new cgeovisitDateListener());
EditText logView = (EditText) findViewById(R.id.log);
if (text != null && text.length() > 0) {
logView.setText(text);
} else {
logView.setText("");
}
if (clear == null) {
clear = (Button) findViewById(R.id.clear);
}
clear.setOnClickListener(new clearListener());
warning.showToast(res.getString(R.string.info_log_cleared));
}
}
private class loadData extends Thread {
private String cacheid = null;
public loadData(String cacheidIn) {
cacheid = cacheidIn;
if (cacheid == null) {
warning.showToast(res.getString(R.string.err_detail_cache_forgot_visit));
finish();
return;
}
}
@Override
public void run() {
final HashMap<String, String> params = new HashMap<String, String>();
showProgressHandler.sendEmptyMessage(0);
gettingViewstate = true;
attempts++;
try {
if (cacheid != null && cacheid.length() > 0) {
params.put("ID", cacheid);
} else {
loadDataHandler.sendEmptyMessage(0);
return;
}
final String page = base.request(false, "www.geocaching.com", "/seek/log.aspx", "GET", params, false, false, false).getData();
viewstate = base.findViewstate(page, 0);
viewstate1 = base.findViewstate(page, 1);
trackables = base.parseTrackableLog(page);
final ArrayList<Integer> typesPre = base.parseTypes(page);
if (typesPre.size() > 0) {
types.clear();
types.addAll(typesPre);
types.remove(new Integer(Base.LOG_UPDATE_COORDINATES));
}
typesPre.clear();
} catch (Exception e) {
Log.e(Settings.tag, "cgeovisit.loadData.run: " + e.toString());
}
loadDataHandler.sendEmptyMessage(0);
}
}
private class postLog extends Thread {
Handler handler = null;
String log = null;
public postLog(Handler handlerIn, String logIn) {
handler = handlerIn;
log = logIn;
}
@Override
public void run() {
int ret = -1;
ret = postLogFn(log);
handler.sendEmptyMessage(ret);
}
}
public int postLogFn(String log) {
int status = -1;
try {
status = base.postLog(app, geocode, cacheid, viewstate, viewstate1, typeSelected, date.get(Calendar.YEAR), (date.get(Calendar.MONTH) + 1), date.get(Calendar.DATE), log, trackables);
if (status == 1) {
CacheLog logNow = new CacheLog();
logNow.author = settings.getUsername();
logNow.date = date.getTimeInMillis();
logNow.type = typeSelected;
logNow.log = log;
cache.logs.add(0, logNow);
app.addLog(geocode, logNow);
if (typeSelected == Base.LOG_FOUND_IT) {
app.markFound(geocode);
if (cache != null) {
cache.found = true;
}
}
if (cache != null) {
app.putCacheInCache(cache);
} else {
app.removeCacheFromCache(geocode);
}
}
if (status == 1) {
app.clearLogOffline(geocode);
}
return status;
} catch (Exception e) {
Log.e(Settings.tag, "cgeovisit.postLogFn: " + e.toString());
}
return 1000;
}
public void goHome(View view) {
base.goHome(activity);
}
}