/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.drrickorang.loopback;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.CompoundButton;
import android.widget.PopupWindow;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.ToggleButton;


/**
 * This activity displays all settings that can be adjusted by the user.
 */

public class SettingsActivity extends Activity implements OnItemSelectedListener,
        ToggleButton.OnCheckedChangeListener {

    private static final String TAG = "SettingsActivity";

    private Spinner      mSpinnerMicSource;
    private Spinner      mSpinnerPerformanceMode;
    private Spinner      mSpinnerSamplingRate;
    private Spinner      mSpinnerAudioThreadType;
    private TextView     mTextSettingsInfo;
    private Spinner      mSpinnerChannelIndex;
    private SettingsPicker mPlayerBufferUI;
    private SettingsPicker mRecorderBufferUI;
    private SettingsPicker mBufferTestDurationUI;
    private SettingsPicker mWavePlotDurationUI;
    private SettingsPicker mLoadThreadUI;
    private SettingsPicker mNumCapturesUI;
    private SettingsPicker mIgnoreFirstFramesUI;
    private ToggleButton   mSystraceToggleButton;
    private ToggleButton   mBugreportToggleButton;
    private ToggleButton   mWavCaptureToggleButton;
    private ToggleButton   mSoundLevelCalibrationToggleButton;

    ArrayAdapter<CharSequence> mAdapterSamplingRate;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Set the layout for this activity. You can find it
        View view = getLayoutInflater().inflate(R.layout.settings_activity, null);
        setContentView(view);
        mTextSettingsInfo = (TextView) findViewById(R.id.textSettingsInfo);

        int micSource = getApp().getMicSource();
        mSpinnerMicSource = (Spinner) findViewById(R.id.spinnerMicSource);
        ArrayAdapter<CharSequence> adapterMicSource = ArrayAdapter.createFromResource(this,
                R.array.mic_source_array, android.R.layout.simple_spinner_item);
        // Specify the layout to use when the list of choices appears
        adapterMicSource.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        // Apply the adapter to the spinner
        mSpinnerMicSource.setAdapter(adapterMicSource);
        //set current value
        mSpinnerMicSource.setSelection(micSource, false);
        mSpinnerMicSource.setOnItemSelectedListener(this);

        int performanceMode = getApp().getPerformanceMode();
        mSpinnerPerformanceMode = (Spinner) findViewById(R.id.spinnerPerformanceMode);
        ArrayAdapter<CharSequence> adapterPerformanceMode = ArrayAdapter.createFromResource(this,
                R.array.performance_mode_array, android.R.layout.simple_spinner_item);
        // Specify the layout to use when the list of choices appears
        adapterPerformanceMode.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        // Apply the adapter to the spinner
        mSpinnerPerformanceMode.setAdapter(adapterPerformanceMode);
        //set current value
        mSpinnerPerformanceMode.setSelection(performanceMode + 1, false);
        mSpinnerPerformanceMode.setOnItemSelectedListener(this);

        int samplingRate = getApp().getSamplingRate();
        //init spinner, etc
        mSpinnerSamplingRate = (Spinner) findViewById(R.id.spinnerSamplingRate);
        mAdapterSamplingRate = ArrayAdapter.createFromResource(this,
                R.array.samplingRate_array, android.R.layout.simple_spinner_item);
        // Specify the layout to use when the list of choices appears
        mAdapterSamplingRate.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        // Apply the adapter to the spinner
        mSpinnerSamplingRate.setAdapter(mAdapterSamplingRate);
        //set current value
        String currentValue = String.valueOf(samplingRate);
        int nPosition = mAdapterSamplingRate.getPosition(currentValue);
        mSpinnerSamplingRate.setSelection(nPosition, false);
        mSpinnerSamplingRate.setOnItemSelectedListener(this);

        //spinner native
        int audioThreadType = getApp().getAudioThreadType();
        mSpinnerAudioThreadType = (Spinner) findViewById(R.id.spinnerAudioThreadType);
        ArrayAdapter<CharSequence> adapter2 = ArrayAdapter.createFromResource(this,
                R.array.audioThreadType_array, android.R.layout.simple_spinner_item);
        // Specify the layout to use when the list of choices appears
        adapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        // Apply the adapter to the spinner
        mSpinnerAudioThreadType.setAdapter(adapter2);
        //set current value
        mSpinnerAudioThreadType.setSelection(audioThreadType, false);
        if (!getApp().isSafeToUseSles())
            mSpinnerAudioThreadType.setEnabled(false);
        mSpinnerAudioThreadType.setOnItemSelectedListener(this);

        mSpinnerChannelIndex = (Spinner) findViewById(R.id.spinnerChannelIndex);
        ArrayAdapter<CharSequence> adapter3 = ArrayAdapter.createFromResource(this,
                R.array.channelIndex_array, android.R.layout.simple_spinner_item);
        // Specify the layout to use when the list of choices appears
        adapter3.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        // Apply the adapter to the spinner
        mSpinnerChannelIndex.setAdapter(adapter3);
        mSpinnerChannelIndex.setOnItemSelectedListener(this);

        // Settings Picker for Buffer Test Duration
        mBufferTestDurationUI = (SettingsPicker) findViewById(R.id.bufferTestDurationSetting);
        mBufferTestDurationUI.setMinMaxDefault(Constant.BUFFER_TEST_DURATION_SECONDS_MIN,
                Constant.BUFFER_TEST_DURATION_SECONDS_MAX, getApp().getBufferTestDuration());
        mBufferTestDurationUI.setTitle(getResources().getString(R.string.labelBufferTestDuration,
                Constant.BUFFER_TEST_DURATION_SECONDS_MAX));
        mBufferTestDurationUI.setSettingsChangeListener(new SettingsPicker.SettingChangeListener() {
            @Override
            public void settingChanged(int seconds) {
                log("buffer test new duration: " + seconds);
                getApp().setBufferTestDuration(seconds);
                setSettingsHaveChanged();
            }
        });

        // Settings Picker for Wave Plot Duration
        mWavePlotDurationUI = (SettingsPicker) findViewById(R.id.wavePlotDurationSetting);
        mWavePlotDurationUI.setMinMaxDefault(Constant.BUFFER_TEST_WAVE_PLOT_DURATION_SECONDS_MIN,
                Constant.BUFFER_TEST_WAVE_PLOT_DURATION_SECONDS_MAX,
                getApp().getBufferTestWavePlotDuration());
        mWavePlotDurationUI.setTitle(getResources().getString(
                R.string.labelBufferTestWavePlotDuration,
                Constant.BUFFER_TEST_WAVE_PLOT_DURATION_SECONDS_MAX));
        mWavePlotDurationUI.setSettingsChangeListener(new SettingsPicker.SettingChangeListener() {
            @Override
            public void settingChanged(int value) {
                log("buffer test's wave plot new duration:" + value);
                getApp().setBufferTestWavePlotDuration(value);
                setSettingsHaveChanged();
            }
        });

        // Settings Picker for Player Buffer Period
        mPlayerBufferUI = (SettingsPicker) findViewById(R.id.playerBufferSetting);
        mPlayerBufferUI.setMinMaxDefault(Constant.PLAYER_BUFFER_FRAMES_MIN,
                Constant.PLAYER_BUFFER_FRAMES_MAX,
                getApp().getPlayerBufferSizeInBytes() / Constant.BYTES_PER_FRAME);
        mPlayerBufferUI.setTitle(getResources().getString(
                R.string.labelPlayerBuffer, Constant.PLAYER_BUFFER_FRAMES_MAX));
        mPlayerBufferUI.setSettingsChangeListener(new SettingsPicker.SettingChangeListener() {
            @Override
            public void settingChanged(int value) {
                log("player buffer new size " + value);
                getApp().setPlayerBufferSizeInBytes(value * Constant.BYTES_PER_FRAME);
                int audioThreadType = mSpinnerAudioThreadType.getSelectedItemPosition();
                // in native mode, recorder buffer size = player buffer size
                if (audioThreadType == Constant.AUDIO_THREAD_TYPE_NATIVE) {
                    getApp().setRecorderBufferSizeInBytes(value * Constant.BYTES_PER_FRAME);
                    mRecorderBufferUI.setValue(value);
                }
                setSettingsHaveChanged();
            }
        });

        // Settings Picker for Recorder Buffer Period
        mRecorderBufferUI = (SettingsPicker) findViewById(R.id.recorderBufferSetting);
        mRecorderBufferUI.setMinMaxDefault(Constant.RECORDER_BUFFER_FRAMES_MIN,
                Constant.RECORDER_BUFFER_FRAMES_MAX,
                getApp().getRecorderBufferSizeInBytes() / Constant.BYTES_PER_FRAME);
        mRecorderBufferUI.setTitle(getResources().getString(R.string.labelRecorderBuffer,
                Constant.RECORDER_BUFFER_FRAMES_MAX));
        mRecorderBufferUI.setSettingsChangeListener(new SettingsPicker.SettingChangeListener() {
            @Override
            public void settingChanged(int value) {
                log("recorder buffer new size:" + value);
                getApp().setRecorderBufferSizeInBytes(value * Constant.BYTES_PER_FRAME);
                setSettingsHaveChanged();
            }
        });

        // Settings Picker for Number of Load Threads
        mLoadThreadUI = (SettingsPicker) findViewById(R.id.numLoadThreadsSetting);
        mLoadThreadUI.setMinMaxDefault(Constant.MIN_NUM_LOAD_THREADS, Constant.MAX_NUM_LOAD_THREADS,
                getApp().getNumberOfLoadThreads());
        mLoadThreadUI.setTitle(getResources().getString(R.string.loadThreadsLabel));
        mLoadThreadUI.setSettingsChangeListener(new SettingsPicker.SettingChangeListener() {
            @Override
            public void settingChanged(int value) {
                log("new num load threads:" + value);
                getApp().setNumberOfLoadThreads(value);
                setSettingsHaveChanged();
            }
        });

        // Settings Picker for Number of Captures
        mNumCapturesUI = (SettingsPicker) findViewById(R.id.numCapturesSettingPicker);
        mNumCapturesUI.setMinMaxDefault(Constant.MIN_NUM_CAPTURES, Constant.MAX_NUM_CAPTURES,
                getApp().getNumStateCaptures());
        mNumCapturesUI.setTitle(getResources().getString(R.string.numCapturesSetting));
        mNumCapturesUI.setSettingsChangeListener(new SettingsPicker.SettingChangeListener() {
            @Override
            public void settingChanged(int value) {
                log("new num captures:" + value);
                getApp().setNumberOfCaptures(value);
                setSettingsHaveChanged();
            }
        });

        mWavCaptureToggleButton = (ToggleButton) findViewById(R.id.wavSnippetsEnabledToggle);
        mWavCaptureToggleButton.setChecked(getApp().isCaptureWavSnippetsEnabled());
        mWavCaptureToggleButton.setOnCheckedChangeListener(this);

        mBugreportToggleButton = (ToggleButton) findViewById(R.id.BugreportEnabledToggle);
        mBugreportToggleButton.setChecked(getApp().isCaptureBugreportEnabled());
        mBugreportToggleButton.setOnCheckedChangeListener(this);

        mSystraceToggleButton = (ToggleButton) findViewById(R.id.SystraceEnabledToggle);
        mSystraceToggleButton.setChecked(getApp().isCaptureSysTraceEnabled());
        mSystraceToggleButton.setOnCheckedChangeListener(this);

        mSoundLevelCalibrationToggleButton = (ToggleButton)
                findViewById(R.id.soundLevelCalibrationEnabledToggle);
        mSoundLevelCalibrationToggleButton.setChecked(getApp().isSoundLevelCalibrationEnabled());
        mSoundLevelCalibrationToggleButton.setOnCheckedChangeListener(this);

        // Settings Picker for number of frames to ignore at the beginning
        mIgnoreFirstFramesUI = (SettingsPicker) findViewById(R.id.ignoreFirstFramesSettingPicker);
        mIgnoreFirstFramesUI.setMinMaxDefault(Constant.MIN_IGNORE_FIRST_FRAMES,
                Constant.MAX_IGNORE_FIRST_FRAMES, getApp().getIgnoreFirstFrames());
        mIgnoreFirstFramesUI.setTitle(getResources().getString(R.string.labelIgnoreFirstFrames,
                Constant.MAX_IGNORE_FIRST_FRAMES));
        mIgnoreFirstFramesUI.setSettingsChangeListener(new SettingsPicker.SettingChangeListener() {
            @Override
            public void settingChanged(int frames) {
                log("new number of first frames to ignore: " + frames);
                getApp().setIgnoreFirstFrames(frames);
                setSettingsHaveChanged();
            }
        });

        refresh();
    }


    public void onDestroy() {
        super.onDestroy();
    }


    @Override
    public void onBackPressed() {
        log("on back pressed");
        setSettingsHaveChanged();
        finish();
    }


    private void refresh() {
        mBufferTestDurationUI.setValue(getApp().getBufferTestDuration());
        mWavePlotDurationUI.setValue(getApp().getBufferTestWavePlotDuration());

        mPlayerBufferUI.setValue(getApp().getPlayerBufferSizeInBytes() / Constant.BYTES_PER_FRAME);
        mRecorderBufferUI.setValue(
                getApp().getRecorderBufferSizeInBytes() / Constant.BYTES_PER_FRAME);

        mRecorderBufferUI.setEnabled(
                getApp().getAudioThreadType() == Constant.AUDIO_THREAD_TYPE_JAVA);

        int samplingRate = getApp().getSamplingRate();
        String currentValue = String.valueOf(samplingRate);
        int nPosition = mAdapterSamplingRate.getPosition(currentValue);
        mSpinnerSamplingRate.setSelection(nPosition);


        if (getApp().getAudioThreadType() == Constant.AUDIO_THREAD_TYPE_JAVA) {
            mSpinnerChannelIndex.setSelection(getApp().getChannelIndex() + 1, false);
            mSpinnerChannelIndex.setEnabled(true);
        } else {
            mSpinnerChannelIndex.setSelection(0, false);
            mSpinnerChannelIndex.setEnabled(false);
        }

        mNumCapturesUI.setEnabled(getApp().isCaptureEnabled() ||
                getApp().isCaptureWavSnippetsEnabled());

        String info = getApp().getSystemInfo();
        mTextSettingsInfo.setText("SETTINGS - " + info);
    }


    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
        // An item was selected. You can retrieve the selected item using
        // parent.getItemAtPosition(pos)
        log("item selected!");

        switch (parent.getId()) {
        case R.id.spinnerSamplingRate:
            String stringValue = mSpinnerSamplingRate.getSelectedItem().toString();
            int samplingRate = Integer.parseInt(stringValue);
            getApp().setSamplingRate(samplingRate);
            setSettingsHaveChanged();
            log("Sampling Rate: " + stringValue);
            refresh();
            break;
        case R.id.spinnerAudioThreadType:
            int audioThreadType = mSpinnerAudioThreadType.getSelectedItemPosition();
            getApp().setAudioThreadType(audioThreadType);
            getApp().computeDefaults();
            setSettingsHaveChanged();
            log("AudioThreadType:" + audioThreadType);
            refresh();
            break;
        case R.id.spinnerChannelIndex:
            int channelIndex = mSpinnerChannelIndex.getSelectedItemPosition() - 1;
            getApp().setChannelIndex(channelIndex);
            setSettingsHaveChanged();
            log("channelIndex:" + channelIndex);
            refresh();
            break;
        case R.id.spinnerMicSource:
            int micSource = mSpinnerMicSource.getSelectedItemPosition();
            getApp().setMicSource(micSource);
            setSettingsHaveChanged();
            log("mic Source:" + micSource);
            refresh();
            break;
        case R.id.spinnerPerformanceMode:
            int performanceMode = mSpinnerPerformanceMode.getSelectedItemPosition() - 1;
            getApp().setPerformanceMode(performanceMode);
            setSettingsHaveChanged();
            log("performanceMode:" + performanceMode);
            refresh();
            break;
        }
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (buttonView.getId() == mWavCaptureToggleButton.getId()){
            getApp().setCaptureWavsEnabled(isChecked);
        } else if (buttonView.getId() == mSystraceToggleButton.getId()) {
            getApp().setCaptureSysTraceEnabled(isChecked);
        } else if (buttonView.getId() == mBugreportToggleButton.getId()) {
            getApp().setCaptureBugreportEnabled(isChecked);
        } else if (buttonView.getId() == mSoundLevelCalibrationToggleButton.getId()) {
            getApp().setSoundLevelCalibrationEnabled(isChecked);
        }
        mNumCapturesUI.setEnabled(getApp().isCaptureEnabled() ||
                getApp().isCaptureWavSnippetsEnabled());
    }

    private void setSettingsHaveChanged() {
        Intent intent = new Intent();
        setResult(RESULT_OK, intent);
    }


    public void onNothingSelected(AdapterView<?> parent) {
        // Another interface callback
    }

    public void onButtonHelp(View view) {
        // Create a PopUpWindow with scrollable TextView
        View puLayout = this.getLayoutInflater().inflate(R.layout.report_window, null);
        PopupWindow popUp = new PopupWindow(puLayout, ViewGroup.LayoutParams.MATCH_PARENT,
                ViewGroup.LayoutParams.MATCH_PARENT, true);

        TextView helpText =
                (TextView) popUp.getContentView().findViewById(R.id.ReportInfo);
        if (view.getId() == R.id.buttonSystraceHelp || view.getId() == R.id.buttonBugreportHelp) {
            helpText.setText(getResources().getString(R.string.systraceHelp));
        } else if (view.getId() == R.id.buttonCalibrateSoundLevelHelp) {
            helpText.setText(getResources().getString(R.string.calibrateSoundLevelHelp));
        }

        // display pop up window, dismissible with back button
        popUp.showAtLocation(findViewById(R.id.settingsMainLayout), Gravity.TOP, 0, 0);
    }

        /** Called when the user clicks the button */
    public void onButtonClick(View view) {
        getApp().computeDefaults();
        refresh();
    }

