#include "com_video.h"
#include "log2ui.h"
#include <QtGui/QVector3D>
#include <X11/Xlib.h>
//s#define USED_VIDEOVIEW2

#ifdef USED_VIDEOVIEW2
    #include "videoview2.h"
#else
    #include "videoview1.h"
#endif

using namespace rtc;

///
Com_Video::Com_Video(QWidget *parent) : QWidget(parent) ,dlg_localvb_(this, this) {
	ui.setupUi(this);
#ifdef USED_VIDEOVIEW2
    localview_  = new CVideoView2(ui.lst_video_localview,0);
    remoteview_ = new CVideoView2(ui.lst_video_remoteview,1);
#else
    localview_  = new CVideoView1(ui.lst_video_localview);
    remoteview_ = new CVideoView1(ui.lst_video_remoteview);
#endif
	localview_->updateViewSize(ui.lst_video_localview->width(), ui.lst_video_localview->height());
	remoteview_->updateViewSize(ui.lst_video_remoteview->width(), ui.lst_video_remoteview->height());

    localview_->setScalingType(IVideoRenderView::Scale_Aspect_Fit);
    remoteview_->setScalingType(IVideoRenderView::Scale_Aspect_Fit);

	resetControls(false);
	connect(ui.btn_video_previewLocal_un, SIGNAL(toggled(bool)), this, SLOT(on_previewCamera(bool)));
	connect(ui.btn_video_publishLocal_un, SIGNAL(toggled(bool)), this, SLOT(on_publishCamera(bool)));
	connect(ui.btn_video_muteLocal_un, SIGNAL(toggled(bool)), this, SLOT(on_muteCamera(bool)));
    //connect(ui.btn_video_setBitrate, SIGNAL(clicked()), this, SLOT(on_setBitrate()));
    //connect(ui.btn_video_showBitrates, SIGNAL(clicked()), this, SLOT(on_showLocalBitrates()));
    //connect(ui.btn_video_changeCapbility, SIGNAL(clicked()), this, SLOT(on_changeCapbility()));
	QValidator* validator = new QIntValidator(10, 800, this);
    //ui.edt_video_bitrate->setValidator(validator);
    //ui.edt_video_bitrate->setText(Utf8Str("50"));
	//
	connect(ui.btn_video_subscribeRemote_un, SIGNAL(toggled(bool)), this, SLOT(on_subscribeRemote(bool)));
	connect(ui.btn_video_attachRemote_un, SIGNAL(toggled(bool)), this, SLOT(on_attachRemote(bool)));
    fillCodecs();
    connect(ui.lst_video_localCameras, SIGNAL(itemSelectionChanged()), this, SLOT(on_localCameras_itemChanged()));
}
Com_Video::~Com_Video() {
}
void Com_Video::resetControls(bool enable) {
	ButtonChecked(ui.btn_video_previewLocal_un, false, Utf8Str("预览"));
	ButtonChecked(ui.btn_video_publishLocal_un, false, Utf8Str("发布"));
	ButtonChecked(ui.btn_video_muteLocal_un, false, Utf8Str("暂停"));
	ButtonChecked(ui.btn_video_subscribeRemote_un, false, Utf8Str("订阅"));
	ButtonChecked(ui.btn_video_attachRemote_un, false, Utf8Str("渲染"));
	ui.btn_video_previewLocal_un->setEnabled(enable);
	ui.btn_video_publishLocal_un->setEnabled(enable);
	ui.btn_video_muteLocal_un->setEnabled(enable);
	ui.btn_video_subscribeRemote_un->setEnabled(enable);
	ui.btn_video_attachRemote_un->setEnabled(enable);
    //ui.btn_video_setBitrate->setEnabled(enable);
	ui.cbo_video_resolutions->clear();
	ui.cbo_video_resolutions->setEnabled(enable);
	ui.cbo_video_codecs->setEnabled(enable);
    //ui.btn_video_showBitrates->setEnabled(enable);
}
void Com_Video::fillCodecs() {
	ui.cbo_video_codecs->addItem(Utf8Str("H264"), codec_h264);
	ui.cbo_video_codecs->addItem(Utf8Str("VP8"), codec_vp8);
	ui.cbo_video_codecs->addItem(Utf8Str("H265"), codec_h265);
}
void Com_Video::fillResolutions() {
	ui.cbo_video_resolutions->clear();
}
void Com_Video::on_localCameras_itemChanged() {
	fillResolutions();
	int currow = ui.lst_video_localCameras->currentRow();
	api_switchIndexvideo(currow);
}

