Bump java lib versions in preparation for 1.9.2
[fw/altos] / altosdroid / app / src / main / java / org / altusmetrum / AltosDroid / SelectTrackerActivity.java
1 /*
2  * Copyright © 2020 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 android.app.Activity;
23 import android.content.*;
24 import android.os.*;
25 import android.util.*;
26 import android.view.*;
27 import android.view.View.*;
28 import android.widget.*;
29 import android.graphics.*;
30 import android.graphics.drawable.*;
31 import android.widget.CompoundButton.OnCheckedChangeListener;
32
33 import org.altusmetrum.altoslib_14.*;
34
35 class TrackerComparatorCall implements Comparator<Tracker> {
36         public int compare(Tracker a, Tracker b) {
37                 int v;
38
39                 v = a.compareCall(b);
40                 if (v != 0)
41                         return v;
42                 v = a.compareAge(b);
43                 if (v != 0)
44                         return v;
45                 v = a.compareSerial(b);
46                 if (v != 0)
47                         return v;
48                 return a.compareFrequency(b);
49         }
50         public boolean equals(Object o) {
51                 return o instanceof TrackerComparatorCall;
52         }
53 }
54
55 class TrackerComparatorSerial implements Comparator<Tracker> {
56         public int compare(Tracker a, Tracker b) {
57                 int v;
58
59                 v = a.compareSerial(b);
60                 if (v != 0)
61                         return v;
62                 v = a.compareAge(b);
63                 if (v != 0)
64                         return v;
65                 v = a.compareCall(b);
66                 if (v != 0)
67                         return v;
68                 return a.compareFrequency(b);
69         }
70         public boolean equals(Object o) {
71                 return o instanceof TrackerComparatorSerial;
72         }
73 }
74
75 class TrackerComparatorAge implements Comparator<Tracker> {
76         public int compare(Tracker a, Tracker b) {
77                 int v;
78
79                 v = a.compareAge(b);
80                 if (v != 0)
81                         return v;
82                 v = a.compareCall(b);
83                 if (v != 0)
84                         return v;
85                 v = a.compareSerial(b);
86                 if (v != 0)
87                         return v;
88                 return a.compareFrequency(b);
89         }
90         public boolean equals(Object o) {
91                 return o instanceof TrackerComparatorAge;
92         }
93 }
94
95 class TrackerComparatorFrequency implements Comparator<Tracker> {
96         public int compare(Tracker a, Tracker b) {
97                 int v;
98
99                 v = a.compareFrequency(b);
100                 if (v != 0)
101                         return v;
102                 v = a.compareAge(b);
103                 if (v != 0)
104                         return v;
105                 v = a.compareCall(b);
106                 if (v != 0)
107                         return v;
108                 return a.compareSerial(b);
109         }
110         public boolean equals(Object o) {
111                 return o instanceof TrackerComparatorFrequency;
112         }
113 }
114
115 public class SelectTrackerActivity extends Activity implements OnTouchListener {
116         // Return Intent extra
117         public static final String EXTRA_SERIAL_NUMBER = "serial_number";
118         public static final String EXTRA_FREQUENCY = "frequency";
119
120         private int button_ids[] = {
121                 R.id.call_button,
122                 R.id.serial_button,
123                 R.id.frequency_button,
124                 R.id.age_button
125         };
126
127         private static final int call_button = 0;
128         private static final int serial_button = 1;
129         private static final int freq_button = 2;
130         private static final int age_button = 3;
131         private RadioButton radio_buttons[] = new RadioButton[4];
132         private TableLayout table;
133
134         private Tracker[] trackers;
135
136         private void set_sort(int id) {
137                 AltosDroidPreferences.set_tracker_sort(id);
138                 resort();
139         }
140
141         private void resort() {
142                 Comparator<Tracker> compare;
143                 int tracker_sort = AltosDroidPreferences.tracker_sort();
144                 AltosDebug.debug("sort %d", tracker_sort);
145                 switch (tracker_sort) {
146                 case call_button:
147                 default:
148                         compare = new TrackerComparatorCall();
149                         break;
150                 case serial_button:
151                         compare = new TrackerComparatorSerial();
152                         break;
153                 case freq_button:
154                         compare = new TrackerComparatorFrequency();
155                         break;
156                 case age_button:
157                         compare = new TrackerComparatorAge();
158                         break;
159                 }
160                 Arrays.sort(trackers, compare);
161                 set_trackers();
162         }
163
164         void init_button_state() {
165                 int tracker_sort = AltosDroidPreferences.tracker_sort();
166                 for (int i = 0; i < 4; i++)
167                         radio_buttons[i].setChecked(i == tracker_sort);
168         }
169
170         OnCheckedChangeListener button_listener = new OnCheckedChangeListener() {
171                         @Override
172                         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
173                                 int id = buttonView.getId();
174                                 if (isChecked) {
175                                         int sort_id = -1;
176                                         for (int i = 0; i < 4; i++) {
177                                                 if (id == button_ids[i])
178                                                         sort_id = i;
179                                                 else
180                                                         radio_buttons[i].setChecked(false);
181                                         }
182                                         if (sort_id != -1)
183                                                 set_sort(sort_id);
184                                 }
185                         }
186                 };
187
188         long start_time;
189
190         private void
191         insert_tracker(Tracker tracker) {
192                 TableRow row = (TableRow) getLayoutInflater().inflate(R.layout.tracker_ent, null);
193
194                 ((TextView) row.findViewById(R.id.call_view)).setText(tracker.call);
195                 if (tracker.serial == 0)
196                         ((TextView) row.findViewById(R.id.serial_view)).setText("");
197                 else
198                         ((TextView) row.findViewById(R.id.serial_view)).setText(String.format("%d", tracker.serial));
199                 if (tracker.frequency == 0.0)
200                         ((TextView) row.findViewById(R.id.frequency_view)).setText("");
201                 else if (tracker.frequency == AltosLib.MISSING)
202                         ((TextView) row.findViewById(R.id.frequency_view)).setText("");
203                 else
204                         ((TextView) row.findViewById(R.id.frequency_view)).setText(String.format("%7.3f", tracker.frequency));
205                 if (tracker.received_time != 0) {
206                         int age = (int) ((start_time - tracker.received_time + 500) / 1000);
207                         ((TextView) row.findViewById(R.id.age_view)).setText(AltosDroid.age_string(age));
208                 } else {
209                         ((TextView) row.findViewById(R.id.age_view)).setText("");
210                 }
211                 row.setClickable(true);
212                 row.setOnTouchListener(this);
213                 table.addView(row);
214         }
215
216         private void set_trackers() {
217                 for (int i = table.getChildCount() - 1; i >= 1; i--)
218                         table.removeViewAt(i);
219                 for (Tracker tracker : trackers)
220                         insert_tracker(tracker);
221         }
222
223         private void done(View v) {
224                 int result = Activity.RESULT_CANCELED;
225                 Intent intent = new Intent();
226                 for (int i = 1; i < table.getChildCount(); i++) {
227                         View child = table.getChildAt(i);
228                         if (child == v) {
229                                 Tracker tracker = trackers[i - 1];
230                                 intent.putExtra(EXTRA_SERIAL_NUMBER, tracker.serial);
231                                 intent.putExtra(EXTRA_FREQUENCY, tracker.frequency);
232                                 result = Activity.RESULT_OK;
233                                 break;
234                         }
235                 }
236                 setResult(Activity.RESULT_OK, intent);
237                 finish();
238         }
239
240         @Override
241         protected void onCreate(Bundle savedInstanceState) {
242                 int title_id = getIntent().getIntExtra(AltosDroid.EXTRA_TRACKERS_TITLE, R.id.select_tracker);
243                 AltosDebug.debug("get title id 0x%x %s", title_id, getResources().getText(title_id));
244                 setTitle(getResources().getText(title_id));
245                 setTheme(AltosDroid.dialog_themes[AltosDroidPreferences.font_size()]);
246                 super.onCreate(savedInstanceState);
247
248                 setContentView(R.layout.tracker_list);
249                 // Set result CANCELED incase the user backs out
250                 setResult(Activity.RESULT_CANCELED);
251
252                 for (int i = 0; i < 4; i++) {
253                         radio_buttons[i] = (RadioButton) findViewById(button_ids[i]);
254                         radio_buttons[i].setOnCheckedChangeListener(button_listener);
255                 }
256
257                 ArrayList<Parcelable> tracker_array = (ArrayList<Parcelable>) getIntent().getParcelableArrayListExtra(AltosDroid.EXTRA_TRACKERS);
258                 if (tracker_array != null) {
259                         Object[] array = tracker_array.toArray();
260                         trackers = new Tracker[array.length];
261                         for (int i = 0; i < array.length; i++)
262                                 trackers[i] = (Tracker) array[i];
263                 }
264
265                 start_time = System.currentTimeMillis();
266
267                 table = (TableLayout) findViewById(R.id.tracker_list);
268
269                 init_button_state();
270
271                 resort();
272
273                 set_trackers();
274         }
275
276         @Override
277         public boolean onTouch(View v, MotionEvent event) {
278                 int action = event.getAction() & MotionEvent.ACTION_MASK;
279                 switch (action) {
280                 case MotionEvent.ACTION_UP:
281                 case MotionEvent.ACTION_CANCEL:
282                 case MotionEvent.ACTION_OUTSIDE:
283                         v.setBackgroundColor(0);
284                         v.invalidate();
285                         break;
286                 case MotionEvent.ACTION_DOWN:
287                         v.setBackgroundColor(Color.RED);
288                         v.invalidate();
289                         break;
290                 }
291                 if (action == MotionEvent.ACTION_UP) {
292                         done(v);
293                         return true;
294                 }
295                 return false;
296         }
297 }