package co.mwater.clientapp.ui;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Random;
import android.content.ContentValues;
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.CheckBox;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
import co.mwater.clientapp.db.ImageManager;
import co.mwater.clientapp.db.ImageStorage;
import co.mwater.clientapp.db.MWaterServer;
import co.mwater.clientapp.db.SourcesTable;
import co.mwater.clientapp.dbsync.SyncTable;
import com.actionbarsherlock.app.SherlockFragmentActivity;
/**
* Activity which displays details for a particular
*
* intent must contain parameter "uri"
*
* @author Clayton
*
*/
public abstract class DetailActivity extends SherlockFragmentActivity {
private static final String TAG = DetailActivity.class.getSimpleName();
protected long id;
protected String idString;
protected Uri uri;
protected Cursor rowCursor;
protected ContentValues rowValues;
protected Handler handler;
private DetailActivityContentObserver contentObserver;
boolean started = false;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
takePhotoColumn = savedInstanceState.getString("takePhotoColumn");
takePhotoUid = savedInstanceState.getString("takePhotoUid");
}
// Create handler
handler = new Handler();
// Get uri
uri = getIntent().getParcelableExtra("uri");
idString = uri.getLastPathSegment();
id = Long.parseLong(idString);
// Load data so onCreate overrides have it
loadData();
// Listen for content changes
contentObserver = new DetailActivityContentObserver(handler);
getContentResolver().registerContentObserver(uri, true, contentObserver);
}
@Override
protected void onStart() {
super.onStart();
started = true;
displayData();
}
@Override
protected void onStop() {
started = false;
super.onStop();
}
@Override
protected void onDestroy() {
// Unregister content observer
if (contentObserver != null)
getContentResolver().unregisterContentObserver(contentObserver);
// Destroy cursor
if (rowCursor != null)
rowCursor.close();
super.onDestroy();
}
private void loadData() {
if (rowCursor != null)
rowCursor.close();
// Query to get cursor
rowCursor = getContentResolver().query(uri, null, null, null, null);
if (!rowCursor.moveToFirst())
{
// Row not found. Probaly deleted.
rowValues = null;
return;
}
// Load fields
rowValues = new ContentValues();
DatabaseUtils.cursorRowToContentValues(rowCursor, rowValues);
}
/**
* Implement this to display the record. Will be called on Start and
* whenever data is changed.
*
* @param rowCursor
* @param rowValues
*/
abstract protected void displayData();
/**
* Updates the specified value in the current row
* @param column
* @param value
*/
protected void updateRow(String column, String value) {
ContentValues values = new ContentValues();
values.put(column, value);
getContentResolver().update(uri, values, null, null);
}
/**
* Updates the specified value in the current row
* @param column
* @param value
*/
protected void updateRow(String column, int value) {
ContentValues values = new ContentValues();
values.put(column, value);
getContentResolver().update(uri, values, null, null);
}
/**
* Convenience method to set the text of preference widget
*
* @param id
* @param text
*/
protected void setPreferenceWidget(int id, String title, String summary, boolean editable) {
PreferenceWidget pw = (PreferenceWidget) findViewById(id);
pw.setTitle(title);
pw.setSummary(summary != null ? summary : "");
pw.setEditable(editable);
}
protected void setPreferenceWidget(int id, String title, String summary, Integer listValue, boolean editable) {
PreferenceWidget pw = (PreferenceWidget) findViewById(id);
pw.setTitle(title);
pw.setSummary(summary != null ? summary : "");
pw.setListValue(listValue != null ? listValue : -1);
pw.setEditable(editable);
}
/**
* Convenience method to set the text of a text view
*
* @param id
* @param text
*/
protected void setControlText(int id, String text) {
TextView textView = (TextView) findViewById(id);
textView.setText(text != null ? text : "");
}
/**
* Convenience method to get the text of a text view
*
* @param id
* @param text
*/
protected String getControlText(int id) {
TextView textView = (TextView) findViewById(id);
return textView.getText().toString();
}
/**
* Convenience method to set the editability of a text view
*
* @param id
* @param text
*/
protected void setControlTextEditable(int id, boolean editable) {
TextView textView = (TextView) findViewById(id);
textView.setEnabled(editable);
}
/**
* Convenience method to set the text of a text view
*
* @param id
* @param text
*/
protected void setControlInteger(int id, Integer integer) {
TextView textView = (TextView) findViewById(id);
textView.setText(integer == null ? "" : integer.toString());
}
/**
* Convenience method to get the text of a text view
*
* @param id
* @param text
*/
protected Integer getControlInteger(int id) {
TextView textView = (TextView) findViewById(id);
String text = textView.getText().toString();
if (text.equals(""))
return null;
return Integer.parseInt(text);
}
/**
* Convenience method to set the checkbox
*
* @param id
* @param text
*/
protected void setControlBoolean(int id, Boolean value) {
CheckBox checkBox = (CheckBox) findViewById(id);
checkBox.setChecked(value != null && value);
}
/**
* Convenience method to get the text of a text view
*
* @param id
* @param text
*/
protected boolean getControlBoolean(int id) {
CheckBox checkBox = (CheckBox) findViewById(id);
return checkBox.isChecked();
}
/**
* Determine if the record was created by me
*
* @return
*/
protected boolean isCreatedByMe() {
// Workaround for strange recurring bug
String username = MWaterServer.getUsername(this);
if (username == null)
{
Log.e(TAG, "Null username");
Intent intent = new Intent(this, SignupActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
return false;
}
return username.equals(rowValues.getAsString(SyncTable.COLUMN_CREATED_BY));
}
protected void displayImage(String imageColumn) {
String photoUid = rowValues.getAsString(imageColumn);
if (photoUid == null)
return;
try {
ImageManager.getDefault(getApplicationContext()).displayImage(photoUid, this);
} catch (IOException e) {
return;
}
}
final int TAKE_PHOTO_REQUEST_CODE = 101;
String takePhotoUid;
String takePhotoColumn;
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("takePhotoColumn", takePhotoColumn);
outState.putString("takePhotoUid", takePhotoUid);
}
protected void takePhoto(String columnPhoto) {
try {
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
takePhotoUid = ImageStorage.createUid();
takePhotoColumn = columnPhoto;
File photo = new File(ImageStorage.getTempImagePath(this, takePhotoUid));
Uri uri = Uri.fromFile(photo);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, TAKE_PHOTO_REQUEST_CODE);
} catch (IOException e) {
Toast.makeText(this, e.getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent)
{
if (requestCode == TAKE_PHOTO_REQUEST_CODE && resultCode == RESULT_OK) {
try {
ImageStorage.moveTempImageFileToPending(this, takePhotoUid);
} catch (IOException e) {
Log.e(TAG, e.getLocalizedMessage());
return;
}
// Set photo
ContentValues update = new ContentValues();
update.put(takePhotoColumn, takePhotoUid);
getContentResolver().update(uri, update, null, null);
}
super.onActivityResult(requestCode, resultCode, intent);
}
// TODO massive work needed to cache, thumbnail, etc.
protected void displayImageButton(int imageButtonId, String imageColumn, int defaultImage) {
ImageButton imageButton = (ImageButton) findViewById(imageButtonId);
String imageUid = rowValues.getAsString(imageColumn);
if (imageUid == null) {
// Use default
imageButton.setImageResource(defaultImage);
return;
}
ImageManager.getDefault(getApplicationContext()).displayThumbnailImage(imageUid, imageButton, defaultImage);
}
void handleContentChange() {
// Reload data
loadData();
// Redisplay if started
if (started && rowValues != null)
displayData();
}
class DetailActivityContentObserver extends ContentObserver {
public DetailActivityContentObserver(Handler handler) {
super(handler);
}
@Override
public void onChange(boolean selfChange) {
handleContentChange();
}
}
}