package com.tencent.gme.audio.apiexample;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;

import androidx.appcompat.app.ActionBar;

import com.gme.TMG.ITMGContext;

import java.util.HashMap;
import java.util.Map;

public class TextToSpeechActivity extends BaseActivity implements View.OnClickListener, TMGDispatcherBase {

    private Button mPlayBtn;
    private Button mStopBtn;
    private EditText mSourceEditText;
    private Spinner mLanguageSpinner;
    private Spinner mVoiceTypeSpinner;
    private TextView mRunInfo;

    private ArrayAdapter<String> mAdapter;
    private boolean mIsPlaying = false;
    private int index = 0;
    private String templeFile;

    private final String[] mLanguages = new String[]{"English(US)", "Japanese", "Chinese(mainland)",
            "Chinese(Taiwan)", "Chinese(HK)", "Korean"};
    private final Map<String, String> mLanguageCodes = new HashMap<String, String>();

    {
        mLanguageCodes.put("English(US)", "en-US");
        mLanguageCodes.put("Japanese", "ja-JP");
        mLanguageCodes.put("Chinese(mainland)", "cmn-Hans-CN");
        mLanguageCodes.put("Chinese(Taiwan)", "cmn-Hant-TW");
        mLanguageCodes.put("Chinese(HK)", "yue-Hant-HK");
        mLanguageCodes.put("Korean", "ko-KR");
    }

    private final Map<String, String[]> mVoiceTypes = new HashMap<String, String[]>();

    {
        mVoiceTypes.put("English(US)", new String[]{"en-US-Standard-A", "en-US-Standard-C",
                "en-US-Wavenet-A", "en-US-Wavenet-C"});
        mVoiceTypes.put("Japanese", new String[]{"ja-JP-Standard-A", "ja-JP-Standard-B",
                "ja-JP-Standard-C", "ja-JP-Standard-D", "ja-JP-Wavenet-A", "ja-JP-Wavenet-B",
                "ja-JP-Wavenet-C","ja-JP-Wavenet-D"});
        mVoiceTypes.put("Chinese(mainland)", new String[]{"cmn-CN-Standard-A", "cmn-CN-Standard-B",
                "cmn-CN-Wavenet-A", "cmn-CN-Wavenet-B"});
        mVoiceTypes.put("Chinese(Taiwan)", new String[]{"cmn-TW-Standard-A", "cmn-TW-Standard-B",
                "cmn-TW-Wavenet-A", "cmn-TW-Wavenet-B"});
        mVoiceTypes.put("Chinese(HK)", new String[]{"yue-HK-Standard-A", "yue-HK-Standard-B"});
        mVoiceTypes.put("Korean", new String[]{"ko-KR-Standard-A", "ko-KR-Standard-C",
                "ko-KR-Wavenet-A", "ko-KR-Wavenet-C"});
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_text_to_speech);

        ActionBar actionBar = getSupportActionBar();
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setTitle("Text To Speech");

        initViews();
        //启动一个service用于提高APP的后台优先级，避免部分机型使用openssl时播放声音异常
        Intent intent = new Intent(this, AudioService.class);
        startService(intent);

        byte[] authBuffer = GMEAuthBufferHelper.getInstance().createAuthBuffer("");
        // Step 1/12 apply ptt authbuffer
        // https://cloud.tencent.com/document/product/607/56341#.E9.89.B4.E6.9D.83.E4.BF.A1.E6.81.AF

