altosdroid: Add 'Auto' to map tracker list
[fw/altos] / altosdroid / src / org / altusmetrum / AltosDroid / AltosDroid.java
index 8fe97187506c174dcecdea6c9cae810224aebed5..71ac298e77b6d6000d4620db1a16eddd57871b5b 100644 (file)
 package org.altusmetrum.AltosDroid;
 
 import java.lang.ref.WeakReference;
-import java.util.ArrayList;
-import java.util.Timer;
-import java.util.TimerTask;
 import java.text.*;
+import java.util.*;
+import java.io.*;
 
 import android.app.Activity;
 import android.app.PendingIntent;
@@ -88,6 +87,11 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
        private int mAgeNewColor;
        private int mAgeOldColor;
 
+       public static final String      tab_pad_name = "pad";
+       public static final String      tab_flight_name = "flight";
+       public static final String      tab_recover_name = "recover";
+       public static final String      tab_map_name = "map";
+
        // field to display the version at the bottom of the screen
        private TextView mVersion;
 
@@ -129,7 +133,6 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
 
                        switch (msg.what) {
                        case MSG_STATE:
-                               AltosDebug.debug("MSG_STATE");
                                if (msg.obj == null) {
                                        AltosDebug.debug("telemetry_state null!");
                                        return;
@@ -137,7 +140,6 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                                ad.update_state((TelemetryState) msg.obj);
                                break;
                        case MSG_UPDATE_AGE:
-                               AltosDebug.debug("MSG_UPDATE_AGE");
                                ad.update_age();
                                break;
                        }
@@ -248,11 +250,13 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                }
        }
 
+       int     selected_serial = 0;
        int     current_serial;
        long    switch_time;
 
        void set_switch_time() {
                switch_time = System.currentTimeMillis();
+               selected_serial = 0;
        }
 
        boolean registered_units_listener;
@@ -262,6 +266,9 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                if (new_telemetry_state != null)
                        telemetry_state = new_telemetry_state;
 
+               if (selected_serial != 0)
+                       current_serial = selected_serial;
+
                if (current_serial == 0)
                        current_serial = telemetry_state.latest_serial;
 
@@ -271,6 +278,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                }
 
                serials = telemetry_state.states.keySet().toArray(new Integer[0]);
+               Arrays.sort(serials);
 
                update_title(telemetry_state);
 
@@ -282,7 +290,9 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                        int age = state_age(state);
                        if (age < 20)
                                aged = false;
-                       if (switch_time != 0 && (switch_time - state.received_time) > 0)
+                       if (current_serial == selected_serial)
+                               aged = false;
+                       else if (switch_time != 0 && (switch_time - state.received_time) > 0)
                                aged = true;
                }
 
@@ -392,9 +402,9 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                                if (prev_locked != locked) {
                                        String currentTab = mTabHost.getCurrentTabTag();
                                        if (locked) {
-                                               if (currentTab.equals("pad")) mTabHost.setCurrentTabByTag("descent");
+                                               if (currentTab.equals(tab_pad_name)) mTabHost.setCurrentTabByTag(tab_flight_name);
                                        } else {
-                                               if (currentTab.equals("descent")) mTabHost.setCurrentTabByTag("pad");
+                                               if (currentTab.equals(tab_flight_name)) mTabHost.setCurrentTabByTag(tab_pad_name);
                                        }
                                }
                        } else {
@@ -402,16 +412,13 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                                        String currentTab = mTabHost.getCurrentTabTag();
                                        switch (state.state) {
                                        case AltosLib.ao_flight_boost:
-                                               if (currentTab.equals("pad")) mTabHost.setCurrentTabByTag("ascent");
-                                               break;
-                                       case AltosLib.ao_flight_drogue:
-                                               if (currentTab.equals("ascent")) mTabHost.setCurrentTabByTag("descent");
+                                               if (currentTab.equals(tab_pad_name)) mTabHost.setCurrentTabByTag(tab_flight_name);
                                                break;
                                        case AltosLib.ao_flight_landed:
-                                               if (currentTab.equals("descent")) mTabHost.setCurrentTabByTag("landed");
+                                               if (currentTab.equals(tab_flight_name)) mTabHost.setCurrentTabByTag(tab_recover_name);
                                                break;
                                        case AltosLib.ao_flight_stateless:
-                                               if (currentTab.equals("pad")) mTabHost.setCurrentTabByTag("descent");
+                                               if (currentTab.equals(tab_pad_name)) mTabHost.setCurrentTabByTag(tab_flight_name);
                                                break;
                                        }
                                }
