package com.wytehat.btlogger;

import android.content.Context;
import android.media.AudioManager;
import android.media.ToneGenerator;
import android.os.Handler;
import android.os.Vibrator;

public class NativeFeedbackController {
    private final Handler handler = new Handler();
    private final Vibrator vibrator;
    private ToneGenerator tone;
    private boolean running;
    private boolean audioEnabled;
    private boolean hapticEnabled = true;
    private String state = RangeStateMachine.LOST;
    private double rssi = -100;

    public NativeFeedbackController(Context context) {
        vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
    }

    public void setAudioEnabled(boolean enabled) {
        audioEnabled = enabled;
        if (enabled && tone == null) tone = new ToneGenerator(AudioManager.STREAM_MUSIC, 55);
    }

    public void setHapticEnabled(boolean enabled) { hapticEnabled = enabled; }

    public void update(String newState, double filteredRssi) {
        if (RangeStateMachine.LOST.equals(newState)) { stop(); state = newState; return; }
        state = newState;
        rssi = filteredRssi;
        if (!running) {
            running = true;
            handler.post(pulse);
        }
    }

    private final Runnable pulse = new Runnable() {
        public void run() {
            if (!running || RangeStateMachine.LOST.equals(state)) return;
            int delay = delayFor(state, rssi);
            if (audioEnabled && tone != null) {
                int sound = RangeStateMachine.HOT.equals(state)
                    ? ToneGenerator.TONE_PROP_BEEP2 : ToneGenerator.TONE_PROP_BEEP;
                tone.startTone(sound, RangeStateMachine.HOT.equals(state) ? 55 : 35);
            }
            if (hapticEnabled && vibrator != null) {
                try {
                    if (RangeStateMachine.HOT.equals(state)) vibrator.vibrate(
                        new long[] { 0, 45, 30, 45 }, -1);
                    else if (RangeStateMachine.WARM.equals(state)) vibrator.vibrate(35);
                    else vibrator.vibrate(18);
                } catch (Exception ignored) { }
            }
            handler.postDelayed(this, delay);
        }
    };

    private int delayFor(String value, double filteredRssi) {
        if (RangeStateMachine.HOT.equals(value))
            return Math.max(100, 210 - (int) Math.abs(filteredRssi + 60) * 8);
        if (RangeStateMachine.WARM.equals(value))
            return Math.max(350, 760 - (int) Math.abs(filteredRssi + 80) * 14);
        return 1200;
    }

    public void stop() {
        running = false;
        handler.removeCallbacks(pulse);
        try { if (vibrator != null) vibrator.cancel(); } catch (Exception ignored) { }
    }

    public void release() {
        stop();
        if (tone != null) { tone.release(); tone = null; }
    }
}