// Below is work in progress by Ricardo
//    public void onButtonRecordDefault(View view) {
//        int samplingRate = getApp().getSamplingRate();
//
//        int minRecorderBufferSizeInBytes =  AudioRecord.getMinBufferSize(samplingRate,
//                AudioFormat.CHANNEL_IN_MONO,
//                AudioFormat.ENCODING_PCM_16BIT);
//        getApp().setRecorderBufferSizeInBytes(minRecorderBufferSizeInBytes);
//
//        refresh();
//    }

//    private void computeDefaults() {
//
////        if (getApp().getAudioThreadType() == LoopbackApplication.AUDIO_THREAD_TYPE_JAVA) {
////            mNumberPickerRecorderBuffer.setEnabled(true);
////        else
////            mNumberPickerRecorderBuffer.setEnabled(false);
//
//        int samplingRate = AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_MUSIC);
//        getApp().setSamplingRate(samplingRate);
//        int minPlayerBufferSizeInBytes = AudioTrack.getMinBufferSize(samplingRate,
//                AudioFormat.CHANNEL_OUT_MONO,
//                AudioFormat.ENCODING_PCM_16BIT);
//        getApp().setPlayerBufferSizeInBytes(minPlayerBufferSizeInBytes);
//
//        int minRecorderBufferSizeInBytes =  AudioRecord.getMinBufferSize(samplingRate,
//                AudioFormat.CHANNEL_IN_MONO,
//                AudioFormat.ENCODING_PCM_16BIT);
//        getApp().setRecorderBufferSizeInBytes(minRecorderBufferSizeInBytes);
//        getApp().setRecorderBufferSizeInBytes(minRecorderBufferSizeInBytes);
//
//        log("computed defaults");
//
//    }

    private LoopbackApplication getApp() {
        return (LoopbackApplication) this.getApplication();
    }


    private static void log(String msg) {
        Log.v(TAG, msg);
    }


}
