package de.geeksfactory.opacclient.frontend;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Filter;
import android.widget.Filterable;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.io.Serializable;
import java.net.URLEncoder;
import java.util.ArrayList;
import de.geeksfactory.opacclient.R;
import de.geeksfactory.opacclient.utils.DebugTools;
import okhttp3.OkHttpClient;
import okhttp3.Request;
public class SuggestLibraryActivity extends AppCompatActivity {
private static final String LOG_TAG = "Opac";
private static final String GEOCODE_API =
"https://maps.googleapis.com/maps/api/place/autocomplete/json";
private static final String DETAIL_API =
"https://maps.googleapis.com/maps/api/place/details/json?placeid=";
private static final String API_KEY = "AIzaSyDau_9TkGF8hVqLlcHhq6yDUUN9c3rqehU";
private AutoCompleteTextView etCity;
private EditText etName;
private EditText etComment;
private City selectedCity = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_suggest_library);
setSupportActionBar((Toolbar) findViewById(R.id.toolbar));
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
etCity = (AutoCompleteTextView) findViewById(R.id.etCity);
etName = (EditText) findViewById(R.id.etName);
etComment = (EditText) findViewById(R.id.etComment);
Button btnSend = (Button) findViewById(R.id.btnSend);
if (savedInstanceState != null) {
etCity.setText(savedInstanceState.getCharSequence("city"));
etName.setText(savedInstanceState.getCharSequence("name"));
etComment.setText(savedInstanceState.getCharSequence("comment"));
selectedCity = (City) savedInstanceState
.getSerializable("selectedCity");
}
final PlacesAutoCompleteAdapter adapter = new PlacesAutoCompleteAdapter(
this, android.R.layout.simple_dropdown_item_1line);
etCity.setAdapter(adapter);
etCity.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
selectedCity = adapter.getCity(position);
}
});
etCity.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
selectedCity = null;
}
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
});
btnSend.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent send = new Intent(Intent.ACTION_SENDTO);
String uriText = "mailto:"
+ Uri.encode("info@opacapp.de")
+ "?subject="
+ Uri.encode(getResources().getString(
R.string.library_suggestion)
+ " "
+ etCity.getText().toString()
+ " "
+ etName.getText().toString()) + "&body="
+ Uri.encode(createMessage());
Uri uri = Uri.parse(uriText);
send.setData(uri);
startActivity(Intent.createChooser(send, getResources()
.getString(R.string.select_mail_app)));
supportFinishAfterTransition();
}
});
}
private String createMessage() {
try {
return createJSON().toString(4) + "\n\n"
+ etComment.getText().toString();
} catch (JSONException e) {
return "";
}
}
protected JSONObject createJSON() {
JSONObject json = new JSONObject();
try {
if (selectedCity != null) {
json.put("country", selectedCity.country);
json.put("state", selectedCity.state);
json.put("city", selectedCity.name);
JSONArray geo = new JSONArray();
geo.put(selectedCity.lat);
geo.put(selectedCity.lon);
json.put("geo", geo);
} else {
json.put("city", etCity.getText().toString());
}
json.put("title", etName.getText().toString());
return json;
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putCharSequence("city", etCity.getText());
outState.putCharSequence("name", etName.getText());
outState.putCharSequence("comment", etComment.getText());
if (selectedCity != null) {
outState.putSerializable("selectedCity", selectedCity);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
supportFinishAfterTransition();
return true;
}
return super.onOptionsItemSelected(item);
}
private ArrayList<City> autocomplete(String input) {
ArrayList<City> resultList = null;
OkHttpClient client = DebugTools.prepareHttpClient(new OkHttpClient.Builder()).build();
String jsonResults;
try {
Request request = new Request.Builder().url(
GEOCODE_API + "?input=" + URLEncoder.encode(input, "utf8") + "&types=(cities)" +
"&language=" + getResources().getConfiguration().locale.getLanguage() +
"&key=" + API_KEY).build();
jsonResults = client.newCall(request).execute().body().string();
} catch (IOException e) {
Log.e(LOG_TAG, "Error connecting to Places API", e);
return null;
}
try {
// Create a JSON object hierarchy from the results
JSONObject jsonObj = new JSONObject(jsonResults);
JSONArray resultsJsonArray = jsonObj.getJSONArray("predictions");
// Extract data from the results
resultList = new ArrayList<>();
for (int i = 0; i < resultsJsonArray.length(); i++) {
JSONObject result = resultsJsonArray.getJSONObject(i);
String placeid = result.getString("place_id");
String jsonDetailedResults;
try {
Request request = new Request.Builder().url(
DETAIL_API + URLEncoder.encode(placeid, "utf8") + "&language=" +
getResources().getConfiguration().locale.getLanguage() +
"&key=" + API_KEY).build();
jsonDetailedResults = client.newCall(request).execute().body().string();
} catch (IOException e) {
Log.e(LOG_TAG, "Error connecting to Places API", e);
return null;
}
try {
JSONObject jsonDetailObj = new JSONObject(jsonDetailedResults);
JSONObject detailResult = jsonDetailObj.getJSONObject("result");
if (contains(detailResult.getJSONArray("types"), "locality")) {
JSONArray addressComponents = detailResult
.getJSONArray("address_components");
City city = new City();
for (int j = 0; j < addressComponents.length(); j++) {
JSONObject component = addressComponents
.getJSONObject(j);
if (contains(component.getJSONArray("types"),
"locality")) {
city.name = component.getString("long_name");
} else if (contains(component.getJSONArray("types"),
"administrative_area_level_1")) {
city.state = component.getString("long_name");
} else if (contains(component.getJSONArray("types"),
"country")) {
city.country = component.getString("long_name");
}
}
city.lat = detailResult.getJSONObject("geometry")
.getJSONObject("location").getDouble("lat");
city.lon = detailResult.getJSONObject("geometry")
.getJSONObject("location").getDouble("lng");
resultList.add(city);
}
} catch (JSONException e) {
Log.e(LOG_TAG, "Cannot process JSON results", e);
}
}
} catch (JSONException e) {
Log.e(LOG_TAG, "Cannot process JSON results", e);
}
return resultList;
}
private boolean contains(JSONArray array, String string) {
boolean found = false;
int i = 0;
try {
while (!found && i < array.length()) {
if (array.getString(i).equals(string)) {
found = true;
}
i++;
}
return found;
} catch (JSONException e) {
e.printStackTrace();
}
return false;
}
private static class City implements Serializable {
private static final long serialVersionUID = 2697131850736622659L;
public String name;
public String state;
public String country;
public double lat;
public double lon;
}
private class PlacesAutoCompleteAdapter extends ArrayAdapter<String>
implements Filterable {
private ArrayList<City> resultList;
public PlacesAutoCompleteAdapter(Context context, int textViewResourceId) {
super(context, textViewResourceId);
}
@Override
public int getCount() {
return resultList == null ? 0 : resultList.size();
}
@Override
public String getItem(int index) {
return resultList.get(index).name + ", "
+ resultList.get(index).state + ", "
+ resultList.get(index).country;
}
public City getCity(int index) {
return resultList.get(index);
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if (constraint != null) {
// Retrieve the autocomplete results.
resultList = autocomplete(constraint.toString());
// Assign the data to the FilterResults
filterResults.values = resultList;
filterResults.count = resultList.size();
}
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
if (results != null && results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
};
}
}
}