/*******************************************************************************
*                                                                              *
* Société de Transports de Montréal.                                    	   *
* 2012 - 2013                                                                        *
*                                                                              *
* Projet Zones Tests                                                           *
*                                                                              *
*                                                                              *
*                                                                              *
*******************************************************************************/
/*
	Description:
	Description du fichier si nécessaire.

*/

/* ************************************************************************** */
/* Revision:
### YYYMMDD JFM
	Verision d'origine.

### YYYYMMDD Description du besoin ou du bug
	Description du changement.
 */

/* ************************************************************************** */

#include "InputModule.h"
#include "OutputModule.h"
#include "AnalogInputModule.h"
#include "QMutex"
#include <QElapsedTimer>
#ifndef EXTIOTHREAD_H
#define EXTIOTHREAD_H

#include <QObject>


enum eOutputsModuleTransactionType
{
	OUTPUT_MODULE_SET_OUTPUT_BUF,
	OUTPUT_MODULE_SET_OUTPUT_WORD,
	OUTPUT_MODULE_SET_OUTPUT_FLAGS,
	OUTPUT_MODULE_CLEAR_OUTPUT_FLAGS,
	OUTPUT_MODULE_TOGGLE_OUTPUT_FLAGS,
	OUTPUT_MODULE_MAX_TRANSACTION_TYPE

};

class COutputTransaction
{
public:
    quint32 mOutputsWord;
    unsigned char mOutputsBuf[4];
    int mOutputTransaction;

    COutputTransaction& operator=(const COutputTransaction& a);
};

class CExtIOThread : public QObject, public CAnalogInputModule, public CInputModule, public COutputModule
{
	Q_OBJECT
public:
	explicit CExtIOThread();

	unsigned int BindPointers(CInputModule *InputModule, COutputModule *OutputModule, CAnalogInputModule *AnalogInputModule, int AnalogChannel);
	bool IsThreadRunning();


	unsigned int StopAcquisition();
	bool IsAnalogModueDetected();

	//Input module interface
	virtual unsigned int GetInputs();
	virtual unsigned int GetInputBuf();

	//Output module interface
	virtual unsigned int SetOutput(unsigned char* buffer);
	virtual unsigned int SetOutput(quint32 buffer);
	virtual unsigned int SetOutputFlags(quint32 Flags);
	virtual unsigned int ClearOutputFlags(quint32 Flags);
	virtual unsigned int ToggleOutputFlags(quint32 Flags);


	//Mixed module interface
    virtual unsigned int GetAnalogInput(int Channel, int *data);
	virtual unsigned int GetAnalogInput(int Channel,double &data);

#ifdef OUTPUT_EXTIO_SAMPLE_RATE
	QElapsedTimer mSampleRateTimer;
	qint64 GetSampleRate();
	qint64 mDelay;
#endif

private:
	CInputModule *mInputModule;
	COutputModule *mOutputModule;
	CAnalogInputModule *mAnalogInputModule;

	QElapsedTimer mDigitalInputsPeriodTimer,mAnalogInputsTimer;

	QMutex mMutex;

	unsigned int mCurInputs;
	int mCurAnalogInput;
	int mCurAnalogChannel;

	quint32 mCurOutputsWord;
//	quint32 mRequestedOutputWord;
	unsigned char mCurOutputsBuf[4];
	int mCurOutputTransaction;
	bool mOutputDirty;
	bool mAnalogModulePresent;

	bool mRun;
	bool mIsRunning;

    QList<COutputTransaction> mOutputTransactionList;



signals:



public slots:
	void DoAcquisition();

};



#endif // EXTIOTHREAD_H