void Com_Video::onAttach() {
	resetControls(true);
	updateLocalCameras();
	updateRemotePublishedCameras();
}
void Com_Video::onDetach() {
	resetControls(false);
	updateLocalCameras();
	updateRemotePublishedCameras();
	dlg_localvb_.stop();
}
void Com_Video::updateLocalCameras() {
	ui.lst_video_localCameras->clear();
}
void Com_Video::updateRemotePublishedCameras() {
	ui.lst_video_remotePublishedCameras->clear();
}

rtc::DeviceId Com_Video::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());
}
rtc::Camera Com_Video::getSelectedCameraParams()  {
	Camera selcam;
	rtc::DeviceId selId = getSelectedDeviceId(ui.lst_video_localCameras);
    qDebug() << "selfId = " <<selId.c_str();
	if (selId.empty()) {
		return selcam;
	}
	selcam = api_getCamera(selId);
#if USED_CPP_API
    selcam.publishedQualities.setStreamOptions(stream_main, getCurrentCapability(), getCurrentCodec());
#endif
	return selcam;
}
///
#define qDebug_Mod qDebug() << Utf8Str("---- Video ")

bool Com_Video::on_previewCamera(bool preview) {
	if (!isAttach()) {
		return false;
	}
	Result ret = Err_Not_Found;
	if (preview) {
		rtc::Camera selcam = getSelectedCameraParams();
		if (!selcam.isValid()) {
			return false;
		}
		ret = api_previewLocalCamera(selcam.id);
		curLocalId_ = selcam.id;
		qDebug_Mod << Utf8Str(" 预览视频 ") << OutputWithRet(ret);
	}
	else {
		curLocalId_ = "";
		ret = api_unpreviewLocalCamera();
		qDebug_Mod << Utf8Str(" 取消预览视频 ") << OutputWithRet(ret);
	}
	if (RT_SUCCEEDED(ret)) {
		ButtonChecked(ui.btn_video_previewLocal_un, preview, (preview ? Utf8Str("取消预览") : Utf8Str("预览")));
	}
	return ret;
}
rtc::VideoCodec Com_Video::getCurrentCodec() {
	int ncodec = ui.cbo_video_codecs->currentData().toInt();
	return (VideoCodec)ncodec;
}
rtc::CameraCapability Com_Video::getCurrentCapability() {
	QVector3D qtdata = ui.cbo_video_resolutions->currentData().value<QVector3D>();
	rtc::CameraCapability cap(qtdata.x(), qtdata.y(), qtdata.z());
	return cap;
}
bool Com_Video::on_publishCamera(bool pub) {
	if (!isAttach()) {
		return false;
	}
	Result ret = Err_Not_Found;
	if (pub) {
		rtc::Camera selcam = getSelectedCameraParams();
		if (!selcam.isValid()) {
			return false;
		}
		ret = api_publishLocalCamera(selcam);
		curLocalId_ = selcam.id;
		qDebug_Mod << Utf8Str(" 发布视频 ") << OutputWithRet(ret);
	}
	else {
		curLocalId_ = "";
		ret = api_unpublishLocalCamera();
		qDebug_Mod << Utf8Str(" 取消发布视频 ") << OutputWithRet(ret);
	}
	if (RT_SUCCEEDED(ret)) {
		ButtonChecked(ui.btn_video_publishLocal_un, pub, (pub ? Utf8Str("取消发布") : Utf8Str("发布")));
		if (pub) {
			dlg_localvb_.start();
		}
		else {
			dlg_localvb_.stop();
		}
	}
	return ret;
}
bool Com_Video::on_muteCamera(bool mute) {
	if (!isAttach()) {
		return false;
	}
	if (curLocalId_.empty()) {
		return false;
	}
	if (mute) {
		qDebug_Mod << Utf8Str(" 暂停本地视频 ");
		api_muteLocalCamera(curLocalId_);
	}
	else {
		qDebug_Mod << Utf8Str(" 取消暂停本地视频 ");
		api_unmuteLocalCamera(curLocalId_);
	}
	ButtonChecked(ui.btn_video_muteLocal_un, mute, (mute ? Utf8Str("出流") : Utf8Str("暂停")));
	return true;
}
void Com_Video::on_setBitrate() {
	if (curLocalId_.empty()) {
		return ;
	}
    int bitRate = 0;//ui.edt_video_bitrate->text().toInt();
	dlg_localvb_.setTargetBitrate(bitRate);
	bitRate = bitRate * 8 * 1000;
	{
        int min_b = ui.lineEdit_4->text().toInt();
        int max_b = ui.lineEdit_5->text().toInt();
        if(min_b != 0 && max_b != 0 && max_b > min_b){
            qDebug_Mod << Utf8Str(" 设置本地视频码率：") << min_b << " ,"<<max_b<<"kbps";
            api_setVideoBitrate(curLocalId_, min_b*1000, max_b*1000);
        }
        else{
            qDebug_Mod << Utf8Str(" 设置本地视频码率：") << bitRate << " KBps";
            api_setVideoBitrate(curLocalId_, bitRate, bitRate);
        }



	}
}
void Com_Video::on_changeCapbility() {
	if (curLocalId_.empty()) {
		return;
	}
	int bitmin = 0, bitmax = 0;
	CameraCapability cap;
	if (smallCapbility_) {
		bitmin = 50 * 1000;
		bitmax = 60 * 1000;
		cap = CameraCapability(160, 120, 10);
	}
	else {
		bitmin = 500 * 1000;
		bitmax = 800 * 1000;
		cap = getCurrentCapability();
	}
	smallCapbility_ = !smallCapbility_;
	api_setVideoBitrate(curLocalId_, bitmin, bitmax);
	api_changeCapability(curLocalId_, cap);
	qDebug_Mod << Utf8Str(" 更改分辨率：") << cap.width << "x" << cap.height;
}
void Com_Video::on_showLocalBitrates() {
	if (dlg_localvb_.isVisible()) {
		dlg_localvb_.hide();
	}
	else {
		dlg_localvb_.show();
	}
}
bool Com_Video::on_subscribeRemote(bool sub) {
	if (!isAttach()) {
		return false;
	}
	Result ret = Err_Not_Found;
	if (sub) {
		rtc::DeviceId selId = getSelectedDeviceId(ui.lst_video_remotePublishedCameras);
		if (selId.empty()) {
			return false;
		}
		ret = api_subscribe(selId);
		curRemoteId_ = selId;
		qDebug_Mod << Utf8Str(" 订阅视频 ") << OutputWithRet(ret);
	}
	else {
		ret = api_unsubscribe(curRemoteId_);
		curRemoteId_ = "";
		qDebug_Mod << Utf8Str(" 取消订阅视频 ") << OutputWithRet(ret);
	}
	if (RT_SUCCEEDED(ret)) {
		ButtonChecked(ui.btn_video_subscribeRemote_un, sub, (sub ? Utf8Str("取消订阅") : Utf8Str("订阅")));
	}
	return ret;
}
bool Com_Video::on_attachRemote(bool attach) {
	if (!isAttach()) {
		return false;
	}
	Result ret = Err_Not_Found;
	if (attach) {
		ret = api_attachRender(curRemoteId_, remoteview_);
		qDebug_Mod << Utf8Str(" 渲染视频 ") << OutputWithRet(ret);
	}
	else {
		ret = api_detachRender(curRemoteId_);
		qDebug_Mod << Utf8Str(" 取消渲染视频 ") << OutputWithRet(ret);
	}	
	if (RT_SUCCEEDED(ret)) {
		ButtonChecked(ui.btn_video_attachRemote_un, attach, (attach ? Utf8Str("取消渲染") : Utf8Str("渲染")));
	}
	return ret;
}
///
void Com_Video::onCameraStatusNotify(rtc::CameraStatus status, const rtc::DeviceId& fromId) {
	qDebug_Mod << Utf8Str(" 摄像头状态：") << status;
}
void Com_Video::onCameraDataNotify(int level, const rtc::String& description, const rtc::DeviceId& fromId) {
	qDebug_Mod << Utf8Str(" 摄像头数据更新：") << fromId.c_str();
}
void Com_Video::onPublishCameraNotify(const rtc::Camera& camera) {
	qDebug_Mod << Utf8Str(" 摄像头发布：") << camera.id.c_str();
	if (api_isSelfDevice(camera.id)) {
		return;
	}
	QListWidgetItem* item = new QListWidgetItem;
	item->setData(Qt::DisplayRole, camera.name.c_str());
	item->setData(Qt::UserRole, camera.id.c_str());
	ui.lst_video_remotePublishedCameras->addItem(item);
}
void Com_Video::onUnpublishCameraNotify(const rtc::Camera& camera) {
	qDebug_Mod << Utf8Str(" 摄像头取消发布：") << camera.id.c_str();
	if (api_isSelfDevice(camera.id)) {
		return;
	}
	getRemoteCameraRowByDeviceId(camera.id, true);
	if (curRemoteId_ == camera.id) {
		on_attachRemote(false);
		on_subscribeRemote(false);
		curRemoteId_.clear();
	}
}
int Com_Video::getRemoteCameraRowByDeviceId(const rtc::DeviceId& deviceId, bool remove) {
	int  idx = 0;
	bool find = false;
	for (; idx < ui.lst_video_remotePublishedCameras->count(); ++idx) {
		QString curId = ui.lst_video_remotePublishedCameras->item(idx)->data(Qt::UserRole).toString();
		if (curId == deviceId.c_str()) {
			if (remove) {
				ui.lst_video_remotePublishedCameras->takeItem(idx);
			}
			find = true;
			break;
		}
	}

	
	return (find) ? idx : -1;
}
void Com_Video::onSubscribeResult(Result result, const rtc::DeviceId& fromId) {
	qDebug_Mod << Utf8Str(" 远端摄像头订阅：") << OutputWithRet(result);
	api_attachRender(fromId, remoteview_);
}
void Com_Video::onUnsubscribeResult(Result result, const rtc::DeviceId& fromId) {
	qDebug_Mod << Utf8Str(" 远端摄像头取消订阅：") << OutputWithRet(result);
	api_detachRender_1(remoteview_);
}
void Com_Video::onPublishLocalResult(Result result, const rtc::DeviceId& fromId) {
	qDebug_Mod << Utf8Str(" 本地摄像头打开：") << OutputWithRet(result);
	if (RT_SUCCEEDED(result)) {
		api_attachRender(fromId, localview_);
        on_setBitrate();

	}
}
void Com_Video::onUnpublishLocalResult(Result result, const rtc::DeviceId& fromId) {
	qDebug_Mod << Utf8Str(" 本地摄像头关闭：") << OutputWithRet(result);
	if (RT_SUCCEEDED(result))
		api_detachRender_1(localview_);
}
void Com_Video::onCameraCapabilityNotify(const rtc::DeviceId& fromId, const uint32 width, const uint32 height, const uint32 fps) {
    qDebug_Mod << Utf8Str(" onCameraCapabilityNotify") ;
}
//

