altosdroid: Get rid of on-line only maps tab
[fw/altos] / altosdroid / src / org / altusmetrum / AltosDroid / AltosDroid.java
index 8c9ff31f0b44d6e1777743d00bd974d8e4f75309..f664510582d291a6f902052cdb2a93ed35f8d502 100644 (file)
@@ -42,16 +42,8 @@ import android.content.res.Resources;
 import android.support.v4.app.FragmentActivity;
 import android.support.v4.app.FragmentManager;
 import android.util.DisplayMetrics;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.view.Window;
-import android.view.View;
-import android.view.LayoutInflater;
-import android.widget.TabHost;
-import android.widget.TextView;
-import android.widget.RelativeLayout;
-import android.widget.Toast;
+import android.view.*;
+import android.widget.*;
 import android.app.AlertDialog;
 import android.location.Location;
 import android.hardware.usb.*;
@@ -112,6 +104,8 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
        // Timer and Saved flight state for Age calculation
        private Timer timer;
        AltosState saved_state;
+       TelemetryState  telemetry_state;
+       Integer[]       serials;
 
        UsbDevice       pending_usb_device;
        boolean         start_with_usb;
@@ -136,13 +130,11 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                        switch (msg.what) {
                        case MSG_STATE:
                                AltosDebug.debug("MSG_STATE");
-                               TelemetryState telemetry_state = (TelemetryState) msg.obj;
-                               if (telemetry_state == null) {
+                               if (msg.obj == null) {
                                        AltosDebug.debug("telemetry_state null!");
                                        return;
                                }
-
-                               ad.update_state(telemetry_state);
+                               ad.update_state((TelemetryState) msg.obj);
                                break;
                        case MSG_UPDATE_AGE:
                                AltosDebug.debug("MSG_UPDATE_AGE");
@@ -256,19 +248,65 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                }
        }
 
+       int     current_serial;
+       long    switch_time;
+
+       void set_switch_time() {
+               switch_time = System.currentTimeMillis();
+       }
+
        boolean registered_units_listener;
 
-       void update_state(TelemetryState telemetry_state) {
+       void update_state(TelemetryState new_telemetry_state) {
+
+               if (new_telemetry_state != null)
+                       telemetry_state = new_telemetry_state;
+
+               if (current_serial == 0)
+                       current_serial = telemetry_state.latest_serial;
 
                if (!registered_units_listener) {
                        registered_units_listener = true;
                        AltosPreferences.register_units_listener(this);
                }
 
+               serials = telemetry_state.states.keySet().toArray(new Integer[0]);
+
                update_title(telemetry_state);
-               update_ui(telemetry_state.state, telemetry_state.location);
-               if (telemetry_state.connect == TelemetryState.CONNECT_CONNECTED)
-                       start_timer();
+
+               AltosState      state = null;
+               boolean         aged = true;
+
+               if (telemetry_state.states.containsKey(current_serial)) {
+                       state = telemetry_state.states.get(current_serial);
+                       int age = state_age(state);
+                       if (age < 20)
+                               aged = false;
+                       if (switch_time != 0 && (switch_time - state.received_time) > 0)
+                               aged = true;
+               }
+
+               if (aged) {
+                       AltosState      newest_state = null;
+                       int             newest_age = 0;
+
+                       for (int serial : telemetry_state.states.keySet()) {
+                               AltosState      existing = telemetry_state.states.get(serial);
+                               int             existing_age = state_age(existing);
+
+                               if (newest_state == null || existing_age < newest_age) {
+                                       newest_state = existing;
+                                       newest_age = existing_age;
+                               }
+                       }
+
+                       if (newest_state != null)
+                               state = newest_state;
+               }
+
+               update_ui(telemetry_state, state, telemetry_state.location);
+
+               start_timer();
        }
 
        boolean same_string(String a, String b) {
@@ -283,22 +321,55 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                }
        }
 
