package com.platypii.baseline.jarvis;

import com.platypii.baseline.Services;
import com.platypii.baseline.measurements.MLocation;
import android.os.Handler;
import android.util.Log;

/**
 * Automatically stop logging when landing is detected (after a known jump)
 */
public class AutoStop {
    private static final String TAG = "AutoStop";

    public static boolean preferenceEnabled = true;

    // Jump detection state
    private static final int STATE_STOPPED = 0;
    private static final int STATE_STARTED = 1;
    private static final int STATE_EXITED = 2;
    private int state = STATE_STOPPED;

    private static final String landing_message = "Landing detected";
    private static final String timeout_message = "Jump timeout";

    // When auto stop is enabled, if we haven't detected landing in 1 hour, stop recording
    private final static Handler handler = new Handler();
    private static final long autoTimeout = 3600000; // 1 hour

    private static final double minHeight = 60;

    private double prExited = 0;
    private double prLanded = 0;

    private double altMin = Double.NaN;
    private double altMax = Double.NaN;

    void update(MLocation loc) {
        final double alt = loc.altitude_gps;
        // Update altitude range
        if(!Double.isNaN(alt)) {
            if(!(altMin < alt)) altMin = alt;
            if(!(alt < altMax)) altMax = alt;
        }
        // Update state
        if(state == STATE_STARTED) {
            // Look for flight / freefall
            if(loc.climb < -15 && altMax - alt > minHeight) {
                prExited += (1 - prExited) * 0.6;
            } else if(loc.flightMode() == FlightMode.MODE_CANOPY && altMax - alt > minHeight) {
                prExited += (1 - prExited) * 0.2;
            } else {
                prExited -= prExited * 0.6;
            }
            if(prExited > 0.85) {
                Log.i(TAG, "Exit detected");
                state = STATE_EXITED;
            }
        } else if(state == STATE_EXITED) {
            // Look for landing
            final double altNormalized = (alt - altMin) / (altMax - altMin);
            if(loc.flightMode() == FlightMode.MODE_GROUND && altMax - altMin > minHeight && altNormalized < 0.1) {
                prLanded += (1 - prLanded) * 0.2;
            }
            if(prLanded > 0.95) {
                landed(landing_message);
            }
        }
    }

    void start() {
        if(state == STATE_STOPPED) {
            // Reset state
            state = STATE_STARTED;
            prExited = 0;
            prLanded = 0;
            // TODO: Should we reset altitude range per recording or per app session?
            altMin = Double.NaN;
            altMax = Double.NaN;
            // When auto stop is enabled, timeout after 1 hour
            handler.postDelayed(stopRunnable, autoTimeout);
        } else {
            Log.e(TAG, "Autostop should not be started twice");
        }
    }

    void stop() {
        if(state != STATE_STOPPED) {
            state = STATE_STOPPED;
            // Stop timeout thread
            handler.removeCallbacks(stopRunnable);
        } else {
            Log.e(TAG, "Autostop should not be stopped twice");
        }
    }

    private void landed(String msg) {
        Log.i(TAG, "Auto-stop landing detected: " + msg);
        state = STATE_STOPPED;
        // If audible enabled, say landing detected
        if(preferenceEnabled) {
            // If audible enabled, disable
            if(Services.audible.isEnabled()) {
                Services.audible.speakNow(msg);
                Services.audible.disableAudible();
            }
            // If logging enabled, disable
            if(Services.logger.isLogging()) {
                Services.logger.stopLogging();
                // TODO: Returns a trackfile, upload to cloud?
            } else {
                Log.e(TAG, "Landing detected, but logger not logging");
            }
        }
    }

    /**
     * A thread that stops recording after 1 hour
     */
    private final Runnable stopRunnable = new Runnable() {
        @Override
        public void run() {
            Log.i(TAG, "Auto-stop timeout");
            landed(timeout_message);
        }
    };

}

@@ -2324,17 +2324,17 @@
 ed %3E 0.9
-5
+8
 ) %7B%0A    

Increase landing threshhold for auto stop