/** * Copyright (c) 2011 Christine Gerpheide <christine.ger@pheide.com> * * This code is distributed under the MIT License. Please see LICENSE.txt * for more details. */ package com.pheide.trainose; import com.pheide.trainose.FlatCharArrayAdapter; import java.util.Arrays; import android.app.Activity; import android.app.ProgressDialog; import android.content.Intent; import android.database.Cursor; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.CheckBox; import android.widget.Toast; /** * Class which displays the form to create or edit routes. * * @author Christine Gerpheide */ public class RouteEdit extends Activity { private static final String TAG = "RouteEdit"; private AutoCompleteTextView mSourceTextView; private AutoCompleteTextView mDestinationTextView; private CheckBox mTwoWayCheckBox; long mRouteId; Boolean mIsTwoWay; long mReversedRouteId; /** * Initialize this view */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); this.setContentView(R.layout.route_edit); this.setTitle(R.string.new_route); // Create source/destination selectors String[] stations = getResources().getStringArray(R.array.stations_array); mSourceTextView = (AutoCompleteTextView) findViewById(R.id.source); FlatCharArrayAdapter sourceAdapter = new FlatCharArrayAdapter(this, R.layout.autocomplete_item, stations); mSourceTextView.setAdapter(sourceAdapter); mDestinationTextView = (AutoCompleteTextView) findViewById(R.id.destination); FlatCharArrayAdapter destinationAdapter = new FlatCharArrayAdapter(this, R.layout.autocomplete_item, stations); mDestinationTextView.setAdapter(destinationAdapter); mTwoWayCheckBox = (CheckBox) findViewById(R.id.twoway); // Create confirm button Button confirmButton = (Button) findViewById(R.id.confirm); confirmButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { if (stationsAreValid()) { RouteEdit.this.createRoute(); } else { Toast.makeText(RouteEdit.this, R.string.invalid_stations, Toast.LENGTH_SHORT).show(); } } }); } /** * Check whether the stations entered are valid stations. * * @return boolean */ private Boolean stationsAreValid() { // Android really ought to handle this itself.. // Make sure stations entered are capitalized String sourceText = mSourceTextView.getText().toString(); String destinationText = mDestinationTextView.getText().toString(); if (sourceText.length() == 0 || destinationText.length() == 0) { return false; } // Prepare array of stations to easily check if we have a valid station String[] stationsOrig = getResources().getStringArray(R.array.stations_array); Arrays.sort(stationsOrig); String[] stations = stationsOrig.clone(); for (int i=0; i<stations.length; ++i) { stations[i] = stations[i].toLowerCase(); } String source = mSourceTextView.getText().toString().toLowerCase(); String destination = mDestinationTextView.getText().toString().toLowerCase(); int sourceIdx = Arrays.binarySearch(stations, source); int destIdx = Arrays.binarySearch(stations, destination); if (sourceIdx > 0 && destIdx > 0) { mSourceTextView.setText(stationsOrig[sourceIdx]); mDestinationTextView.setText(stationsOrig[destIdx]); return true; } else { return false; } } /** * Create a route with the stations entered by the user. */ private void createRoute() { RoutesDbAdapter routesDbAdapter = new RoutesDbAdapter(this); routesDbAdapter.open(); String source = mSourceTextView.getText().toString(); String destination = mDestinationTextView.getText().toString(); // Create route if it does not yet exist try { Cursor routeCursor = routesDbAdapter.fetchBySourceAndDestination(source,destination); this.startManagingCursor(routeCursor); mRouteId = routeCursor.getLong(routeCursor.getColumnIndex(RoutesDbAdapter.KEY_ROWID)); this.stopManagingCursor(routeCursor); } catch (Exception e) { mRouteId = routesDbAdapter.create(source,destination); } if (mTwoWayCheckBox.isChecked()) { mIsTwoWay = true; try { Cursor reversedRouteCursor = routesDbAdapter.fetchBySourceAndDestination(destination,source); this.startManagingCursor(reversedRouteCursor); mReversedRouteId = reversedRouteCursor.getLong(reversedRouteCursor.getColumnIndex(RoutesDbAdapter.KEY_ROWID)); this.stopManagingCursor(reversedRouteCursor); } catch (Exception e) { mReversedRouteId = routesDbAdapter.create(destination,source); } } routesDbAdapter.close(); this.syncRoute(); // uses callback } /** * Callback after creating a route. Close this view and * show the timetables for the route. */ private void didCreateRoute() { Intent i = new Intent(this, Timetables.class); i.putExtra(RoutesDbAdapter.KEY_ROWID, mRouteId); this.setResult(RESULT_OK,i); this.finish(); } /** * Initialize a background task to synchronize this route. */ protected void syncRoute() { new AsyncTask<Void, Void, Void>() { ProgressDialog mDialog; @Override protected void onPreExecute() { mDialog = ProgressDialog.show(RouteEdit.this, "", RouteEdit.this.getString(R.string.sync_in_progress), true); } @Override protected Void doInBackground(Void... params){ try { TimetablesSynchronizer timetablesSynchronizer = new TimetablesSynchronizer(RouteEdit.this); timetablesSynchronizer.syncTimetablesForRoute(mRouteId); if (mIsTwoWay) { timetablesSynchronizer.syncTimetablesForRoute(mReversedRouteId); } } catch (Exception e) { Log.e(TAG, "Exception syncing timetables", e); } return null; } @Override protected void onPostExecute(Void result) { mDialog.dismiss(); RouteEdit.this.didCreateRoute(); } }.execute(); } }