// The following ifdef block is the standard way of creating macros which make exporting 
// from a DLL simpler. All files within this DLL are compiled with the CAMERADLL_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see 
// CAMERADLL_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef CAMERADLL_EXPORTS
#define CAMERADLL_API extern "C" __declspec(dllexport)
#else
#define CAMERADLL_API extern "C" __declspec(dllimport)
#endif

#include <string>
#include <vector>
#include <deque>
#include <cstdarg>
#include <Firei.h>

using namespace std;

#define MAX_CAMERA_NUMBER 10
#define CAMERA_BUFFER     50 //!!!//150

typedef struct
{
	HANDLE						hMutex;
    FIREi_CAMERA_HANDLE         hCamera;
    FIREi_CAMERA_STARTUP_INFO   StartupInfo;
	FIREi_ISOCH_ENGINE_HANDLE	hIsochEngine;
    string						strFileName;
	int							nCameraNumber;
	int							nCameraIdentifier;
	BOOL						bRun;
	deque<BYTE*>				vecFrames;
	ULONG						nFirstFrameInVector;
	BYTE*						pFirstFrame;
	BYTE*						pLastFrame;
	UINT						nFrameWidth;
	UINT						nFrameHeight;
	ULONG						nFrameSize;
}
CAMERA_STRUCT, *PCAMERA_STRUCT;


PCAMERA_STRUCT			pCameraArray[MAX_CAMERA_NUMBER];
FIREi_CAMERA_GUID		CameraGuidArray[MAX_CAMERA_NUMBER];
FIREi_STATUS			FireiStatus;
ULONG					nCamerasCount;
ULONG					nCamerasFound;

//--------------------------------------------------------------------

int GetCameraIndex(int camera);

CAMERADLL_API void Init();
CAMERADLL_API BOOL AddCamera(const char *fileName, int camera);
CAMERADLL_API void StartCamera(int camera);
CAMERADLL_API void StartAll();
CAMERADLL_API void StopCamera(int camera);
CAMERADLL_API void StopAll();
CAMERADLL_API void Terminate();

CAMERADLL_API ULONG GetCamerasFound() { return nCamerasFound; }
CAMERADLL_API ULONG GetCamerasCount() { return nCamerasCount; }

CAMERADLL_API ULONG GetFrameSize(int camera);
CAMERADLL_API ULONG GetLastFrameIndex(int camera);

CAMERADLL_API UINT GetFrameWidth(int camera);
CAMERADLL_API UINT GetFrameHeight(int camera);

CAMERADLL_API void GetFirstFrame(int camera, BYTE* data, UINT *width, UINT *height);
CAMERADLL_API void GetLastFrame(int camera, BYTE* data, UINT *width, UINT *height);
CAMERADLL_API void GetFrame(int camera, ULONG frame, BYTE* data, UINT* width, UINT* height);

//--------------------------------------------------------------------

void CameraProcessFunction(void* param);

//--------------------------------------------------------------------

#ifdef _DEBUG
	#include <stdarg.h>

	FILE *dbgFile;
	static BOOL dbgFileOpened = FALSE;
#endif

void DEBUG_OPEN()
{
#ifdef _DEBUG
	if (dbgFileOpened == FALSE)
	{
		fopen_s(&dbgFile, "C:/CameraDll-debug.out", "w");
		dbgFileOpened = TRUE;
	}
#endif
}

void DEBUG(const char *str, ...)
{
#ifdef _DEBUG
	char fmt[256];
	if (dbgFile != NULL)
	{
		va_list paramList;
		va_start(paramList, str);

		sprintf_s(fmt, str, paramList);
		//fprintf(dbgFile, str, paramList);
		fprintf(dbgFile, fmt);
		fprintf(dbgFile, "\n");
		fflush(dbgFile);

		va_end(paramList);
	}
#endif
}

void DEBUG_CLOSE()
{
#ifdef _DEBUG
	if (dbgFile != NULL)
	{
		fclose(dbgFile);
	}
#endif
}
