altosdroid: Split setup functions to separate dialog
[fw/altos] / altosdroid / src / org / altusmetrum / AltosDroid / SetupActivity.java
1 /*
2  * Copyright © 2016 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; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 package org.altusmetrum.AltosDroid;
19
20 import java.lang.ref.WeakReference;
21 import java.util.*;
22 import org.altusmetrum.AltosDroid.R;
23
24 import android.app.Activity;
25 import android.bluetooth.*;
26 import android.content.*;
27 import android.os.*;
28 import android.view.*;
29 import android.view.View.*;
30 import android.widget.*;
31 import android.widget.AdapterView.*;
32
33 import org.altusmetrum.altoslib_10.*;
34
35 public class SetupActivity extends Activity {
36         private Spinner select_rate;
37         private Spinner set_units;
38         private Spinner map_type;
39         private Spinner map_source;
40         private Button preload_maps;
41         private Button done;
42
43         private boolean is_bound;
44         private Messenger service = null;
45
46         public final static String EXTRA_SETUP_CHANGES = "setup_changes";
47
48         private ServiceConnection connection = new ServiceConnection() {
49                 public void onServiceConnected(ComponentName className, IBinder binder) {
50                         service = new Messenger(binder);
51                 }
52
53                 public void onServiceDisconnected(ComponentName className) {
54                         // This is called when the connection with the service has been unexpectedly disconnected - process crashed.
55                         service = null;
56                 }
57         };
58
59         void doBindService() {
60                 bindService(new Intent(this, TelemetryService.class), connection, Context.BIND_AUTO_CREATE);
61                 is_bound = true;
62         }
63
64         void doUnbindService() {
65                 if (is_bound) {
66                         // If we have received the service, and hence registered with it, then now is the time to unregister.
67                         unbindService(connection);
68                         is_bound = false;
69                 }
70         }
71
72         static final String[] rates = {
73                 "38400",
74                 "9600",
75                 "2400",
76         };
77
78         static final String[] map_types = {
79                 "Hybrid",
80                 "Satellite",
81                 "Roadmap",
82                 "Terrain"
83         };
84
85         static final int[] map_type_values = {
86                 AltosMap.maptype_hybrid,
87                 AltosMap.maptype_satellite,
88                 AltosMap.maptype_roadmap,
89                 AltosMap.maptype_terrain,
90         };
91
92         static final String[] map_sources = {
93                 "Online",
94                 "Offline"
95         };
96
97         private int     set_telemetry_rate;
98         private int     set_map_source;
99         private int     set_map_type;
100         private boolean set_imperial_units;
101
102         private int     changes = 0;
103
104         private void add_change(int change) {
105                 changes |= change;
106         }
107
108         private void done() {
109                 Intent intent = new Intent();
110                 if ((changes & AltosDroid.SETUP_BAUD) != 0)
111                         AltosPreferences.set_telemetry_rate(1, set_telemetry_rate);
112                 if ((changes & AltosDroid.SETUP_UNITS) != 0)
113                         AltosPreferences.set_imperial_units(set_imperial_units);
114                 if ((changes & AltosDroid.SETUP_MAP_SOURCE) != 0)
115                         AltosDroidPreferences.set_map_source(set_map_source);
116                 if ((changes & AltosDroid.SETUP_MAP_TYPE) != 0)
117                         AltosPreferences.set_map_type(set_map_type);
118                 intent.putExtra(EXTRA_SETUP_CHANGES, changes);
119                 setResult(Activity.RESULT_OK, intent);
120                 finish();
121         }
122
123         private void add_strings(Spinner spinner, String[] strings, int def) {
124                 ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);
125
126                 for (int i = 0; i < strings.length; i++)
127                         adapter.add(strings[i]);
128
129                 spinner.setAdapter(adapter);
130                 if (def >= 0)
131                         spinner.setSelection(def);
132         }
133
134         private int default_rate_pos() {
135                 int     default_rate = AltosPreferences.telemetry_rate(1);
136
137                 for (int pos = 0; pos < rates.length; pos++) {
138                         if (string_to_rate(rates[pos]) == default_rate)
139                                 return pos;
140                 }
141                 return -1;
142         }
143
144         private void setBaud(int baud) {
145                 try {
146                         service.send(Message.obtain(null, TelemetryService.MSG_SETBAUD, baud));
147                         set_telemetry_rate = baud;
148                         add_change(AltosDroid.SETUP_BAUD);
149                 } catch (RemoteException e) {
150                 }
151         }
152
153         private int string_to_rate(String baud) {
154                 int     rate = AltosLib.ao_telemetry_rate_38400;
155                 try {
156                         int     value = Integer.parseInt(baud);
157                         switch (value) {
158                         case 2400:
159                                 rate = AltosLib.ao_telemetry_rate_2400;
160                                 break;
161                         case 9600:
162                                 rate = AltosLib.ao_telemetry_rate_9600;
163                                 break;
164                         case 38400:
165                                 rate = AltosLib.ao_telemetry_rate_38400;
166                                 break;
167                         }
168                 } catch (NumberFormatException e) {
169                 }
170                 return rate;
171         }
172
173         private void setBaud(String baud) {
174                 setBaud(string_to_rate(baud));
175         }
176
177         private void select_rate(int pos) {
178                 setBaud(rates[pos]);
179         }
180
181         static final String[] units = {
182                 "Metric",
183                 "Imperial"
184         };
185
186         private int default_units_pos() {
187                 boolean imperial = AltosPreferences.imperial_units();
188
189                 if (imperial)
190                         return 1;
191                 return 0;
192         }
193
194         private void set_units(int pos) {
195                 switch (pos) {
196                 default:
197                         set_imperial_units = false;
198                         break;
199                 case 1:
200                         set_imperial_units = true;
201                         break;
202                 }
203                 add_change(AltosDroid.SETUP_UNITS);
204         }
205
206         private int default_map_type_pos() {
207                 int     default_map_type = AltosPreferences.map_type();
208
209                 for (int pos = 0; pos < map_types.length; pos++)
210                         if (map_type_values[pos] == default_map_type)
211                                 return pos;
212                 return 0;
213         }
214
215         private void select_map_type(int pos) {
216                 set_map_type = map_type_values[pos];
217                 add_change(AltosDroid.SETUP_MAP_TYPE);
218         }
219
220         private int default_map_source_pos() {
221                 int     default_source = AltosDroidPreferences.map_source();
222
223                 switch (default_source) {
224                 case AltosDroidPreferences.MAP_SOURCE_OFFLINE:
225                         return 1;
226                 default:
227                         return 0;
228                 }
229         }
230
231         private void select_map_source(int pos) {
232                 switch (pos) {
233                 default:
234                         set_map_source = AltosDroidPreferences.MAP_SOURCE_ONLINE;
235                         break;
236                 case 1:
237                         set_map_source = AltosDroidPreferences.MAP_SOURCE_OFFLINE;
238                         break;
239                 }
240                 add_change(AltosDroid.SETUP_MAP_SOURCE);
241         }
242
243         private void preload_maps(){
244                 Intent intent = new Intent(this, PreloadMapActivity.class);
245                 startActivity(intent);
246         }
247
248         @Override
249         protected void onCreate(Bundle savedInstanceState) {
250                 super.onCreate(savedInstanceState);
251
252                 // Setup the window
253                 requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
254                 setContentView(R.layout.setup);
255
256                 select_rate = (Spinner) findViewById(R.id.select_rate);
257                 add_strings(select_rate, rates, default_rate_pos());
258                 select_rate.setOnItemSelectedListener(new OnItemSelectedListener() {
259                                 public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
260                                         select_rate(pos);
261                                 }
262                                 public void onNothingSelected(AdapterView<?> parent) {
263                                 }
264                         });
265
266                 set_units = (Spinner) findViewById(R.id.set_units);
267                 add_strings(set_units, units, default_units_pos());
268                 set_units.setOnItemSelectedListener(new OnItemSelectedListener() {
269                                 public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
270                                         set_units(pos);
271                                 }
272                                 public void onNothingSelected(AdapterView<?> parent) {
273                                 }
274                         });
275
276                 map_type = (Spinner) findViewById(R.id.map_type);
277                 add_strings(map_type, map_types, default_map_type_pos());
278                 map_type.setOnItemSelectedListener(new OnItemSelectedListener() {
279                                 public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
280                                         select_map_type(pos);
281                                 }
282                                 public void onNothingSelected(AdapterView<?> parent) {
283                                 }
284                         });
285
286                 map_source = (Spinner) findViewById(R.id.map_source);
287                 add_strings(map_source, map_sources, default_map_source_pos());
288                 map_source.setOnItemSelectedListener(new OnItemSelectedListener() {
289                                 public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
290                                         select_map_source(pos);
291                                 }
292                                 public void onNothingSelected(AdapterView<?> parent) {
293                                 }
294                         });
295
296
297                 preload_maps = (Button) findViewById(R.id.preload_maps);
298                 preload_maps.setOnClickListener(new OnClickListener() {
299                                 public void onClick(View v) {
300                                         preload_maps();
301                                 }
302                         });
303
304                 done = (Button) findViewById(R.id.done);
305                 done.setOnClickListener(new OnClickListener() {
306                                 public void onClick(View v) {
307                                         done();
308                                 }
309                         });
310
311                 // Set result for when the user backs out
312                 setResult(Activity.RESULT_CANCELED);
313         }
314
315         @Override
316         protected void onStart() {
317                 super.onStart();
318                 doBindService();
319         }
320
321         @Override
322         protected void onStop() {
323                 super.onStop();
324                 doUnbindService();
325         }
326 }