package co.mwater.clientapp.ui;
import java.util.Calendar;
import java.util.GregorianCalendar;
import android.app.AlertDialog;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.location.Location;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
import co.mwater.clientapp.LocationFinder;
import co.mwater.clientapp.LocationFinder.LocationFinderListener;
import co.mwater.clientapp.R;
import co.mwater.clientapp.db.MWaterContentProvider;
import co.mwater.clientapp.db.MWaterServer;
import co.mwater.clientapp.db.OtherCodes;
import co.mwater.clientapp.db.SamplesTable;
import co.mwater.clientapp.db.SourceNotesTable;
import co.mwater.clientapp.db.SourcesTable;
import co.mwater.clientapp.ui.map.SourceMapActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.MenuItem.OnMenuItemClickListener;
public class SourceDetailActivity extends DetailActivity implements LocationFinderListener {
private static final String TAG = SourceDetailActivity.class.getSimpleName();
LocationFinder locationFinder;
boolean setLocationFlag;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.source_detail_activity);
setLocationFlag = getIntent().getBooleanExtra("setLocation", false);
// Set up fragments
SampleListSummaryFragment sampleFragment = new SampleListSummaryFragment();
Bundle args = new Bundle();
args.putString("sourceUid", rowValues.getAsString(SourcesTable.COLUMN_UID));
sampleFragment.setArguments(args);
getSupportFragmentManager().beginTransaction()
.add(R.id.sample_list, sampleFragment).commit();
SourceNoteListSummaryFragment sourceNoteFragment = new SourceNoteListSummaryFragment();
args = new Bundle();
args.putString("sourceUid", rowValues.getAsString(SourcesTable.COLUMN_UID));
sourceNoteFragment.setArguments(args);
getSupportFragmentManager().beginTransaction()
.add(R.id.note_list, sourceNoteFragment).commit();
// Set up location service
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
locationFinder = new LocationFinder(locationManager);
}
@Override
protected void onStart() {
super.onStart();
locationFinder.addLocationListener(this);
}
@Override
protected void onStop() {
locationFinder.removeLocationListener(this);
super.onStop();
}
@Override
protected void displayData() {
if (rowValues == null)
return;
getSupportActionBar().setTitle("Source " + rowValues.getAsString(SourcesTable.COLUMN_CODE));
setControlText(R.id.name, rowValues.getAsString(SourcesTable.COLUMN_NAME));
setControlText(R.id.desc, rowValues.getAsString(SourcesTable.COLUMN_DESC));
// Look up type
String[] sourceTypes = getResources().getStringArray(R.array.source_types);
Integer sourceType = rowValues.getAsInteger(SourcesTable.COLUMN_SOURCE_TYPE);
String sourceTypeText;
if (sourceType == null)
sourceTypeText = "Unspecified";
else if (sourceType >= sourceTypes.length)
sourceTypeText = "?";
else
sourceTypeText = sourceTypes[sourceType];
setControlText(R.id.source_type, "Type: " + sourceTypeText);
displayLocation();
// Display photo
displayImageButton(R.id.photo, SourcesTable.COLUMN_PHOTO, R.drawable.camera);
// Enable/disable
((Button) findViewById(R.id.locationSet)).setEnabled(isCreatedByMe());
}
public void onPhotoClick(View v) {
String photoUid = rowValues.getAsString(SourcesTable.COLUMN_PHOTO);
if (photoUid == null) {
// Take photo
takePhoto(SourcesTable.COLUMN_PHOTO);
}
else {
// Display photo
displayImage(SourcesTable.COLUMN_PHOTO);
}
}
public void onBasicsClick(View v) {
if (isCreatedByMe())
editSource();
}
public void onAddSampleClick(View v) {
// Create sample linked to source
ContentValues values = new ContentValues();
values.put(SamplesTable.COLUMN_SOURCE, rowValues.getAsString(SourcesTable.COLUMN_UID));
values.put(SamplesTable.COLUMN_CODE, OtherCodes.getNewSampleCode(this));
values.put(SamplesTable.COLUMN_SAMPLED_ON, System.currentTimeMillis() / 1000);
values.put(SamplesTable.COLUMN_CREATED_BY, MWaterServer.getUsername(this));
Uri sampleUri = getContentResolver().insert(MWaterContentProvider.SAMPLES_URI, values);
// View sample
Intent intent = new Intent(this, SampleDetailActivity.class);
intent.putExtra("uri", sampleUri);
startActivity(intent);
}
public void onAddTestClick(View v) {
long sampleId = -1;
// Find existing sample on same day
GregorianCalendar calendar = new GregorianCalendar();
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
long startOfToday = calendar.getTimeInMillis();
Cursor samples = getContentResolver().query(MWaterContentProvider.SAMPLES_URI, null,
SamplesTable.COLUMN_SAMPLED_ON + ">? AND " + SamplesTable.COLUMN_SOURCE + "=?",
new String[] { Long.toString(startOfToday/1000), rowValues.getAsString(SourcesTable.COLUMN_UID) },
SamplesTable.COLUMN_SAMPLED_ON + " DESC");
if (samples.moveToFirst()) {
sampleId = samples.getLong(samples.getColumnIndexOrThrow(SamplesTable.COLUMN_ID));
}
samples.close();
Uri sampleUri;
if (sampleId == -1) {
// Create sample linked to source
ContentValues values = new ContentValues();
values.put(SamplesTable.COLUMN_SOURCE, rowValues.getAsString(SourcesTable.COLUMN_UID));
values.put(SamplesTable.COLUMN_CODE, OtherCodes.getNewSampleCode(this));
values.put(SamplesTable.COLUMN_SAMPLED_ON, System.currentTimeMillis() / 1000);
values.put(SamplesTable.COLUMN_CREATED_BY, MWaterServer.getUsername(this));
sampleUri = getContentResolver().insert(MWaterContentProvider.SAMPLES_URI, values);
}
else {
sampleUri = Uri.withAppendedPath(MWaterContentProvider.SAMPLES_URI, sampleId + "");
}
new TestCreator(this, sampleUri).create();
}
public void onAddNoteClick(View v) {
// Create sample linked to source
ContentValues values = new ContentValues();
values.put(SourceNotesTable.COLUMN_SOURCE, rowValues.getAsString(SourcesTable.COLUMN_UID));
values.put(SourceNotesTable.COLUMN_CREATED_ON, System.currentTimeMillis() / 1000);
values.put(SourceNotesTable.COLUMN_CREATED_BY, MWaterServer.getUsername(this));
Uri sourceNoteUri = getContentResolver().insert(MWaterContentProvider.SOURCE_NOTES_URI, values);
// View sample
Intent intent = new Intent(this, SourceNoteDetailActivity.class);
intent.putExtra("uri", sourceNoteUri);
startActivity(intent);
}
public void onLocationSetClick(View v) {
setLocationFlag = true;
attemptSetLocation();
displayLocation();
}
public void onLocationMapClick(View v) {
Intent intent = new Intent(this, SourceMapActivity.class);
intent.putExtra("latitude", rowValues.getAsDouble(SourcesTable.COLUMN_LAT));
intent.putExtra("longitude", rowValues.getAsDouble(SourcesTable.COLUMN_LONG));
startActivity(intent);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getSupportMenuInflater().inflate(R.menu.source_detail_menu, menu);
// Add listeners
menu.findItem(R.id.menu_star).setOnMenuItemClickListener(new OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
// TODO
Toast.makeText(SourceDetailActivity.this, "To do", Toast.LENGTH_SHORT).show();
return true;
}
});
menu.findItem(R.id.menu_delete).setOnMenuItemClickListener(new OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
deleteSource();
return true;
}
});
menu.findItem(R.id.menu_delete).setVisible(isCreatedByMe());
menu.findItem(R.id.menu_edit).setOnMenuItemClickListener(new OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
editSource();
return true;
}
});
menu.findItem(R.id.menu_edit).setVisible(isCreatedByMe());
menu.findItem(R.id.menu_add_sample).setOnMenuItemClickListener(new OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
SourceDetailActivity.this.onAddSampleClick(null);
return true;
}
});
return super.onCreateOptionsMenu(menu);
}
void editSource() {
Intent intent = new Intent(this, SourceEditActivity.class);
intent.putExtra("uri", uri);
startActivity(intent);
}
void deleteSource() {
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
getContentResolver().delete(uri, null, null);
finish();
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Permanently delete source?").setPositiveButton("Yes", dialogClickListener).setNegativeButton("No", null).show();
}
public void onLocationChanged(Location loc) {
Log.d(TAG, String.format("onLocationChanged: acc=%f", loc.getAccuracy()));
// If waiting to set location and sufficient accuracy and time
if (setLocationFlag)
attemptSetLocation();
displayLocation();
}
private void attemptSetLocation() {
Location lastLocation = locationFinder.getLastLocation();
if (lastLocation == null)
return;
long age = System.currentTimeMillis() - lastLocation.getTime();
// If recent (<2 min) and close
if (lastLocation.getAccuracy() < 100 && age < 1000 * 60 * 2)
{
ContentValues values = new ContentValues();
values.put(SourcesTable.COLUMN_LAT, lastLocation.getLatitude());
values.put(SourcesTable.COLUMN_LONG, lastLocation.getLongitude());
getContentResolver().update(uri, values, null, null);
setLocationFlag = false;
return;
}
}
private void displayLocation() {
((Button) findViewById(R.id.locationMap)).setEnabled(hasLocation());
if (setLocationFlag) {
setControlText(R.id.locationText, "Setting location");
((ProgressBar) findViewById(R.id.locationProgress)).setVisibility(View.VISIBLE);
setControlText(R.id.accuracy, "");
return;
}
if (hasLocation())
{
Location lastLocation = locationFinder.getLastLocation();
if (lastLocation != null) {
double lat = rowValues.getAsDouble(SourcesTable.COLUMN_LAT);
double dlat = lat - lastLocation.getLatitude();
double dlong = rowValues.getAsDouble(SourcesTable.COLUMN_LONG) - lastLocation.getLongitude();
// Convert to relative position (approximate)
double dy = dlat / 57.3 * 6371000;
double dx = Math.cos(lat / 57.3) * dlong / 57.3 * 6371000;
// Determine direction and angle
double dist = Math.sqrt(dx * dx + dy * dy);
double angle = 90 - (Math.atan2(dy, dx) * 57.3);
if (angle < 0)
angle += 360;
if (angle > 360)
angle -= 360;
// Get approximate direction
int compassDir = ((int) ((angle + 22.5) / 45)) % 8;
String[] compassStrs = new String[] { "N", "NE", "E", "SE", "S", "SW", "W", "NW" };
if (dist > 1000)
setControlText(R.id.locationText, String.format("%.1fkm %s from here", dist / 1000, compassStrs[compassDir]));
else
setControlText(R.id.locationText, String.format("%.0fm %s from here", dist, compassStrs[compassDir]));
((ProgressBar) findViewById(R.id.locationProgress)).setVisibility(View.GONE);
setControlText(R.id.accuracy, String.format("+/- %.1f", lastLocation.getAccuracy()));
}
else {
setControlText(R.id.locationText, "Waiting for GPS");
((ProgressBar) findViewById(R.id.locationProgress)).setVisibility(View.VISIBLE);
setControlText(R.id.accuracy, "");
}
}
else {
setControlText(R.id.locationText, "Unspecified");
((ProgressBar) findViewById(R.id.locationProgress)).setVisibility(View.GONE);
setControlText(R.id.accuracy, "");
}
}
boolean hasLocation() {
return rowValues != null && (rowValues.get(SourcesTable.COLUMN_LAT)) != null && (rowValues.get(SourcesTable.COLUMN_LONG) != null);
}
}