package party.bami.eqfix.analysis;

import android.media.AudioTrack;
import android.os.AsyncTask;
import android.os.SystemClock;
import android.widget.Toast;

import org.jtransforms.fft.FloatFFT_1D;

import java.io.IOException;
import java.util.Arrays;

import party.bami.eqfix.R;
import party.bami.eqfix.VisualizerView;
import party.bami.eqfix.channels.ChanMode;
import party.bami.eqfix.fragment.AnalysisFragment;
import party.bami.eqfix.preset.EQFPreset;
import party.bami.eqfix.transientGenerator.TransientGenerator;

import static android.media.AudioRecord.READ_NON_BLOCKING;

public class Analysis extends AsyncTask<Void, Object, Object> {
    private AnalysisFragment analysisFragment;
    public Analysis(AnalysisFragment analysisFragment) {
        this.analysisFragment = analysisFragment;
    }

    @Override
    protected Object doInBackground(Void... params) {
        int sampR = 44100;
        int noiseDuration = 30;

//        /* Measuring the transient delay. */
//        TransientGenerator tg = new TransientGenerator(sampR);
//        MicAnalysis microphone = new MicAnalysis();
//        PCMPlayer pcmp = new PCMPlayer();
//
//        publishProgress("Toast", "Generating transients");
//        float[] trancient = tg.generate(3, 3 * sampR, 100);
//        pcmp.play(trancient, sampR, ChanMode.STEREO);
//
//        /* Records the transients in segments. */
//        publishProgress("Toast", "Recording started");
//        float[] result = microphone.record(2, sampR);
//        pcmp.release();
//        publishProgress("Toast", "Recording finished");


        /* Measuring the frequency response. */
        WhiteNoise wn = new WhiteNoise();
        MicAnalysis microphone = new MicAnalysis();
        PCMPlayer pcmp = new PCMPlayer();
        EQFPreset preset = new EQFPreset(analysisFragment.getContext());

        publishProgress("Toast", "Recording started");
        microphone.record(noiseDuration, sampR);

        float[] noise = wn.gen(noiseDuration * sampR * 2);
        publishProgress("Toast", "Playing noise");
        pcmp.play(noise, sampR, ChanMode.STEREO, AudioTrack.WRITE_BLOCKING);
        publishProgress("Toast", "Fetching recording");
        float[] result = microphone.get(noiseDuration, sampR);
        publishProgress("Toast", "Recording finished");

        /* Deconvolve the frequency response. */
        Deconvolver deconvolver = new Deconvolver(2048);
        float[] kernel = deconvolver.getKernel(result, noise, 1024);

        // Saving the acquired parameters to a preset file.
        publishProgress("Toast", "Saving preset");
        preset.setData(kernel, 0, 0);
        try {
            preset.save("test.eqf");
        } catch (PresetEmptyException|IOException e) {
            e.printStackTrace();
        }

        return result;
    }

    protected void onProgressUpdate(Object... progress) {
        switch (progress.length) {
            case 1:
                VisualizerView mVisualizerView = (VisualizerView) analysisFragment.getInflatedView().findViewById(R.id.visualizerView);
                float[] buffer = (float[]) progress[0];
                mVisualizerView.updateVisualizer(buffer);
                break;
            case 2:
                String notification = (String) progress[1];
                Toast.makeText(analysisFragment.getContext(), notification, Toast.LENGTH_SHORT).show();
                break;
            default:
                Toast.makeText(analysisFragment.getContext(), progress.length + " is not a valid argument.", Toast.LENGTH_SHORT).show();
        }
    }

    protected void onPostExecute(Object result) {
        float[] resF = (float[]) result;
        VisualizerView mVisualizerView = (VisualizerView) analysisFragment.getInflatedView().findViewById(R.id.visualizerView);
        float[] FFT = Split.averageSpilt(Split.getSplitFFTReal(Split.splitPCM(resF, 512)));
        mVisualizerView.updateVisualizer(FFT);
    }
}