@@ -457,8 +464,8 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                for (AltosDroidTab mTab : mTabs)
                        mTab.update_ui(telem_state, state, from_receiver, location, mTab == mTabsAdapter.currentItem());
 
-               if (state != null && mAltosVoice != null)
-                       mAltosVoice.tell(state, from_receiver);
+               if (mAltosVoice != null)
+                       mAltosVoice.tell(telem_state, state, from_receiver, location, (AltosDroidTab) mTabsAdapter.currentItem());
 
                saved_state = state;
        }
@@ -503,12 +510,20 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                return tab_view;
        }
 
+       public void set_map_source(int source) {
+               for (AltosDroidTab mTab : mTabs)
+                       mTab.set_map_source(source);
+       }
+
        @Override
        public void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                AltosDebug.init(this);
                AltosDebug.debug("+++ ON CREATE +++");
 
+               // Initialise preferences
+               AltosDroidPreferences.init(this);
+
                fm = getSupportFragmentManager();
 
                // Set up the window layout
@@ -523,12 +538,10 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
 
                mTabsAdapter = new TabsAdapter(this, mTabHost, mViewPager);
 
-               mTabsAdapter.addTab(mTabHost.newTabSpec("pad").setIndicator(create_tab_view("Pad")), TabPad.class, null);
-               mTabsAdapter.addTab(mTabHost.newTabSpec("ascent").setIndicator(create_tab_view("Ascent")), TabAscent.class, null);
-               mTabsAdapter.addTab(mTabHost.newTabSpec("descent").setIndicator(create_tab_view("Descent")), TabDescent.class, null);
-               mTabsAdapter.addTab(mTabHost.newTabSpec("landed").setIndicator(create_tab_view("Landed")), TabLanded.class, null);
-               mTabsAdapter.addTab(mTabHost.newTabSpec("map").setIndicator(create_tab_view("Map")), TabMap.class, null);
-               mTabsAdapter.addTab(mTabHost.newTabSpec("offmap").setIndicator(create_tab_view("OffMap")), TabMapOffline.class, null);
+               mTabsAdapter.addTab(mTabHost.newTabSpec(tab_pad_name).setIndicator(create_tab_view("Pad")), TabPad.class, null);
+               mTabsAdapter.addTab(mTabHost.newTabSpec(tab_flight_name).setIndicator(create_tab_view("Flight")), TabFlight.class, null);
+               mTabsAdapter.addTab(mTabHost.newTabSpec(tab_recover_name).setIndicator(create_tab_view("Recover")), TabRecover.class, null);
+               mTabsAdapter.addTab(mTabHost.newTabSpec(tab_map_name).setIndicator(create_tab_view("Map")), TabMap.class, null);
 
                // Display the Version
                mVersion = (TextView) findViewById(R.id.version);
@@ -639,6 +652,8 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                super.onStart();
                AltosDebug.debug("++ ON START ++");
 
+               set_switch_time();
+
                noticeIntent(getIntent());
 
                // Start Telemetry Service
@@ -676,12 +691,6 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
        public void onStop() {
                super.onStop();
                AltosDebug.debug("-- ON STOP --");
-
-               doUnbindService();
-               if (mAltosVoice != null) {
-                       mAltosVoice.stop();
-                       mAltosVoice = null;
-               }
        }
 
        @Override
@@ -689,7 +698,11 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                super.onDestroy();
                AltosDebug.debug("--- ON DESTROY ---");
 
-               if (mAltosVoice != null) mAltosVoice.stop();
+               doUnbindService();
+               if (mAltosVoice != null) {
+                       mAltosVoice.stop();
+                       mAltosVoice = null;
+               }
                stop_timer();
        }
 
