 // nikonD3Test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"


extern "C" {
	LPMAIDEntryPointProc	g_pMAIDEntryPoint = NULL;
	UCHAR	g_bFileRemoved = false;
	ULONG	g_ulCameraType = 0;	// CameraType
	char sNextFileName[32] =	"";	
	char	sLastFileName[128] ="img";
	char	sNextDTOrig[128] = "2001:01:01 00:00:00";
	char	sNextDTOrigSS[128] = "000";
	int		ShowTags = 0;
}

#if defined( _WIN32 )
HINSTANCE	g_hInstModule = NULL;
#endif

FILE * fid;
triggerSerialPort * tspTrigger;
nikonHandler *		nhCamera;


void siginthandler(int param)
{
	printf("Program Terminating...\n");
	/*if (!tspTrigger->closeSerialPort()) 
	fprintf(stderr,"ERROR: Cannot close serial port. ERRNO %lu\n",GetLastError());
	*/
	exit(param);
}



void print_usage() {
	fprintf(stdout, "Usage: %s options\n", "nikonD3Test");
	fprintf(stdout, "  -h --help                  Display this usage information.\n");
	fprintf(stdout, "  -p --period [milliseconds] Image Acquisition rate.     \n");
	fprintf(stdout, "  -n --nacquisitions          Number of repeat acquisitions (0 for infinity)\n");
	fprintf(stdout, "  -d --device				  Serial device to trigger through (i.e. COM1) \n");

	exit(0);
}

int _tmain(int argc, _TCHAR* argv[])
{

	static int verbose_flag;

	int c;
	ULONG iPeriodMS=1000; //rep rate of image acquisition
	ULONG iNAcq=1;		//number of image acquisitions to be made
	TCHAR sDevice[] = "COM1";

	//PROCESS OPTIONS
	while (1)
	{        
		static struct option long_options[] =
		{
			{_T("verbose"), ARG_NONE, &verbose_flag, 1},
			{_T("brief"),   ARG_NONE, &verbose_flag, 0},
			{_T("help"),     ARG_NONE, 0, _T('h')},
			{_T("period"),     ARG_NONE, 0, _T('p')},
			{_T("nacquisitions"),  ARG_NONE,  0, _T('n')},
			{_T("device"),  ARG_NONE,  0, _T('d')},
			{ ARG_NULL , ARG_NULL , ARG_NULL , ARG_NULL }
		};

		int option_index = 0;
		c = getopt_long(argc, argv, _T("hp:n:d:"), long_options, &option_index);

		// Check for end of operation or error
		if (c == -1)
			break;

		// Handle options
		switch (c)
		{
		case 0:
			/* If this option set a flag, do nothing else now. */
			if (long_options[option_index].flag != 0)
				break;
			_tprintf (_T("option %s"), long_options[option_index].name);
			if (optarg)
				_tprintf (_T(" with arg %s"), optarg);
			_tprintf (_T("\n"));
			break;

		case _T('h'):
			print_usage();
			break;

		case _T('p'):
			_tprintf (_T("Setting period with value `%s'\n"), optarg);
			iPeriodMS = atoi(optarg);
			break;

		case _T('n'):
			_tprintf (_T("Setting number of acquistions to value `%s'\n"), optarg);
			iNAcq = atoi(optarg);
			break;

		case _T('d'):
			_tprintf (_T("Setting trigger serial device to `%s'\n"), optarg);
			_tcscpy_s(sDevice,optarg);
			break;

		case '?':
			/* getopt_long already printed an error message. */
			print_usage();
			break;

		default:
			abort();
		}
	}

	signal(SIGINT, siginthandler);


	//CONNECT TO CAMERA MODULE

	nhCamera = new nikonHandler();
	if (!nhCamera->isConnected()){
		fprintf(stderr,"main(): ERROR: Cannot Connect to Camera or Control Module.\n");
		siginthandler(-1);
	}


	//SET UP SERIAL PORT
	tspTrigger = new triggerSerialPort(sDevice);
	if (!tspTrigger->isConnected()) {
		fprintf(stderr,"nikonD3Test::main() ERROR Cannot open serial port %s\n",sDevice);
		siginthandler(-1);
	}

	//RUNNING LOOP
	int i = 0, j = 0;
	ULONG ulLoopCount = 0;
	//ULONG ulItemID = 0; 
	ULONG iSleepIntvl = 0;
	float  fLoopElapsed; // in milliseconds.

	bool bRet = false;
	bool bGotImageThisLoop;

	clock_t  t = clock();
	clock_t now;


	ULONG ctr = 0;
	//open file for writing
	//fid = fopen("out.log","w+");
	//fprintf(fid,"CAPTURE ASYNC SELECTITEM DOWNLOAD TOTAL\n");
	//sendTrigger(hSerial);
	//Sleep(100);

	while (ctr < iNAcq) {
		t = clock();
		now  = clock();
		bGotImageThisLoop = false;
		printf("RC: %04.1f ms | Call: %04.1f ms [START]\n",((float)(clock()-t))/CLOCKS_PER_SEC*1000,  ((float)(clock()-now))/CLOCKS_PER_SEC*1000);

		now  = clock();

		// Send the Trigger Via Serial
		tspTrigger->sendTrigger();

		i = 0;

		// Start Loop to test time elapsed and 
		do {


			bRet = nhCamera->itemSelect();
			if( nhCamera->itemSelected() ) {
				printf("\nRC: %04.1f ms | Call: %04.1f ms [SELECTITEM]\n",((float)(clock()-t))/CLOCKS_PER_SEC*1000,  ((float)(clock()-now))/CLOCKS_PER_SEC*1000);
				now  = clock();
				bRet = nhCamera->itemDownloadDefault();
				printf("RC: %04.1f ms | Call: %04.1f ms [DOWNLOAD]\n",((float)(clock()-t))/CLOCKS_PER_SEC*1000,  ((float)(clock()-now))/CLOCKS_PER_SEC*1000);
				if (bGotImageThisLoop) {
					fprintf(stderr,"main() ERROR: Multiple images collected during one sampling period.\n");
				}
				bGotImageThisLoop = true;
				now  = clock();
			}
			else if( bRet == true) { // No item but we're at least hearing from the camera.

			}
			else {
				fprintf(stderr,"main() ERROR: Cannot communicate with camera for item select.\n");
			}

			fLoopElapsed = ((float)(clock()-t))/CLOCKS_PER_SEC*1000;

			if (fLoopElapsed >= iPeriodMS && !bGotImageThisLoop) {
				fprintf(stderr,"main() ERROR: No image present in loop as requested.\n");
			}
			fprintf(stdout,"\rIN LOOP: %10.0f of %i",fLoopElapsed, iPeriodMS);
			fflush(stdout);
			Sleep(iSleepIntvl);
			now = clock();	

		} while (fLoopElapsed < iPeriodMS);



		printf("\nRC: %04.1f ms | Call: %04.1f ms [WAIT/FINISH]\n",((float)(clock()-t))/CLOCKS_PER_SEC*1000,  ((float)(clock()-now))/CLOCKS_PER_SEC*1000);
		fflush(stdout);
		fflush(stderr);
		//fprintf(fid,"%04.1f\n",((float)(clock()-t))/CLOCKS_PER_SEC*1000);
		ctr++;
	}


	//CLOSE CONNECTIONS
	siginthandler(0);

	return 0;
}

