#include "com_audio.h"
#include "log2ui.h"

///
using namespace rtc;

///
Com_Audio::Com_Audio(QWidget *parent) : QWidget(parent) {
	ui.setupUi(this);
	connect(ui.btn_audio_openMicrophone_un, SIGNAL(toggled(bool)), this, SLOT(on_opencloseMicrophone(bool)));
	connect(ui.btn_audio_muteLocalMicrophone_un, SIGNAL(toggled(bool)), this, SLOT(on_muteMicrophone(bool)));
	connect(ui.btn_audio_muteLocalSpeaker_un, SIGNAL(toggled(bool)), this, SLOT(on_muteSpeaker(bool)));
	//connect(ui.btn_audio_muteLocalSpeaker_un, SIGNAL(toggled(bool)), this, SLOT(on_monitorAudioLevel(bool)));
	connect(ui.btn_audio_playoutGain, SIGNAL(toggled(bool)), this, SLOT(on_applyPlayoutGain(bool)));
	fillCodecs();
    connect(ui.lst_audio_localMicrophones, SIGNAL(itemSelectionChanged()), this, SLOT(localMicrophones_itemChanged()));
    connect(ui.lst_audio_localSpeakers, SIGNAL(itemSelectionChanged()), this, SLOT(localSpeakers_itemChanged()));
	connect(ui.ckb_audio_aec, SIGNAL(stateChanged(int)), this, SLOT(audio_aec_stateChanged(int)));
	connect(ui.ckb_audio_dae, SIGNAL(stateChanged(int)), this, SLOT(audio_dae_stateChanged(int)));
	connect(ui.ckb_audio_agc, SIGNAL(stateChanged(int)), this, SLOT(audio_agc_stateChanged(int)));
	connect(ui.ckb_audio_hpf, SIGNAL(stateChanged(int)), this, SLOT(audio_hpf_stateChanged(int)));
	connect(ui.ckb_audio_ns, SIGNAL(stateChanged(int)), this, SLOT(audio_ns_stateChanged(int)));
}
Com_Audio::~Com_Audio() {
}
void Com_Audio::resetControls(bool enable) {
	ButtonChecked(ui.btn_audio_openMicrophone_un, false, Utf8Str("发布"));
	ButtonChecked(ui.btn_audio_muteLocalMicrophone_un, false, Utf8Str("暂停"));
	ButtonChecked(ui.btn_audio_muteLocalSpeaker_un, false, Utf8Str("暂停"));
	ui.btn_audio_openMicrophone_un->setEnabled(enable);
	ui.btn_audio_muteLocalMicrophone_un->setEnabled(enable);
	ui.btn_audio_muteLocalSpeaker_un->setEnabled(enable);
	ui.cbo_audio_codecs->setEnabled(enable);
}
void Com_Audio::updateLocalMicrophones() {
	ui.lst_audio_localMicrophones->clear();
}
void Com_Audio::updateLocalSpeakers() {
	ui.lst_audio_localSpeakers->clear();
}
void Com_Audio::updateRemotePublishedMicrophones() {

}
void Com_Audio::fillCodecs() {
	ui.cbo_audio_codecs->addItem(Utf8Str("isac"), Utf8Str("isac"));
	ui.cbo_audio_codecs->addItem(Utf8Str("opus"), Utf8Str("opus"));
	ui.cbo_audio_codecs->addItem(Utf8Str("aac "), Utf8Str("aac"));
}
QString Com_Audio::getCurrentCodec() {
	QString scodec = ui.cbo_audio_codecs->currentData().toString();
	return scodec;
}
rtc::DeviceId Com_Audio::getSelectedDeviceId(QListWidget* listw)  {
	QList<QListWidgetItem*> lst = listw->selectedItems();
	if (lst.empty()) {
		return rtc::DeviceId("");
	}
	QListWidgetItem* selItem = lst.at(0);
	QString selId = selItem->data(Qt::UserRole).toString();
	return rtc::DeviceId(selId.toUtf8().data());
}
void Com_Audio::localMicrophones_itemChanged() {
}
void Com_Audio::localSpeakers_itemChanged() {
	DeviceId selId = getSelectedDeviceId(ui.lst_audio_localSpeakers);
	if (!selId.empty()) {
		api_setPlayoutSpeaker(selId);
	}
}
void Com_Audio::audio_aec_stateChanged(int checked) {
	bool aec_enable = ui.ckb_audio_aec->isChecked();
	api_engineSetOption(eo_audio_aec_Enable, &aec_enable);
}
void Com_Audio::audio_dae_stateChanged(int checked) {
	bool dea_enable = ui.ckb_audio_dae->isChecked();
	api_engineSetOption(eo_audio_aec_DAEcho_Enable, &dea_enable);
}
void Com_Audio::audio_agc_stateChanged(int checked) {
	bool agc_enable = ui.ckb_audio_agc->isChecked();
	api_engineSetOption(eo_audio_autoGainControl_Enable, &agc_enable);
}
void Com_Audio::audio_hpf_stateChanged(int checked) {
	bool hpf_enable = ui.ckb_audio_hpf->isChecked();
	api_engineSetOption(eo_audio_highpassFilter_Enable, &hpf_enable);
}
void Com_Audio::audio_ns_stateChanged(int checked) {
	bool ns_enable = ui.ckb_audio_ns->isChecked();
	api_engineSetOption(eo_audio_noiseSuppression_Enable, &ns_enable);
}
void Com_Audio::onAttach() {
	resetControls(true);
	updateLocalMicrophones();
	updateLocalSpeakers();
	updateRemotePublishedMicrophones();
}
void Com_Audio::onDetach() {
	resetControls(false);
	updateLocalMicrophones();
	updateLocalSpeakers();
	updateRemotePublishedMicrophones();
}