@@ -821,16 +834,49 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
 
        void select_tracker(int serial) {
                int i;
-               for (i = 0; i < serials.length; i++)
-                       if (serials[i] == serial)
-                               break;
-               if (i == serials.length)
+
+               AltosDebug.debug("select tracker %d\n", serial);
+
+               if (serial == selected_serial) {
+                       AltosDebug.debug("%d already selected\n", serial);
                        return;
+               }
 
-               current_serial = serial;
+               if (serial != 0) {
+                       for (i = 0; i < serials.length; i++)
+                               if (serials[i] == serial)
+                                       break;
+
+                       if (i == serials.length) {
+                               AltosDebug.debug("attempt to select unknown tracker %d\n", serial);
+                               return;
+                       }
+               }
+
+               current_serial = selected_serial = serial;
                update_state(null);
        }
 
+       void touch_trackers(Integer[] serials) {
+               AlertDialog.Builder builder_tracker = new AlertDialog.Builder(this);
+               builder_tracker.setTitle("Select Tracker");
+               final String[] trackers = new String[serials.length + 1];
+               trackers[0] = "Auto";
+               for (int i = 0; i < serials.length; i++)
+                       trackers[i+1] = String.format("%d", serials[i]);
+               builder_tracker.setItems(trackers,
+                                        new DialogInterface.OnClickListener() {
+                                                public void onClick(DialogInterface dialog, int item) {
+                                                        if (item == 0)
+                                                                select_tracker(0);
+                                                        else
+                                                                select_tracker(Integer.parseInt(trackers[item]));
+                                                }
+                                        });
+               AlertDialog alert_tracker = builder_tracker.create();
+               alert_tracker.show();
+       }
+
        void delete_track(int serial) {
                try {
                        mService.send(Message.obtain(null, TelemetryService.MSG_DELETE_SERIAL, (Integer) serial));
@@ -918,17 +964,27 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                        serverIntent = new Intent(this, MapTypeActivity.class);
                        startActivityForResult(serverIntent, REQUEST_MAP_TYPE);
                        return true;
+               case R.id.map_source:
+                       int source = AltosDroidPreferences.map_source();
+                       int new_source = source == AltosDroidPreferences.MAP_SOURCE_ONLINE ? AltosDroidPreferences.MAP_SOURCE_OFFLINE : AltosDroidPreferences.MAP_SOURCE_ONLINE;
+                       AltosDroidPreferences.set_map_source(new_source);
+                       set_map_source(new_source);
+                       return true;
                case R.id.select_tracker:
                        if (serials != null) {
-                               String[] trackers = new String[serials.length];
+                               String[] trackers = new String[serials.length+1];
+                               trackers[0] = "Auto";
                                for (int i = 0; i < serials.length; i++)
-                                       trackers[i] = String.format("%d", serials[i]);
+                                       trackers[i+1] = String.format("%d", serials[i]);
                                AlertDialog.Builder builder_serial = new AlertDialog.Builder(this);
                                builder_serial.setTitle("Select a tracker");
                                builder_serial.setItems(trackers,
                                                        new DialogInterface.OnClickListener() {
                                                                public void onClick(DialogInterface dialog, int item) {
-                                                                       select_tracker(serials[item]);
+                                                                       if (item == 0)
+                                                                               select_tracker(0);
+                                                                       else
+                                                                               select_tracker(serials[item-1]);
                                                                }
                                                        });
                                AlertDialog alert_serial = builder_serial.create();
@@ -957,4 +1013,35 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                }
                return false;
        }
+
+       static String direction(AltosGreatCircle from_receiver,
+                            Location receiver) {
+               if (from_receiver == null)
+                       return null;
+
+               if (receiver == null)
+                       return null;
+
+               if (!receiver.hasBearing())
+                       return null;
+
+               float   bearing = receiver.getBearing();
+               float   heading = (float) from_receiver.bearing - bearing;
+
+               while (heading <= -180.0f)
+                       heading += 360.0f;
+               while (heading > 180.0f)
+                       heading -= 360.0f;
+
+               int iheading = (int) (heading + 0.5f);
+
+               if (-1 < iheading && iheading < 1)
+                       return "ahead";
+               else if (iheading < -179 || 179 < iheading)
+                       return "backwards";
+               else if (iheading < 0)
+                       return String.format("left %d°", -iheading);
+               else
+                       return String.format("right %d°", iheading);
+       }
 }