package net.osmand.plus.activities;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.MenuItemCompat;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import com.jwetherell.openmap.common.LatLonPoint;
import com.jwetherell.openmap.common.UTMPoint;
import net.osmand.LocationConvert;
import net.osmand.PlatformUtil;
import net.osmand.data.LatLon;
import net.osmand.data.PointDescription;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.activities.search.SearchActivity;
import net.osmand.plus.activities.search.SearchActivity.SearchActivityChild;
import net.osmand.plus.helpers.AndroidUiHelper;
import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
public class NavigatePointFragment extends Fragment implements SearchActivityChild {
int currentFormat = Location.FORMAT_DEGREES;
public static final String SEARCH_LAT = SearchActivity.SEARCH_LAT;
public static final String SEARCH_LON = SearchActivity.SEARCH_LON;
private static final int SHOW_ON_MAP = 3;
private View view;
private LatLon location;
private OsmandApplication app;
public View onCreateView(android.view.LayoutInflater inflater, android.view.ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.search_point, container, false);
setHasOptionsMenu(true);
location = null;
app = (OsmandApplication) getActivity().getApplication();
Intent intent = getActivity().getIntent();
if(intent != null){
double lat = intent.getDoubleExtra(SEARCH_LAT, 0);
double lon = intent.getDoubleExtra(SEARCH_LON, 0);
if(lat != 0 || lon != 0){
location = new LatLon(lat, lon);
}
}
if (location == null && getActivity() instanceof SearchActivity) {
location = ((SearchActivity) getActivity()).getSearchPoint();
}
if (location == null) {
location = app.getSettings().getLastKnownMapLocation();
}
currentFormat = app.getSettings().COORDINATES_FORMAT.get();
initUI(location.getLatitude(), location.getLongitude());
if(savedInstanceState != null && savedInstanceState.containsKey(SEARCH_LAT) && savedInstanceState.containsKey(SEARCH_LON) &&
currentFormat != PointDescription.UTM_FORMAT) {
String lat = savedInstanceState.getString(SEARCH_LAT);
String lon = savedInstanceState.getString(SEARCH_LON);
if(lat != null && lon != null && lat.length() > 0 && lon.length() > 0) {
((TextView)view.findViewById(R.id.LatitudeEdit)).setText(lat);
((TextView)view.findViewById(R.id.LongitudeEdit)).setText(lon);
}
}
return view;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if(view != null) {
final TextView latEdit = ((TextView)view.findViewById(R.id.LatitudeEdit));
final TextView lonEdit = ((TextView)view.findViewById(R.id.LongitudeEdit));
outState.putString(SEARCH_LAT, latEdit.getText().toString());
outState.putString(SEARCH_LON, lonEdit.getText().toString());
}
}
@Override
public void onCreateOptionsMenu(Menu onCreate, MenuInflater inflater) {
OsmandApplication app = (OsmandApplication) getActivity().getApplication();
boolean portrait = AndroidUiHelper.isOrientationPortrait(getActivity());
boolean light = app.getSettings().isLightActionBar();
Menu menu = onCreate;
if(getActivity() instanceof SearchActivity) {
((SearchActivity) getActivity()).getClearToolbar(false);
light = false;
}
MenuItem menuItem = menu.add(0, SHOW_ON_MAP, 0, R.string.shared_string_show_on_map);
MenuItemCompat.setShowAsAction(menuItem, MenuItemCompat.SHOW_AS_ACTION_ALWAYS);
menuItem = menuItem.setIcon(app.getIconsCache().getIcon(R.drawable.ic_action_marker_dark, light));
menuItem.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
select(SHOW_ON_MAP);
return true;
}
});
}
@Override
public void onResume() {
super.onResume();
OsmandApplication app = (OsmandApplication) getActivity().getApplication();
LatLon loc = null;
if (getActivity() instanceof SearchActivity) {
loc = ((SearchActivity) getActivity()).getSearchPoint();
}
if (loc == null) {
loc = app.getSettings().getLastKnownMapLocation();
}
if(!Algorithms.objectEquals(loc, location)) {
location = loc;
locationUpdate(location);
}
}
@Override
public void locationUpdate(LatLon l) {
//location = l;
if (view != null) {
if (l != null) {
showCurrentFormat(l);
} else {
showCurrentFormat(new LatLon(0, 0));
}
}
}
protected void showCurrentFormat(LatLon l) {
final EditText latEdit = ((EditText)view.findViewById(R.id.LatitudeEdit));
final EditText lonEdit = ((EditText)view.findViewById(R.id.LongitudeEdit));
boolean utm = currentFormat == PointDescription.UTM_FORMAT;
view.findViewById(R.id.easting_row).setVisibility(utm ? View.VISIBLE : View.GONE);
view.findViewById(R.id.northing_row).setVisibility(utm ? View.VISIBLE : View.GONE);
view.findViewById(R.id.zone_row).setVisibility(utm ? View.VISIBLE : View.GONE);
view.findViewById(R.id.lat_row).setVisibility(!utm ? View.VISIBLE : View.GONE);
view.findViewById(R.id.lon_row).setVisibility(!utm ? View.VISIBLE : View.GONE);
if(currentFormat == PointDescription.UTM_FORMAT) {
final EditText northingEdit = ((EditText)view.findViewById(R.id.NorthingEdit));
final EditText eastingEdit = ((EditText)view.findViewById(R.id.EastingEdit));
final EditText zoneEdit = ((EditText)view.findViewById(R.id.ZoneEdit));
UTMPoint pnt = new UTMPoint(new LatLonPoint(l.getLatitude(), l.getLongitude()));
zoneEdit.setText(pnt.zone_number + ""+pnt.zone_letter);
northingEdit.setText(((long)pnt.northing)+"");
eastingEdit.setText(((long)pnt.easting)+"");
} else {
latEdit.setText(LocationConvert.convert(MapUtils.checkLatitude(l.getLatitude()), currentFormat));
lonEdit.setText(LocationConvert.convert(MapUtils.checkLongitude(l.getLongitude()), currentFormat));
}
}
protected LatLon parseLocation() {
LatLon loc ;
if(currentFormat == LocationConvert.UTM_FORMAT) {
double northing = Double.parseDouble(((EditText)view.findViewById(R.id.NorthingEdit)).getText().toString());
double easting = Double.parseDouble(((EditText)view.findViewById(R.id.EastingEdit)).getText().toString());
String zone = ((EditText)view.findViewById(R.id.ZoneEdit)).getText().toString();
char c = zone.charAt(zone.length() -1);
int z = Integer.parseInt(zone.substring(0, zone.length() - 1));
UTMPoint upoint = new UTMPoint(northing, easting, z, c);
LatLonPoint ll = upoint.toLatLonPoint();
loc = new LatLon(ll.getLatitude(), ll.getLongitude());
} else {
double lat = LocationConvert.convert(((EditText) view.findViewById(R.id.LatitudeEdit)).getText().toString(), true);
double lon = LocationConvert.convert(((EditText) view.findViewById(R.id.LongitudeEdit)).getText().toString(), true);
loc = new LatLon(lat, lon);
}
return loc;
}
public void initUI(double latitude, double longitude){
showCurrentFormat(new LatLon(latitude, longitude));
final Spinner format = ((Spinner)view.findViewById(R.id.Format));
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_item, new String[] {
PointDescription.formatToHumanString(this.getContext(), PointDescription.FORMAT_DEGREES),
PointDescription.formatToHumanString(this.getContext(), PointDescription.FORMAT_MINUTES),
PointDescription.formatToHumanString(this.getContext(), PointDescription.FORMAT_SECONDS),
PointDescription.formatToHumanString(this.getContext(), PointDescription.UTM_FORMAT),
});
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
format.setAdapter(adapter);
format.setSelection(currentFormat);
format.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View v, int position, long id) {
int newFormat = currentFormat;
String itm = (String) format.getItemAtPosition(position);
if (PointDescription.formatToHumanString(NavigatePointFragment.this.getContext(), PointDescription.FORMAT_DEGREES).equals(itm)) {
newFormat = PointDescription.FORMAT_DEGREES;
} else if (PointDescription.formatToHumanString(NavigatePointFragment.this.getContext(), PointDescription.FORMAT_MINUTES).equals(itm)) {
newFormat = PointDescription.FORMAT_MINUTES;
} else if (PointDescription.formatToHumanString(NavigatePointFragment.this.getContext(), PointDescription.FORMAT_SECONDS).equals(itm)) {
newFormat = PointDescription.FORMAT_SECONDS;
} else if (PointDescription.formatToHumanString(NavigatePointFragment.this.getContext(), PointDescription.UTM_FORMAT).equals(itm)) {
newFormat = PointDescription.UTM_FORMAT;
}
try {
LatLon loc = parseLocation();
currentFormat = newFormat;
app.getSettings().COORDINATES_FORMAT.set(currentFormat);
view.findViewById(R.id.ValidateTextView).setVisibility(View.INVISIBLE);
showCurrentFormat(loc);
} catch (RuntimeException e) {
view.findViewById(R.id.ValidateTextView).setVisibility(View.VISIBLE);
((TextView) view.findViewById(R.id.ValidateTextView)).setText(R.string.invalid_locations);
Log.w(PlatformUtil.TAG, "Convertion failed", e); //$NON-NLS-1$
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
addPasteListeners();
}
protected void addPasteListeners() {
final EditText latEdit = ((EditText)view.findViewById(R.id.LatitudeEdit));
final EditText lonEdit = ((EditText)view.findViewById(R.id.LongitudeEdit));
TextWatcher textWatcher = new TextWatcher() {
String pasteString = null;
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
pasteString = null;
if(count > 3) {
pasteString = s.subSequence(start, start + count).toString();
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
if(pasteString != null){
int latSt = -1;
int latEnd = -1;
int lonSt = -1;
int lonEnd = -1;
int step = 0; // 0 - init, 1- lat, 2-between, 3-lon
for (int i = 0; i < pasteString.length(); i++) {
char ch = pasteString.charAt(i);
if (Character.isDigit(ch)) {
if (step == 0 || step == 2){
int t = i;
if (i > 0 && pasteString.charAt(i - 1) == '-') {
t--;
}
if (step == 0) {
latSt = t;
} else {
lonSt = t;
}
step++;
}
} else if (ch == '.' || ch == ':' ) {
// do nothing here
} else {
if (step == 1) {
latEnd = i;
step++;
} else if (step == 3) {
lonEnd = i;
step++;
break;
}
}
}
if(lonSt != -1){
if(lonEnd == -1){
lonEnd = pasteString.length();
}
try {
String latString = pasteString.substring(latSt, latEnd);
String lonString = pasteString.substring(lonSt, lonEnd);
Double.parseDouble(latString);
Double.parseDouble(lonString);
latEdit.setText(latString);
lonEdit.setText(lonString);
} catch (NumberFormatException e) {
}
}
}
}
};
latEdit.addTextChangedListener(textWatcher);
lonEdit.addTextChangedListener(textWatcher);
}
public void select(int mode){
try {
LatLon loc = parseLocation();
double lat = loc.getLatitude();
double lon = loc.getLongitude();
PointDescription pd = new PointDescription(lat, lon);
if (mode == SHOW_ON_MAP){
OsmandApplication app = (OsmandApplication) getActivity().getApplication();
app.getSettings().setMapLocationToShow(lat, lon, Math.max(12, app.getSettings().getLastKnownMapZoom()),
pd);
MapActivity.launchMapActivityMoveToTop(getActivity());
}
} catch (RuntimeException e) {
view.findViewById(R.id.ValidateTextView).setVisibility(View.VISIBLE);
((TextView) view.findViewById(R.id.ValidateTextView)).setText(R.string.invalid_locations);
Log.w(PlatformUtil.TAG, "Convertion failed", e); //$NON-NLS-1$
}
}
}