package org.djd.busntrain.bus;
import java.util.ArrayList;
import org.djd.busntrain.R;
import org.djd.busntrain.bus.BusPredictions.Prediction;
import org.djd.busntrain.commons.StringUtil;
import org.djd.busntrain.commons.XmlUtilException;
import org.djd.busntrain.provider.BusFavoriteContentProvider;
import android.app.ListActivity;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
public class BusPredictionActivity extends ListActivity {
private static final String TAG = BusPredictionActivity.class.getSimpleName();
private static final String SAVE_PREDICTION_INFO_KEY = "SAVE_PREDICTION_INFO";
private static final String SAVE_LAST_UPDATE_TIME_KEY = "SAVE_LAST_UPDATE_TIME_KEY";
private static final String SAVE_STAR_ON_KEY = "SAVE_STAR_ON_KEY";
private static final String SAVE_STAR_OFF_KEY = "SAVE_STAR_OFF_KEY";
private static final int[] VIEW_PREDICTION_ID_ARRAY = new int[]{R.id.prediction_wait_time_in_minutes,
R.id.prediction_prediction_time, R.id.prediction_vehicle_id, R.id.prediction_route,
R.id.prediction_destination};
private BusPredictionActivityBroadcastReceiver receiver;
private ArrayList<Prediction> predictions;
private long lastUpdateTime;
private TextView lastUpdateTimeTextView;
private ImageButton starOnImageButton;
private ImageButton starOffImageButton;
private BusFavoriteEntity busFavoriteEntity;
@SuppressWarnings("unchecked")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.prediction_list_view);
lastUpdateTimeTextView = (TextView) findViewById(R.id.last_update_time);
View.OnClickListener clickLIstener = new StarButtonClickLIstener();
starOnImageButton = (ImageButton) findViewById(R.id.btn_favorite_star_on);
starOnImageButton.setOnClickListener(clickLIstener);
starOffImageButton = (ImageButton) findViewById(R.id.btn_favorite_star_off);
starOffImageButton.setOnClickListener(clickLIstener);
receiver = new BusPredictionActivityBroadcastReceiver();
if (null != savedInstanceState) {
predictions = (ArrayList<Prediction>) savedInstanceState.getSerializable(SAVE_PREDICTION_INFO_KEY);
lastUpdateTime = savedInstanceState.getLong(SAVE_LAST_UPDATE_TIME_KEY);
busFavoriteEntity = (BusFavoriteEntity) savedInstanceState
.getSerializable(BusFavoriteEntity.BUS_FAVORITE_ENTITY_EXTRA_DATA_KEY);
starOnImageButton.setVisibility(savedInstanceState.getInt(SAVE_STAR_ON_KEY));
starOffImageButton.setVisibility(savedInstanceState.getInt(SAVE_STAR_OFF_KEY));
displayListItems();
} else {
Intent payload = getIntent();
if (null == payload) {
throw new IllegalArgumentException("route and direction is required.");
}
busFavoriteEntity = (BusFavoriteEntity) payload
.getSerializableExtra(BusFavoriteEntity.BUS_FAVORITE_ENTITY_EXTRA_DATA_KEY);
callBusPredictionService();
checkFavorite();
Toast.makeText(this, R.string.toast_getting_predictions, Toast.LENGTH_SHORT).show();
}
TextView directionTextView = (TextView) findViewById(R.id.prediction_direction);
directionTextView.setText(busFavoriteEntity.direction);
TextView stopNameTextView = (TextView) findViewById(R.id.prediction_stop_name);
stopNameTextView.setText(busFavoriteEntity.stopName);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable(SAVE_PREDICTION_INFO_KEY, predictions);
outState.putLong(SAVE_LAST_UPDATE_TIME_KEY, lastUpdateTime);
outState.putSerializable(BusFavoriteEntity.BUS_FAVORITE_ENTITY_EXTRA_DATA_KEY, busFavoriteEntity);
outState.putInt(SAVE_STAR_ON_KEY, starOnImageButton.getVisibility());
outState.putInt(SAVE_STAR_OFF_KEY, starOffImageButton.getVisibility());
Log.i(TAG, "Saving activity state.");
}
@Override
protected void onResume() {
super.onResume();
super.registerReceiver(receiver, receiver.intentFilter);
}
@Override
protected void onPause() {
super.onPause();
if (null != receiver) {
super.unregisterReceiver(receiver);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
protected void onListItemClick(ListView listView, View v, int position, long id) {
super.onListItemClick(listView, v, position, id);
Toast.makeText(this, R.string.msg_refresh, Toast.LENGTH_SHORT).show();
callBusPredictionService();
}
private void callBusPredictionService() {
Intent intent = new Intent(this, BusPredictionService.class);
intent.putExtra(BusFavoriteEntity.BUS_FAVORITE_ENTITY_EXTRA_DATA_KEY, busFavoriteEntity);
startService(intent);
}
private void checkFavorite() {
String where = String.format("%s=? and %s=?", BusFavoriteEntity.Columns.ROUTE, BusFavoriteEntity.Columns.STOP_ID);
String whereArgs[] = new String[]{busFavoriteEntity.route, busFavoriteEntity.stopId};
Cursor cursor = managedQuery(BusFavoriteContentProvider.CONTENT_URI, BusFavoriteEntity.Columns.FULL_PROJECTION,
where, whereArgs, BusFavoriteEntity.Columns._ID);
if (1 == cursor.getCount()) {
busFavoriteEntity = BusFavoriteEntity.Helper.createBusFavoriteEntity(cursor, 0);
if (isFavorite()) {
Log.i(TAG, "Star is already shining.");
} else {
toggle();
}
}
}
private void displayListItems() {
ListAdapter listAdapter = new SimpleAdapter(this, predictions, R.layout.prediction_list_item_view,
Prediction.COLUMNS, VIEW_PREDICTION_ID_ARRAY);
lastUpdateTime = System.currentTimeMillis();
lastUpdateTimeTextView.setText(StringUtil.timeToString(this, lastUpdateTime));
setListAdapter(listAdapter);
}
/**
* This is workaround to get imageButton toggle feature.
* <p/>
* TODO improve image button toggle code.
* <p/>
* Also, save the BusDto to Database
*/
public class StarButtonClickLIstener implements OnClickListener {
@Override
public void onClick(View v) {
if (isFavorite()) {
removeStar();
} else {
addStar();
}
toggle();
}
private void addStar() {
ContentResolver contentResolver = getContentResolver();
contentResolver.insert(BusFavoriteContentProvider.CONTENT_URI, busFavoriteEntity.getContentValuesForInsert());
}
private void removeStar() {
ContentResolver contentResolver = getContentResolver();
Uri uri = Uri.withAppendedPath(BusFavoriteContentProvider.CONTENT_URI, String.valueOf(busFavoriteEntity.id));
contentResolver.delete(uri, null, null);
}
}
private boolean isFavorite() {
return Button.VISIBLE == starOnImageButton.getVisibility();
}
private void toggle() {
int visibility = starOnImageButton.getVisibility();
starOnImageButton.setVisibility(starOffImageButton.getVisibility());
starOffImageButton.setVisibility(visibility);
}
/**
* Callback handler receives category list data from database.
*/
public class BusPredictionActivityBroadcastReceiver extends BroadcastReceiver {
public static final String ACTION_RESPONSE = "org.djd.busntrain.bus.BusPredictionActivityBroadcastReceiver";
public static final String XML_DATA_TXT = "XML_DATA_TXT";
public final IntentFilter intentFilter;
public BusPredictionActivityBroadcastReceiver() {
intentFilter = new IntentFilter(ACTION_RESPONSE);
intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
}
@Override
public void onReceive(Context context, Intent intent) {
String result = "Completed Download and Updated Database.";
Toast.makeText(BusPredictionActivity.this, result, Toast.LENGTH_SHORT).show();
String xmlDataTxt = intent.getStringExtra(XML_DATA_TXT);
try {
predictions = BusPredictions.parseValue(xmlDataTxt);
} catch (XmlUtilException e) {
throw new RuntimeException(e);
}
displayListItems();
}
}
}