Convert to AndroidX from support_v4
[fw/altos] / altosdroid / app / src / main / java / org / altusmetrum / AltosDroid / PreloadMapActivity.java
1 /*
2  * Copyright © 2015 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 package org.altusmetrum.AltosDroid;
20
21 import java.util.*;
22 import java.text.*;
23
24 import android.app.Activity;
25 import android.content.Context;
26 import android.os.Bundle;
27 import android.view.View;
28 import android.view.Window;
29 import android.view.View.OnClickListener;
30 import android.widget.*;
31 import android.widget.AdapterView.*;
32 import android.location.Location;
33 import android.location.LocationManager;
34 import android.location.LocationListener;
35
36 import org.altusmetrum.altoslib_13.*;
37
38 /**
39  * This Activity appears as a dialog. It lists any paired devices and
40  * devices detected in the area after discovery. When a device is chosen
41  * by the user, the MAC address of the device is sent back to the parent
42  * Activity in the result Intent.
43  */
44 public class PreloadMapActivity extends Activity implements AltosLaunchSiteListener, AltosMapLoaderListener, LocationListener {
45
46         private ArrayAdapter<AltosLaunchSite> known_sites_adapter;
47
48 /*
49         private CheckBox        hybrid;
50         private CheckBox        satellite;
51         private CheckBox        roadmap;
52         private CheckBox        terrain;
53 */
54
55         private Spinner         known_sites_spinner;
56         private Spinner         min_zoom;
57         private Spinner         max_zoom;
58         private TextView        radius_label;
59         private Spinner         radius;
60
61         private EditText        latitude;
62         private EditText        longitude;
63
64         private ProgressBar     progress;
65
66         private AltosMapLoader  loader;
67
68         long    loader_notify_time;
69
70         /* AltosMapLoaderListener interfaces */
71         public void loader_start(final int max) {
72                 loader_notify_time = System.currentTimeMillis();
73
74                 this.runOnUiThread(new Runnable() {
75                                 public void run() {
76                                         progress.setMax(max);
77                                         progress.setProgress(0);
78                                 }
79                         });
80         }
81
82         public void loader_notify(final int cur, final int max, final String name) {
83                 long    now = System.currentTimeMillis();
84
85                 if (now - loader_notify_time < 100)
86                         return;
87
88                 loader_notify_time = now;
89
90                 this.runOnUiThread(new Runnable() {
91                                 public void run() {
92                                         progress.setProgress(cur);
93                                 }
94                         });
95         }
96
97         public void loader_done(int max) {
98                 loader = null;
99                 this.runOnUiThread(new Runnable() {
100                                 public void run() {
101                                         progress.setProgress(0);
102                                         finish();
103                                 }
104                         });
105         }
106
107         public void debug(String format, Object ... arguments) {
108                 AltosDebug.debug(format, arguments);
109         }
110
111         /* AltosLaunchSiteListener interface */
112
113         public void notify_launch_sites(final List<AltosLaunchSite> sites) {
114                 this.runOnUiThread(new Runnable() {
115                                 public void run() {
116                                         for (AltosLaunchSite site : sites)
117                                                 known_sites_adapter.add(site);
118                                 }
119                         });
120         }
121
122         /* LocationProvider interface */
123
124         AltosLaunchSite current_location_site;
125
126         public void onLocationChanged(Location location) {
127                 AltosDebug.debug("location changed");
128                 if (current_location_site == null) {
129                         AltosLaunchSite selected_item = (AltosLaunchSite) known_sites_spinner.getSelectedItem();
130
131                         current_location_site = new AltosLaunchSite("Current Location", location.getLatitude(), location.getLongitude());
132                         known_sites_adapter.insert(current_location_site, 0);
133
134                         if (selected_item != null)
135                                 known_sites_spinner.setSelection(known_sites_adapter.getPosition(selected_item));
136                         else {
137                                 latitude.setText(new StringBuffer(String.format("%12.6f", current_location_site.latitude)));
138                                 longitude.setText(new StringBuffer(String.format("%12.6f", current_location_site.longitude)));
139                         }
140                 } else {
141                         current_location_site.latitude = location.getLatitude();
142                         current_location_site.longitude = location.getLongitude();
143                 }
144         }
145
146         public void onStatusChanged(String provider, int status, Bundle extras) {
147         }
148
149         public void onProviderEnabled(String provider) {
150         }
151
152         public void onProviderDisabled(String provider) {
153         }
154
155         private double text(EditText view) throws ParseException {
156                 return AltosParse.parse_double_locale(view.getEditableText().toString());
157         }
158
159         private double latitude() throws ParseException {
160                 return text(latitude);
161         }
162
163         private double longitude() throws ParseException {
164                 return text(longitude);
165         }
166
167         private int value(Spinner spinner) {
168                 return (Integer) spinner.getSelectedItem();
169         }
170
171         private int min_z() {
172                 return value(min_zoom);
173         }
174
175         private int max_z() {
176                 return value(max_zoom);
177         }
178
179         private double value_distance(Spinner spinner) {
180                 return (Double) spinner.getSelectedItem();
181         }
182
183         private double radius() {
184                 double r = value_distance(radius);
185                 if (AltosPreferences.imperial_units())
186                         r = AltosConvert.miles_to_meters(r);
187                 else
188                         r = r * 1000;
189                 return r;
190         }
191
192 /*
193         private int bit(CheckBox box, int value) {
194                 if (box.isChecked())
195                         return 1 << value;
196                 return 0;
197         }
198 */
199
200         private int types() {
201 /*
202                 return (bit(hybrid, AltosMap.maptype_hybrid) |
203                         bit(satellite, AltosMap.maptype_satellite) |
204                         bit(roadmap, AltosMap.maptype_roadmap) |
205                         bit(terrain, AltosMap.maptype_terrain));
206 */
207                 return 1 << AltosMap.maptype_hybrid;
208         }
209
210         private void load() {
211                 if (loader != null)
212                         return;
213
214                 try {
215                         double  lat = latitude();
216                         double  lon = longitude();
217                         int     min = min_z();
218                         int     max = max_z();
219                         double  r = radius();
220                         int     t = types();
221
222                         AltosDebug.debug("PreloadMap load %f %f %d %d %f %d\n",
223                                          lat, lon, min, max, r, t);
224                         loader = new AltosMapLoader(this, lat, lon, min, max, r, t, AltosMapOffline.scale);
225                 } catch (ParseException e) {
226                         AltosDebug.debug("PreloadMap load raised exception %s", e.toString());
227                 }
228         }
229
230         private void add_numbers(Spinner spinner, int min, int max, int def) {
231
232                 ArrayAdapter<Integer> adapter = new ArrayAdapter<Integer>(this, android.R.layout.simple_spinner_item);
233
234                 int     spinner_def = 0;
235                 int     pos = 0;
236
237                 for (int i = min; i <= max; i++) {
238                         adapter.add(new Integer(i));
239                         if (i == def)
240                                 spinner_def = pos;
241                         pos++;
242                 }
243
244                 spinner.setAdapter(adapter);
245                 spinner.setSelection(spinner_def);
246         }
247
248
249         private void add_distance(Spinner spinner, double[] distances_km, double def_km, double[] distances_mi, double def_mi) {
250
251                 ArrayAdapter<Double> adapter = new ArrayAdapter<Double>(this, android.R.layout.simple_spinner_item);
252
253                 int     spinner_def = 0;
254                 int     pos = 0;
255
256                 double[] distances;
257                 double  def;
258                 if (AltosPreferences.imperial_units()) {
259                         distances = distances_mi;
260                         def = def_mi;
261                 } else {
262                         distances = distances_km;
263                         def = def_km;
264                 }
265
266                 for (int i = 0; i < distances.length; i++) {
267                         adapter.add(distances[i]);
268                         if (distances[i] == def)
269                                 spinner_def = pos;
270                         pos++;
271                 }
272
273                 spinner.setAdapter(adapter);
274                 spinner.setSelection(spinner_def);
275         }
276
277
278
279         class SiteListListener implements OnItemSelectedListener {
280                 public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
281                         AltosLaunchSite site = (AltosLaunchSite) parent.getItemAtPosition(pos);
282                         latitude.setText(new StringBuffer(String.format("%12.6f", site.latitude)));
283                         longitude.setText(new StringBuffer(String.format("%12.6f", site.longitude)));
284                 }
285                 public void onNothingSelected(AdapterView<?> parent) {
286                 }
287
288                 public SiteListListener() {
289                 }
290         }
291
292         double[]        radius_mi = { 1, 2, 5, 10, 20 };
293         double          radius_def_mi = 2;
294         double[]        radius_km = { 1, 2, 5, 10, 20, 30 };
295         double          radius_def_km = 2;
296
297         @Override
298         protected void onCreate(Bundle savedInstanceState) {
299                 super.onCreate(savedInstanceState);
300
301                 // Setup the window
302                 requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
303                 setContentView(R.layout.map_preload);
304
305                 // Set result CANCELED incase the user backs out
306                 setResult(Activity.RESULT_CANCELED);
307
308                 // Initialize the button to perform device discovery
309                 Button loadButton = (Button) findViewById(R.id.preload_load);
310                 loadButton.setOnClickListener(new OnClickListener() {
311                         public void onClick(View v) {
312                                 load();
313                         }
314                 });
315
316                 latitude = (EditText) findViewById(R.id.preload_latitude);
317                 longitude = (EditText) findViewById(R.id.preload_longitude);
318
319 /*
320                 hybrid = (CheckBox) findViewById(R.id.preload_hybrid);
321                 satellite = (CheckBox) findViewById(R.id.preload_satellite);
322                 roadmap = (CheckBox) findViewById(R.id.preload_roadmap);
323                 terrain = (CheckBox) findViewById(R.id.preload_terrain);
324
325                 hybrid.setChecked(true);
326 */
327
328                 min_zoom = (Spinner) findViewById(R.id.preload_min_zoom);
329                 add_numbers(min_zoom,
330                             AltosMap.min_zoom - AltosMap.default_zoom,
331                             AltosMap.max_zoom - AltosMap.default_zoom, -2);
332                 max_zoom = (Spinner) findViewById(R.id.preload_max_zoom);
333                 add_numbers(max_zoom,
334                             AltosMap.min_zoom - AltosMap.default_zoom,
335                             AltosMap.max_zoom - AltosMap.default_zoom, 2);
336                 radius_label = (TextView) findViewById(R.id.preload_radius_label);
337                 radius = (Spinner) findViewById(R.id.preload_radius);
338                 if (AltosPreferences.imperial_units())
339                         radius_label.setText("Radius (miles)");
340                 else
341                         radius_label.setText("Radius (km)");
342                 add_distance(radius, radius_km, radius_def_km, radius_mi, radius_def_mi);
343
344                 progress = (ProgressBar) findViewById(R.id.preload_progress);
345
346                 // Initialize array adapters. One for already paired devices and
347                 // one for newly discovered devices
348                 known_sites_spinner = (Spinner) findViewById(R.id.preload_site_list);
349
350                 known_sites_adapter = new ArrayAdapter<AltosLaunchSite>(this, android.R.layout.simple_spinner_item);
351
352                 known_sites_adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
353
354                 known_sites_spinner.setAdapter(known_sites_adapter);
355                 known_sites_spinner.setOnItemSelectedListener(new SiteListListener());
356
357                 // Listen for GPS and Network position updates
358                 LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
359
360                 locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 1, this);
361
362                 new AltosLaunchSites(this);
363         }
364
365         @Override
366         protected void onDestroy() {
367                 super.onDestroy();
368
369                 if (loader != null)
370                         loader.abort();
371
372                 // Stop listening for location updates
373                 ((LocationManager) getSystemService(Context.LOCATION_SERVICE)).removeUpdates(this);
374         }
375 }