#include "ccam_img.h"
#include "CCamDriver.h"
#include "udshl/Grabber.h"

#define  ALARM_CAMERA_COMMUNICATION 50240
CCam_IMG::CCam_IMG(const QString &name, int32_t id)
	:CMCam(name,id)
{
	m_pSink=new tFrameSnapSinkPtr;
	m_pGrabber=0;
}

CCam_IMG::~CCam_IMG()
{
}

int32_t CCam_IMG::init_channel()
{
	QString sSerialID=m_Variants.get_VData(Var_Base_SerialID_ID)->toString();
	m_pGrabber=new Grabber;

	/*typedef VideoFormatItem							tVideoFormatItem;
	typedef std::vector<tVideoFormatItem>			tVidFmtList;
	/// VideoFormatList
	typedef smart_ptr<tVidFmtList>					tVidFmtListPtr;*/
	//smart_ptr<std::vector<VideoFormatItem>> list = m_pGrabber->getAvailableVideoFormats();
	//bool setRet = m_pGrabber->setVideoFormat("Y800 (1280x1024)");
	//
	FrameTypeInfo typeInfo;
	(*m_pSink)=FrameSnapSink::create(FrameTypeInfo(eY800), 1);

	bool ok1 = (*m_pSink)->getOutputFrameType(typeInfo);
	int formatId = typeInfo.getColorformat();
	//    qDebug()<<m_strserialID;
	
	/*VideoCaptureDeviceItem item = devList->at(0);

	QString name1 = devList->at(0).getUniqueName().c_str();
	QString name2 = devList->at(1).getUniqueName().c_str();*/
	//Grabber::tVidCapDevListPtr devList = m_pGrabber->getAvailableVideoCaptureDevices();
	//int64_t serialId0 = devList->at(0).getSerialNumber();
	//int64_t serialId1 = devList->at(1).getSerialNumber();
	//int64_t serialId2 = devList->at(2).getSerialNumber();

	bool b= false;
	int64_t serialId = sSerialID.toInt();
	if(serialId< 10)
	{
		Grabber::tVidCapDevListPtr devList = m_pGrabber->getAvailableVideoCaptureDevices();
		if(devList->size()<3){
			MQT_THROW_STR(QObject::trUtf8("Need %1 Cam, Find %2 Cam ")
				.arg(3).arg(devList->size()));
			return RTN_FAILED1;
		}
		/*int iSize=mchannels.size();
		if(devList->size()!=iSize)
		{
			MQT_THROW_STR(QObject::trUtf8("Need %1 Cam, Find %2 Cam ")
				.arg(iSize).arg(iCameraCounts));
		}*/

		//int64_t serialId11 = devList->at(0).getSerialNumber();
		//int64_t serialId12 = devList->at(1).getSerialNumber();
		//if(devList != nullptr){
		//	qDebug() << "find devList" << endl;
		//}
		if(sSerialID == "0")
		b= m_pGrabber->openDev(devList->at(0));
		else if(sSerialID == "1")
		b= m_pGrabber->openDev(devList->at(1));
		else if(sSerialID == "2")
		b= m_pGrabber->openDev(devList->at(2));
		//    Grabber::tVidCapDevListPtr ptr=	m_pGrabber->getAvailableVideoCaptureDevices();
		//    VideoCaptureDeviceItem& item=ptr->at(0);
		//    qDebug()<<item.getUniqueName().c_str();
	}
	else{
		//68305024
		b = m_pGrabber->openDev(serialId);
	}
	if(!b)
	{
		MQT_THROW_STR(m_sName+QObject::trUtf8("open Cam Failed"));
	}

	smart_ptr<std::vector<VideoFormatItem>> list = m_pGrabber->getAvailableVideoFormats();
	//bool setRet = m_pGrabber->setVideoFormat("Y800 (3840x2160)");

	//bool setRet = m_pGrabber->setVideoFormat("Y800 (2560x1920)");
	m_pGrabber->setFPS(20);
	//Grabber::tVidFmtDescListPtr DecriptionList;
	//DecriptionList = m_pGrabber->getAvailableVideoFormatDescs();
	//for( Grabber::tVidFmtDescList::iterator pDescription = DecriptionList->begin(); pDescription != DecriptionList->end(); pDescription++ )
	//{
	//	qDebug() << (*pDescription)->toString().c_str() << endl;
	//	//printf("%s\n", (*pDescription)->toString().c_str());
	//}
	int iWidth = m_pGrabber->getAcqSizeMaxX();
	int iHeight = m_pGrabber->getAcqSizeMaxY();

	m_Variants.set_VData(Var_Cam_Width_ID,int(iWidth));
	m_Variants.set_VData(Var_Cam_Height_ID,int(iHeight));

	m_pRawImageData=new uint8_t[iWidth*iHeight];
	memset(m_pRawImageData,0,iHeight*iWidth);

	m_pGrabber->setSinkType(*m_pSink);

	// Prepare the live mode, to get the output size of the sink.
	if( !m_pGrabber->prepareLive( false ) )
	{
		MqDebug() << "Could not render the VideoFormat into a eY800 sink.";
		return -1;
	}
	bool ok = (*m_pSink)->getOutputFrameType(typeInfo);
	formatId = typeInfo.getColorformat();
	(*m_pSink)->getOutputFrameType(typeInfo);
	if(false == m_pGrabber->startLive( false ))
	{
		MqDebug() << "Start Camera failed";
		return -1;
	}

	//tFrameQueueBufferPtr frame;
	//Error e = (*m_pSink)->snapSingle(frame, 2000);
	//if(e.isError() )
	//{
	//	qDebug() << "Snap error.";
	//}

	return CCam::init_channel();
}