        ITMGContext.GetInstance(this).GetPTT().ApplyPTTAuthbuffer(authBuffer);
        TMGCallbackDispatcher.getInstance().registerSubDispatcher(this);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        TMGCallbackDispatcher.getInstance().unregisterSubDispatcher(this);
    }

    private void initViews() {
        findViewById(R.id.btnClear).setOnClickListener(this);
        mPlayBtn = findViewById(R.id.btnPlay);
        mPlayBtn.setOnClickListener(this);
        mStopBtn = findViewById(R.id.btnStop);
        mStopBtn.setOnClickListener(this);
        setButtonEnable(true);

        mLanguageSpinner = findViewById(R.id.spLanguage);
        mLanguageSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
                // your code here
                setVoiceTypeAdapter();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parentView) {
                // your code here
            }
        });
        mVoiceTypeSpinner = findViewById(R.id.spVoiceType);
        mSourceEditText = findViewById(R.id.etSourceText);
        mSourceEditText.setText("Hello");
        mRunInfo = findViewById(R.id.tvRunInfo);

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_spinner_dropdown_item, mLanguages);
        mLanguageSpinner.setAdapter(adapter);
        mLanguageSpinner.setSelection(0);
        setVoiceTypeAdapter();
    }

    private void setVoiceTypeAdapter() {
        String language = mLanguageSpinner.getSelectedItem().toString();
        if (mVoiceTypes.containsKey(language)) {
            mAdapter = new ArrayAdapter<String>(this,
                    android.R.layout.simple_spinner_dropdown_item, mVoiceTypes.get(language));
            mVoiceTypeSpinner.setAdapter(mAdapter);
            mVoiceTypeSpinner.setSelection(0);
        }
    }

    @Override
    public void onClick(View v) {
        final int id = v.getId();
        if (id == R.id.btnClear) {
            mSourceEditText.setText("");
            appendLog2MonitorView("");
        } else if (id == R.id.btnPlay) {
            onPlayClick();
        } else if (id == R.id.btnStop) {
            onStopClick();
        }
    }

    private void onPlayClick() {
        if (mIsPlaying) {
            return;
        }
        mIsPlaying = true;
        appendLog2MonitorView("Text to speech ...");
        int ret = ITMGContext.GetInstance(this).GetPTT().TextToSpeech(
                mSourceEditText.getText().toString(),
                mVoiceTypeSpinner.getSelectedItem().toString(),
                mLanguageSpinner.getSelectedItem().toString(), 1);

        if (0 != ret) {
            appendLog2MonitorView(String.format("Text to speech error, error code:%d", ret));
            mIsPlaying = false;
            return;
        }
        setButtonEnable(false);
    }

    private void onStopClick() {
        mIsPlaying = false;
        appendLog2MonitorView("");
        setButtonEnable(true);
        ITMGContext.GetInstance(this).GetPTT().StopPlayFile();
    }

    private void setButtonEnable(boolean isEnable) {
        mPlayBtn.setEnabled(isEnable);
        mStopBtn.setEnabled(!isEnable);
    }

    @Override
    public void OnEvent(ITMGContext.ITMG_MAIN_EVENT_TYPE type, Intent data) {
        final int nErrCode = data.getIntExtra("result", -2);

        if (type == ITMGContext.ITMG_MAIN_EVENT_TYPE
                .ITMG_MAIN_EVNET_TYPE_PTT_TEXT2SPEECH_COMPLETE) {
            if (nErrCode == 0) {
                String fileUrl = data.getStringExtra("file_id");
                onDownloadFile(fileUrl);
            } else {
                mIsPlaying = false;
                appendLog2MonitorView(
                        String.format("Text to speech failed, error code:%d", nErrCode));
                setButtonEnable(true);
            }
        } else if (type == ITMGContext.ITMG_MAIN_EVENT_TYPE
                .ITMG_MAIN_EVNET_TYPE_PTT_DOWNLOAD_COMPLETE) {
            if (nErrCode == 0) {
                String downloadFilePath = data.getStringExtra("file_path");
                onPlayFile(downloadFilePath);
            } else {
                mIsPlaying = false;
                appendLog2MonitorView(
                        String.format("Download speech file failed, error code:%d", nErrCode));
                setButtonEnable(true);
            }
        } else if (type == ITMGContext.ITMG_MAIN_EVENT_TYPE
                .ITMG_MAIN_EVNET_TYPE_PTT_PLAY_COMPLETE) {
            if (nErrCode == 0) {
                appendLog2MonitorView("Play speech file success");
            } else {
                appendLog2MonitorView("Play speech file fail errCode:" + nErrCode);
            }
            mIsPlaying = false;
            setButtonEnable(true);
        }
    }

    private void appendLog2MonitorView(String text) {
        mRunInfo.setText(text);
    }

    private void onDownloadFile(String fileUrl) {
        if (!mIsPlaying) {
            appendLog2MonitorView("");
            return;
        }

        appendLog2MonitorView("Download speech file ...");
        templeFile = getExternalFilesDir(null).getAbsolutePath()
                + String.format("/speech_%d.ptt", index++);
        ITMGContext.GetInstance(this).GetPTT().DownloadRecordedFile(fileUrl, templeFile);
    }

    private void onPlayFile(String recordFilePath) {
        if (!mIsPlaying) {
            appendLog2MonitorView("");
            return;
        }

        appendLog2MonitorView("Play ...");
        ITMGContext.GetInstance(this).GetPTT().PlayRecordedFile(recordFilePath);
    }
}
