#include "SyncObject.h"
#include <QSemaphore>
//#include <windows.h>
//include <mmsystem.h>
#include <QDebug>
QList<CameraThread *> SyncObject::getCameraList() const
{
    return cameraList;
}

QList<ProcessorThread *> SyncObject::getProcessorList() const
{
    return processorList;
}

void SyncObject::startAcquisition(int T)
{
    if(isRunning)
        return;
    isRunning = true;
	first_run = true;

	emit cStart();
	syncSem->acquire(cameraList.size());

	emit pStart();
	syncSem->acquire(processorList.size());

	connect ( syncTimer, SIGNAL( timeout() ), this, SLOT( sync() ) );
	emit startTimer(T);
	emit operationDone();
}
void SyncObject::stopAcquisition()
{

    if(!isRunning)
		return;
	disconnect ( syncTimer, SIGNAL( timeout() ), this, SLOT( sync() ) );
	emit stopTimer();

	emit cStop();
	syncSem->acquire(cameraList.size());

	emit pStop();
	syncSem->acquire(processorList.size());

	isRunning=false;
     first_run = true;
	emit operationDone();
}
void SyncObject::connectCamera(CameraThread * ct)
{
	connect ( this, SIGNAL( cStart() ), ct->cameraObject, SLOT( cStart() ), Qt::QueuedConnection );
	connect ( this, SIGNAL( cSync() ), ct->cameraObject, SLOT( cSync() ), Qt::QueuedConnection );
	connect ( this, SIGNAL( cGrab() ), ct->cameraObject, SLOT( cGrab() ), Qt::QueuedConnection );
	connect ( this, SIGNAL( cStop() ), ct->cameraObject, SLOT( cStop() ), Qt::QueuedConnection );
	cameraList.push_back(ct);
	//qDebug()<<"camera connected";
	//emit cameraConnected(cameraList.size());
	emit operationDone();
}
void SyncObject::disconnectCamera(CameraThread * ct)
{
	for(int i=0; i<cameraList.size(); ++i)
	{
		if(cameraList[i]==ct)
		{
			cameraList.erase(cameraList.begin()+i);
			disconnect ( this, SIGNAL( cStart() ), ct->cameraObject, SLOT( cStart() ));
			disconnect ( this, SIGNAL( cSync() ), ct->cameraObject, SLOT( cSync() ));
			disconnect ( this, SIGNAL( cGrab() ), ct->cameraObject, SLOT( cGrab() ));
			disconnect ( this, SIGNAL( cStop() ), ct->cameraObject, SLOT( cStop() ));
			delete ct;
			emit operationDone();
			return;
		}
	}
}

void SyncObject::connectProcessor(ProcessorThread * pt)
{
	connect ( this, SIGNAL( pStart() ), pt->processorObject, SLOT( pStart() ), Qt::QueuedConnection );
	connect ( this, SIGNAL( pProcess(int,int) ), pt->processorObject, SLOT( pProcess(int,int) ), Qt::QueuedConnection );
	connect ( this, SIGNAL( pStop() ), pt->processorObject, SLOT( pStop() ), Qt::QueuedConnection );
	processorList.push_back(pt);
	//emit processorConnected(processorList.size());
	emit operationDone();
}

void SyncObject::disconnectProcessor(ProcessorThread * pt)
{
	for(int i=0; i<processorList.size(); ++i)
	{
		if(processorList[i]==pt)
		{
			processorList.erase(processorList.begin()+i);
			disconnect ( this, SIGNAL( pStart() ), pt->processorObject, SLOT( pStart() ));
			disconnect ( this, SIGNAL( pProcess(int,int) ), pt->processorObject, SLOT( pProcess(int,int) ));
			disconnect ( this, SIGNAL( pStop() ), pt->processorObject, SLOT( pStop() ));
			delete pt;
			emit operationDone();
			return;
		}
	}
}

void SyncObject::sync()
{
	syncTimer->blockSignals(true);

    int64 t1_new=QDateTime::currentMSecsSinceEpoch();
	emit cSync();
	syncSem->acquire(cameraList.size());
    int64 t2_new=QDateTime::currentMSecsSinceEpoch();

	fps = fps*0.9 + 0.1*1000.0/((float)(t1_new-t1));
	displayFPS(fps);

	if(!first_run)
	{
		emit pProcess(t1,t2);
		syncSem->acquire(processorList.size());
	}
	else
	{
		first_run = false;
	}
	t1=t1_new;
	t2=t2_new;

	emit cGrab();
	syncSem->acquire(cameraList.size());

		//emit pProcess(t1_new,t2_new);
		//syncSem->acquire(processorList.size());

	syncTimer->blockSignals(false);

}