int32_t CCam_IMG::exit_channel()
{
	if(m_bInited)
	{
		m_pGrabber->stopLive();
		m_pGrabber->closeDev();
	}
	delete m_pGrabber;
	m_pGrabber=0;
	delete m_pSink;
	return CCam::exit_channel();
}

bool CCam_IMG::Reconnect()
{
	if(m_bInited)
	{
		m_pGrabber->stopLive();
		m_pGrabber->closeDev();

		//qDebug() << "Reconnect Camera ---" << m_iID << endl;;
		//LOG(ERROR) << "Reconnect Camera ---" << m_iID;
		QString sSerialID=m_Variants.get_VData(Var_Base_SerialID_ID)->toString();
		/*m_pGrabber=new Grabber;

		FrameTypeInfo typeInfo;
		(*m_pSink)=FrameSnapSink::create(FrameTypeInfo(eY800));

		bool ok1 = (*m_pSink)->getOutputFrameType(typeInfo);
		int formatId = typeInfo.getColorformat();*/
		bool b= false;
		int64_t serialId = sSerialID.toInt();
		b = m_pGrabber->openDev(serialId);
		if(!b)
		{
			//LOG(ERROR)<<m_pGrabber->getLastError().toString();
			MQT_THROW_CODESTR(ALARM_CAMERA_COMMUNICATION, (m_sName+QObject::trUtf8("open Cam Failed")));
			return false;
		}

		m_pGrabber->setSinkType(*m_pSink);

		// Prepare the live mode, to get the output size of the sink.
		if( !m_pGrabber->prepareLive( false ) )
		{
			//LOG(ERROR)<<m_pGrabber->getLastError().toString();
			MQT_THROW_CODESTR(ALARM_CAMERA_COMMUNICATION,(m_sName+QObject::trUtf8("Cam prepareLive Failed")));
			return false;
		}

		//m_pGrabber->setVideoFormat("Y800 (2560x1920)");
		//m_pGrabber->setVideoFormat("Y800 (3840x2160)");
		if(false == m_pGrabber->startLive( false ))
		{
			//qDebug() << "Start Camera failed";
			//LOG(ERROR)<<m_pGrabber->getLastError().toString();
			MQT_THROW_CODESTR(ALARM_CAMERA_COMMUNICATION,(m_sName+QObject::trUtf8("Start Camera live failed")));
			return false;
		}
	}

	return true;
}

