/**
*
This file is part of the "Get There!" application for android developed
for the SFWR ENG 4G06 Capstone course in the 2014/2015 Fall/Winter
terms at McMaster University.
Copyright (C) 2015 M. Fluder, T. Miele, N. Mio, M. Ngo, and J. Rabaya
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.capstone.transit.trans_it;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Address;
import android.location.Geocoder;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.text.Editable;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.maps.model.LatLng;
import com.squareup.okhttp.Call;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.Locale;
public class TripPlannerActivity extends ListActivity {
public static final String TAG = TripPlannerActivity.class.getSimpleName();
private Step[] mStep;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_trip_planner);
final AutoCompleteTextView Start = (AutoCompleteTextView) findViewById(R.id.Start);
final AutoCompleteTextView End = (AutoCompleteTextView) findViewById(R.id.End);
Start.setAdapter(new PlacesAutoCompleteAdapter(this, R.layout.trip_list_item));
End.setAdapter(new PlacesAutoCompleteAdapter(this, R.layout.trip_list_item));
final Button ShowOnMap = (Button) findViewById(R.id.ShowMapB);
final ImageView favButton = (ImageView) findViewById(R.id.favButton);
final ImageView reverseButton = (ImageView) findViewById(R.id.reverseButton);
final Button loadDirectionsButton = (Button) findViewById(R.id.loadDirectionsButton);
FavoritesManager.LoadFavorites(this);
Intent myIntent = getIntent();
Start.setText(myIntent.getStringExtra("EXTRA_TRIP_START"));
End.setText(myIntent.getStringExtra("EXTRA_TRIP_END"));
ShowOnMap.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(validAddressCheck(Start,End) == 1){
final String StartAddress,EndAddress;
StartAddress = Start.getText().toString();
EndAddress = End.getText().toString();
Intent intent = new Intent(getBaseContext(), TripDisplayActivity.class);
intent.putExtra("START_ADDRESS", StartAddress); // Passing StartAddress to next activity
intent.putExtra("END_ADDRESS", EndAddress); // Passing EndAddress to next activity
startActivity(intent);
}
}
});
loadDirectionsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Trying to hide the dial pad afterwards. It worked once. Never again.
InputMethodManager inputManager = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(loadDirectionsButton.getApplicationWindowToken(), 0);
if(validAddressCheck(Start,End) == 1){
double[] StartCoordinates, EndCoordinates;
StartCoordinates = getFromLocation(Start.getText().toString());
EndCoordinates = getFromLocation(End.getText().toString());
LatLng origin = new LatLng(StartCoordinates[0], StartCoordinates[1]);
LatLng dest = new LatLng(EndCoordinates[0], EndCoordinates[1]);
getDirections(origin,dest);
StepAdapter adapter = new StepAdapter(getApplicationContext(),mStep);
setListAdapter(adapter);
}
}
});
favButton.setOnClickListener(favButtonClickListener);
reverseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Editable temp;
temp = Start.getText();
Start.setText(End.getText());
End.setText(temp);
}
});
}
public int validAddressCheck(AutoCompleteTextView Start, AutoCompleteTextView End){
final String StartAddress,EndAddress;
String startWarn = "";
String endWarn = "";
Geocoder geoCoder = new Geocoder(this, Locale.getDefault());
int signal=1;
double[] startCoordinates = new double[2];
double[] endCoordinates = new double[2];
StartAddress = Start.getText().toString();
EndAddress = End.getText().toString();
try
{
Address startAddressConvert = geoCoder.getFromLocationName(StartAddress , 1).get(0);
startCoordinates[0] = startAddressConvert.getLatitude();
startCoordinates[1] = startAddressConvert.getLongitude();
}
catch(Exception ee)
{
Log.d("RAAAAAAGE", ee.toString());
}
try
{
Address endAddressConvert = geoCoder.getFromLocationName(EndAddress , 1).get(0);
endCoordinates[0] = endAddressConvert.getLatitude();
endCoordinates[1] = endAddressConvert.getLongitude();
}
catch(Exception ee)
{
Log.d("RAAAAAAGE", ee.toString());
}
if(startCoordinates[0] == 0.0 && startCoordinates[1] == 0.0){
signal = 0;
startWarn = "Start Address";
}
if(endCoordinates[0] == 0.0 && endCoordinates[1] == 0.0){
signal = 0;
endWarn = "End Address";
if(startWarn.equals("Start Address")){
endWarn = " and End Address";
}
}
if(signal == 0){
Toast toast = Toast.makeText(TripPlannerActivity.this, "Please enter a valid " + startWarn + endWarn, Toast.LENGTH_SHORT);
toast.show();
startWarn = "";
endWarn = "";
}
return signal;
}
public double[] getFromLocation(String address){
double[] Coordinates = new double[2];
Geocoder geoCoder = new Geocoder(this, Locale.getDefault());
try{
Address addressConvert = geoCoder.getFromLocationName(address , 1).get(0);
Log.v("ADDRESS CHECK",addressConvert+"");
Coordinates[0] = addressConvert.getLatitude();
Log.v("ADDRESS CHECK", Coordinates[0]+"");
Coordinates[1] = addressConvert.getLongitude();
Log.v("ADDRESS CHECK", Coordinates[1]+"");
}
catch(Exception ee)
{
Log.d(TAG, "THERE IS AN EXCEPTION SHIz: " + ee.toString());
}
return Coordinates;
}
//JSON STUFF=========================================================================
private String getDirectionsUrl(LatLng origin,LatLng dest){
// Origin of route
String str_origin = "origin="+origin.latitude+","+origin.longitude;
// Destination of route
String str_dest = "destination="+dest.latitude+","+dest.longitude;
// Sensor enabled
String sensor = "sensor=false";
// Transit Mode
String mode = "mode=transit";
// Building the parameters to the web service
String parameters = str_origin+"&"+str_dest+"&"+mode+"&"+sensor;
// Output format
String output = "json";
// Building the url to the web service
String url = "https://maps.googleapis.com/maps/api/directions/"+output+"?"+parameters;
return url;
}
private boolean isNetworkAvailable() {
ConnectivityManager manager = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
boolean isAvailable = false;
if(networkInfo != null && networkInfo.isConnected()){
isAvailable = true;
}
return isAvailable;
}
private void alertUserAboutError() {
AlertDialogFragment dialog = new AlertDialogFragment();
dialog.show(getFragmentManager(), "error_dialog");
}
private Step[] getSteps(String jsonData) throws JSONException{
JSONObject trip = new JSONObject(jsonData);
JSONArray routes = trip.getJSONArray("routes");
JSONObject route = routes.getJSONObject(0);
JSONArray legs = route.getJSONArray("legs");
JSONObject leg = legs.getJSONObject(0);
JSONArray data = leg.getJSONArray("steps");
Step[] steps = new Step[data.length()];
for(int i = 0; i < data.length(); i++){
JSONObject jsonStep = data.getJSONObject(i);
Step step = new Step();
JSONObject stepDistance = jsonStep.getJSONObject("distance");
JSONObject stepDuration = jsonStep.getJSONObject("duration");
step.setDistance(stepDistance.getString("text"));
step.setDuration(stepDuration.getString("text"));
step.setHtmlInstructions(jsonStep.getString("html_instructions"));
steps[i] = step;
}
return steps;
}
private void getDirections(LatLng origin, LatLng destination) {
final String directionsURL = getDirectionsUrl(origin,destination);
Log.v(TAG, directionsURL);
if(isNetworkAvailable()) {
Thread T = new Thread() {
public void run() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(directionsURL)
.build();
Call call = client.newCall(request);
try {
Response response = call.execute();
String jsonData = response.body().string();
Log.v(TAG, jsonData);
if (response.isSuccessful()) {
mStep = getSteps(jsonData);
} else {
alertUserAboutError();
}
} catch (JSONException | IOException e) {
e.printStackTrace();
}
}
};
T.start();
try {
T.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
else{
Toast.makeText(this, "unavailable network", Toast.LENGTH_LONG).show();
}
}
//FAVORITES METHODS=======================================
final View.OnClickListener favButtonClickListener = new View.OnClickListener() {
@Override
public void onClick(final View v) {
final AutoCompleteTextView Start = (AutoCompleteTextView) findViewById(R.id.Start);
final AutoCompleteTextView End = (AutoCompleteTextView) findViewById(R.id.End);
if(validAddressCheck(Start,End) == 1) {
final Trip trip = new Trip(Start.getText().toString(), End.getText().toString());
//ADD THE FAVORITE
AlertDialog.Builder alert = new AlertDialog.Builder(TripPlannerActivity.this);
alert.setTitle("Add To Favorites");
alert.setMessage("Enter a small description/name to identify trip. \n(e.g. \"ToGrandmas\"):");
// Set an EditText view to get user input
final EditText input = new EditText(TripPlannerActivity.this);
input.setMaxLines(1);
alert.setView(input);
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Canceled.
}
});
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
//This is not used in the end. Just to diplay the button.
}
});
final AlertDialog dialog = alert.create();
dialog.show();
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
String description = input.getText().toString();
if (description.equals("")) {
Toast toast = Toast.makeText(TripPlannerActivity.this, "Description cannot be empty.", Toast.LENGTH_SHORT);
toast.show();
} else if (FavoritesManager.isFavoriteTripName(description)) {
Toast toast = Toast.makeText(TripPlannerActivity.this, "Description has already been used.", Toast.LENGTH_SHORT);
toast.show();
} else {
dialog.dismiss();
trip.setDescription(description);
FavoritesManager.addFavoriteTrip(trip, getApplication());
Toast toast = Toast.makeText(TripPlannerActivity.this, "Trip Added to Favorites", Toast.LENGTH_SHORT);
toast.show();
}
}
});
}
}
};
}
/*
TODO(TOM):
Some valid trips aren't validated properly.
GH Gunther Huettlin Manufacturing .....
to
DFFD, Ouagadougou, Centre, Burkina Faso
Does not work.
ACTUALLY it doesn't validate anything.
Also in the same session but unrelated, It crashed with a null pointer exception.
StackTrace:
04-17 14:43:47.663 9092-9092/com.capstone.transit.trans_it E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
at com.capstone.transit.trans_it.PlacesAutoCompleteAdapter.getCount(PlacesAutoCompleteAdapter.java:43)
at android.widget.AdapterView.checkFocus(AdapterView.java:700)
at android.widget.AdapterView$AdapterDataSetObserver.onInvalidated(AdapterView.java:823)
at android.widget.AbsListView$AdapterDataSetObserver.onInvalidated(AbsListView.java:5619)
at android.database.DataSetObservable.notifyInvalidated(DataSetObservable.java:47)
at android.widget.BaseAdapter.notifyDataSetInvalidated(BaseAdapter.java:59)
at com.capstone.transit.trans_it.PlacesAutoCompleteAdapter$1.publishResults(PlacesAutoCompleteAdapter.java:74)
The layout needs to be reorganized, the buttons aren't in great spots and don't work at all in landscape.
*/
/*
TODO:(NICK)
Check if renaming favorites works after tom fixes the validation issue.
*/