package party.bami.eqfix.analysis;

import android.media.AudioFormat;
import android.media.AudioManager;
import android.media.AudioRecord;
import android.media.AudioTrack;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.widget.Toast;

import java.util.Arrays;
import java.util.Vector;

import java.util.concurrent.TimeUnit;

import party.bami.eqfix.R;
import party.bami.eqfix.VisualizerView;
import party.bami.eqfix.fragment.AnalysisFragment;

import static android.media.AudioRecord.READ_NON_BLOCKING;

/* Records the Microphone for a given duration the segments of 10ms. */
public class MicAnalysis {
    AudioRecord rec;
    /* Records the microphone and returns it as a float[]. */
    public void record(int duration, int sampleRate) {
        int nSamples = sampleRate * duration;
        /* Only even numbers are valid audio buffer sizes. */
        if (nSamples % 2 != 0)
            nSamples -= 1;

        /* Records the microphone for the given duration */
        rec = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, nSamples);
        rec.startRecording();
    }

    public float[] get(int duration, int sampleRate) {
        int nSamples = sampleRate * duration;
        /* Only even numbers are valid audio buffer sizes. */
        if (nSamples % 2 != 0)
            nSamples -= 1;
        short[] buffer = new short[nSamples];
        rec.read(buffer, 0, nSamples);
        rec.release();

        return pcm16ToFloat(buffer);
    }

    /**
     * Normalizes and converts the buffer to floats.
     * @param pcm16 short buffer
     * @return float buffer
     */
    private float[] pcm16ToFloat(short[] pcm16) {
        float[] pcmFloat = new float[pcm16.length];
        for (int i = 0; i < pcmFloat.length; i++)
            pcmFloat[i] = pcm16[i] / 65535f;

        return pcmFloat;
    }

    private Vector<Integer> powers =  new Vector<>();
    /* If a display is set it displays the current buffer segment. */
    public void transientDetect(short[] buffer) {
        int sampleSize = 10;

        int power = 0;
        for (short sample : buffer)
            power += Math.abs(sample);

        powers.add(power);
        if (powers.size() > sampleSize) {
            int avgPower = 0;
            for (int i = 0; i < sampleSize; i++)
                avgPower += powers.get(i);

            if (powers.get(sampleSize) > avgPower) {
                System.out.println("Found one: " + powers.get(sampleSize) + " > " + avgPower);
            }

            powers.remove(0);
        }
    }

    // Temp
    public void play(float[] buffer) {
        AudioTrack at = new AudioTrack(AudioManager.STREAM_MUSIC,
                44100, AudioFormat.CHANNEL_OUT_MONO,
                AudioFormat.ENCODING_PCM_FLOAT,
                buffer.length,
                AudioTrack.MODE_STREAM);
        at.write(buffer, 0, buffer.length, AudioTrack.WRITE_NON_BLOCKING);
        at.play();
    }
}