+
+       private int blend_component(int a, int b, double r, int shift, int mask) {
+               return ((int) (((a >> shift) & mask) * r + ((b >> shift) & mask) * (1 - r)) & mask) << shift;
+       }
+       private int blend_color(int a, int b, double r) {
+               return (blend_component(a, b, r, 0, 0xff) |
+                       blend_component(a, b, r, 8, 0xff) |
+                       blend_component(a, b, r, 16, 0xff) |
+                       blend_component(a, b, r, 24, 0xff));
+       }
+
+       int state_age(AltosState state) {
+               return (int) ((System.currentTimeMillis() - state.received_time + 500) / 1000);
+       }
+
+       void set_screen_on(int age) {
+               if (age < 60)
+                       getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+               else
+                       getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
+       }
+
        void update_age() {
                if (saved_state != null) {
-                       int age = (int) ((System.currentTimeMillis() - saved_state.received_time + 500) / 1000);
-                       boolean old = age >= 10;
-                       if (old != mAgeViewOld) {
-                               if (old)
-                                       mAgeView.setTextColor(mAgeOldColor);
-                               else
-                                       mAgeView.setTextColor(mAgeNewColor);
-                               mAgeViewOld = old;
-                       }
-                       mAgeView.setText(String.format("%d", age));
+                       int age = state_age(saved_state);
+
+                       double age_scale = age / 100.0;
+
+                       if (age_scale > 1.0)
+                               age_scale = 1.0;
+
+                       mAgeView.setTextColor(blend_color(mAgeOldColor, mAgeNewColor, age_scale));
+
+                       set_screen_on(age);
+
+                       String  text;
+                       if (age < 60)
+                               text = String.format("%ds", age);
+                       else if (age < 60 * 60)
+                               text = String.format("%dm", age / 60);
+                       else if (age < 60 * 60 * 24)
+                               text = String.format("%dh", age / (60 * 60));
+                       else
+                               text = String.format("%dd", age / (24 * 60 * 60));
+                       mAgeView.setText(text);
                }
        }
 
-       void update_ui(AltosState state, Location location) {
+       void update_ui(TelemetryState telem_state, AltosState state, Location location) {
 
                int prev_state = AltosLib.ao_flight_invalid;
 
@@ -308,6 +379,8 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                        prev_state = saved_state.state;
 
                if (state != null) {
+                       set_screen_on(state_age(state));
+
                        if (state.state == AltosLib.ao_flight_stateless) {
                                boolean prev_locked = false;
                                boolean locked = false;
@@ -382,7 +455,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                }
 
                for (AltosDroidTab mTab : mTabs)
-                       mTab.update_ui(state, from_receiver, location, mTab == mTabsAdapter.currentItem());
+                       mTab.update_ui(telem_state, state, from_receiver, location, mTab == mTabsAdapter.currentItem());
 
                if (state != null && mAltosVoice != null)
                        mAltosVoice.tell(state, from_receiver);
@@ -430,12 +503,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
@@ -455,7 +536,6 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
                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);
 
                // Display the Version
                mVersion = (TextView) findViewById(R.id.version);
@@ -706,6 +786,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
        void setFrequency(double freq) {
                try {
                        mService.send(Message.obtain(null, TelemetryService.MSG_SETFREQUENCY, freq));
+                       set_switch_time();
                } catch (RemoteException e) {
                }
        }
@@ -720,6 +801,7 @@ public class AltosDroid extends FragmentActivity implements AltosUnitsListener {
        void setBaud(int baud) {
                try {
                        mService.send(Message.obtain(null, TelemetryService.MSG_SETBAUD, baud));
+                       set_switch_time();
                } catch (RemoteException e) {
                }
        }
@@ -744,6 +826,25 @@ 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)
+                       return;
+
+               current_serial = serial;
+               update_state(null);
+       }
+
+       void delete_track(int serial) {
+               try {
+                       mService.send(Message.obtain(null, TelemetryService.MSG_DELETE_SERIAL, (Integer) serial));
+               } catch (Exception ex) {
+               }
+       }
+
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
                Intent serverIntent = null;
@@ -824,8 +925,49 @@ 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];
+                               for (int i = 0; i < serials.length; i++)
+                                       trackers[i] = 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]);
+                                                               }
+                                                       });
+                               AlertDialog alert_serial = builder_serial.create();
+                               alert_serial.show();
+
+                       }
+                       return true;
+               case R.id.delete_track:
+                       if (serials != null) {
+                               String[] trackers = new String[serials.length];
+                               for (int i = 0; i < serials.length; i++)
+                                       trackers[i] = String.format("%d", serials[i]);
+                               AlertDialog.Builder builder_serial = new AlertDialog.Builder(this);
+                               builder_serial.setTitle("Delete a track");
+                               builder_serial.setItems(trackers,
+                                                       new DialogInterface.OnClickListener() {
+                                                               public void onClick(DialogInterface dialog, int item) {
+                                                                       delete_track(serials[item]);
+                                                               }
+                                                       });
+                               AlertDialog alert_serial = builder_serial.create();
+                               alert_serial.show();
+
+                       }
+                       return true;
                }
                return false;
        }
-
 }