package com.evancharlton.mileage;
import com.evancharlton.mileage.adapters.VehicleStatisticsAdapter;
import com.evancharlton.mileage.dao.CachedValue;
import com.evancharlton.mileage.dao.Vehicle;
import com.evancharlton.mileage.provider.Statistic;
import com.evancharlton.mileage.provider.Statistics;
import com.evancharlton.mileage.provider.StatisticsGroup;
import com.evancharlton.mileage.provider.tables.CacheTable;
import com.evancharlton.mileage.provider.tables.VehiclesTable;
import com.evancharlton.mileage.tasks.VehicleStatisticsTask;
import android.app.Activity;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.Toast;
public class VehicleStatisticsActivity extends Activity {
private static final String TAG = "VehicleStatisticsActivity";
private static final Statistic[] ECONOMIES = {
Statistics.AVG_ECONOMY, Statistics.MIN_ECONOMY, Statistics.MAX_ECONOMY
};
private static final Statistic[] DISTANCES = {
Statistics.AVG_DISTANCE, Statistics.MIN_DISTANCE, Statistics.MAX_DISTANCE
};
private static final Statistic[] COSTS = {
Statistics.AVG_COST, Statistics.MIN_COST, Statistics.MAX_COST, Statistics.TOTAL_COST,
Statistics.LAST_MONTH_COST, Statistics.AVG_MONTHLY_COST, Statistics.LAST_YEAR_COST,
Statistics.AVG_YEARLY_COST
};
private static final Statistic[] COSTS_PER_DISTANCE = {
Statistics.AVG_COST_PER_DISTANCE, Statistics.MIN_COST_PER_DISTANCE,
Statistics.MAX_COST_PER_DISTANCE
};
private static final Statistic[] PRICES = {
Statistics.AVG_PRICE, Statistics.MIN_PRICE, Statistics.MAX_PRICE
};
private static final Statistic[] CONSUMPTIONS = {
Statistics.MIN_FUEL, Statistics.MAX_FUEL, Statistics.AVG_FUEL, Statistics.TOTAL_FUEL,
Statistics.FUEL_PER_YEAR
};
private static final Statistic[] LOCATIONS = {
Statistics.NORTH, Statistics.SOUTH, Statistics.EAST, Statistics.WEST
};
private static final StatisticsGroup[] GROUPS = {
new StatisticsGroup(R.string.stat_fuel_economy, ECONOMIES),
new StatisticsGroup(R.string.stat_distance_between_fillups, DISTANCES),
new StatisticsGroup(R.string.stat_fillup_cost, COSTS),
new StatisticsGroup(R.string.stat_cost_per_distance, COSTS_PER_DISTANCE),
new StatisticsGroup(R.string.stat_price, PRICES),
new StatisticsGroup(R.string.stat_fuel, CONSUMPTIONS),
new StatisticsGroup(R.string.stat_location, LOCATIONS)
};
private final Vehicle mVehicle = new Vehicle(new ContentValues());
private Spinner mVehicleSpinner;
private ListView mListView;
private VehicleStatisticsTask mCalculationTask = null;
private LinearLayout mContainer;
private ProgressBar mProgressBar;
private ImageView mCancel;
private VehicleStatisticsAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.vehicle_statistics);
Object[] saved = (Object[]) getLastNonConfigurationInstance();
if (saved != null) {
mCalculationTask = (VehicleStatisticsTask) saved[0];
mAdapter = null;
}
if (mCalculationTask != null) {
mCalculationTask.attach(this);
}
mListView = (ListView) findViewById(android.R.id.list);
mVehicleSpinner = (Spinner) findViewById(R.id.vehicle);
mContainer = (LinearLayout) findViewById(R.id.progress_container);
mProgressBar = (ProgressBar) findViewById(R.id.progress);
mCancel = (ImageView) findViewById(R.id.cancel);
mVehicleSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> list, View row, int position, long id) {
if (mVehicle.getId() != id) {
loadVehicle();
cancelTask();
recalculate();
}
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
}
});
loadVehicle();
recalculate();
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> list, View row, int position, long id) {
position -= mAdapter.getNumHeadersAbove(position);
Statistic statistic = Statistics.STATISTICS.get(position);
Class<? extends ChartActivity> target = statistic.getChartClass();
if (target != null) {
Intent intent = new Intent(VehicleStatisticsActivity.this, target);
intent.putExtra(ChartActivity.VEHICLE_ID, String.valueOf(mVehicle.getId()));
startActivity(intent);
} else {
Toast.makeText(VehicleStatisticsActivity.this, getString(R.string.no_chart),
Toast.LENGTH_SHORT).show();
}
}
});
mCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
cancelTask();
}
});
}
@Override
protected void onResume() {
super.onResume();
loadVehicle();
recalculate();
}
private void recalculate() {
Log.d(TAG, "Checking recalculation ...");
Cursor c = getCacheCursor();
if (c.getCount() < Statistics.STATISTICS.size()) {
calculate();
Log.d(TAG, "Recalculation started!");
} else {
Log.d(TAG, "Recalculation not necessary.");
}
setAdapter(c);
}
private void cancelTask() {
if (mCalculationTask != null && mCalculationTask.getStatus() == AsyncTask.Status.RUNNING) {
mCalculationTask.cancel(true);
}
}
public Cursor getCacheCursor() {
return managedQuery(CacheTable.BASE_URI, CacheTable.PROJECTION, CachedValue.ITEM
+ " = ? and " + CachedValue.VALID + " = ?", new String[] {
String.valueOf(mVehicle.getId()), "1"
}, CachedValue.GROUP + " asc, " + CachedValue.ORDER + " asc");
}
public ProgressBar getProgressBar() {
return mProgressBar;
}
public void setAdapter(Cursor c) {
if (mAdapter == null) {
mAdapter = new VehicleStatisticsAdapter(this, mVehicle, GROUPS);
}
mAdapter.changeCursor(c);
mListView.setAdapter(mAdapter);
mAdapter.notifyDataSetChanged();
}
private void calculate() {
Log.d(TAG, "Recalculating statistics");
mCalculationTask = new VehicleStatisticsTask();
mCalculationTask.attach(this);
mCalculationTask.execute();
}
@Override
public Object onRetainNonConfigurationInstance() {
return new Object[] {
mCalculationTask, mAdapter
};
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(Menu.NONE, 1, Menu.NONE, "Recalculate").setIcon(R.drawable.ic_menu_recalculate);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case 1:
calculate();
return true;
}
return super.onOptionsItemSelected(item);
}
private void loadVehicle() {
long id = mVehicleSpinner.getSelectedItemId();
Uri uri = ContentUris.withAppendedId(VehiclesTable.BASE_URI, id);
Cursor vehicle = managedQuery(uri, VehiclesTable.PROJECTION, null, null, null);
vehicle.moveToFirst();
mVehicle.load(vehicle);
}
public Vehicle getVehicle() {
return mVehicle;
}
public VehicleStatisticsAdapter getAdapter() {
return mAdapter;
}
public void startCalculations() {
mContainer.setVisibility(View.VISIBLE);
mProgressBar.setIndeterminate(true);
}
public void stopCalculations() {
mContainer.setVisibility(View.GONE);
}
}