///
#define qDebug_Mod qDebug() << Utf8Str("---- Audio ")

bool Com_Audio::on_opencloseMicrophone(bool pub) {
	if (!isAttach()) {
		return false;
	}
	Result ret = Err_Not_Found;
	if (pub) {
		DeviceId selId = getSelectedDeviceId(ui.lst_audio_localMicrophones);
		if (!selId.empty()) {
			api_setRecordingMicrophone(selId);
		}
		QString selcodec = getCurrentCodec();
		if (!selcodec.isEmpty()) {
			rtc::String scodec = selcodec.toUtf8().data();
			api_roomSetOption(ro_audio_option_codec, scodec);
		}
		bool aec_enable = ui.ckb_audio_aec->isChecked();
		api_engineSetOption(eo_audio_aec_Enable, &aec_enable);

		bool ns_enable = ui.ckb_audio_ns->isChecked();
		api_engineSetOption(eo_audio_noiseSuppression_Enable, &ns_enable);

		bool agc_enable = ui.ckb_audio_agc->isChecked();
		api_engineSetOption(eo_audio_autoGainControl_Enable, &agc_enable);

		bool hpf_enable = ui.ckb_audio_hpf->isChecked();
		api_engineSetOption(eo_audio_highpassFilter_Enable, &hpf_enable);

		ret = api_openMicrophone(pub);
		qDebug_Mod << Utf8Str(" 发布音频 ") << OutputWithRet(ret);
	}
	else {
		ret = api_openMicrophone(pub);
		qDebug_Mod << Utf8Str(" 取消发布音频 ") << OutputWithRet(ret);
	}
	if (RT_SUCCEEDED(ret)) {
		ButtonChecked(ui.btn_audio_openMicrophone_un, pub, (pub ? Utf8Str("取消发布") : Utf8Str("发布")));
	}
	return ret;
}
bool Com_Audio::on_muteMicrophone(bool mute) {
	if (!isAttach()) {
		return false;
	}
	if (mute) {
		qDebug_Mod << Utf8Str(" 闭音麦克风 ");
	}
	else {
		qDebug_Mod << Utf8Str(" 取消闭音麦克风 ");
	}
    api_muteMicrophone(mute);
	ButtonChecked(ui.btn_audio_muteLocalMicrophone_un, mute, (mute ? Utf8Str("出流") : Utf8Str("暂停")));
	return true;
}
bool Com_Audio::on_muteSpeaker(bool mute) {
	if (!isAttach()) {
		return false;
	}
	if (mute) {
		qDebug_Mod << Utf8Str(" 静音扬声器 ");
	}
	else {
		qDebug_Mod << Utf8Str(" 取消静音扬声器 ");
	}
	api_muteSpeaker(mute);
	ButtonChecked(ui.btn_audio_muteLocalSpeaker_un, mute, (mute ? Utf8Str("播放") : Utf8Str("暂停")));
	return true;
}
void Com_Audio::on_applyPlayoutGain(bool) {
	float playoutGain = 1.0f;
	playoutGain = ui.dpb_audio_playoutGain->value();
	api_applyPlayoutGain(playoutGain);
}
bool Com_Audio::on_monitorAudioLevel(bool enable) {
	api_monitorAudioLevel(enable);
	return true;
}

///
void Com_Audio::onMicrophoneStatusNotify(rtc::MicrophoneStatus status, const rtc::UserId& fromUserId) {
	qDebug_Mod << Utf8Str(" 麦克风状态：") << status;
}
void Com_Audio::onAudioLevelMonitorNotify(const rtc::AudioInfo& info) {
	qDebug_Mod << Utf8Str(" 语音能量 in：") << info.input_level << Utf8Str(" out：") << info.output_level 
		<< Utf8Str(" acts：") << info.active_streams.size();
	const AudioInfo::RemoteUser2LevelType& streams = info.active_streams;
	for (int i = 0; i < streams.size(); ++i) {
		qDebug_Mod << Utf8Str(" user: ") << streams[i].first.c_str()
			<< Utf8Str(" - ") << streams[i].second;
	}
}
void Com_Audio::onOpenMicrophoneResult(Result result) {
	qDebug_Mod << Utf8Str(" 本地音频打开：") << OutputWithRet(result);
}
void Com_Audio::onCloseMicrophoneResult(Result result) {
	qDebug_Mod << Utf8Str(" 本地音频关闭：") << OutputWithRet(result);
}
