/* 
*	file: nikonD3Server.cpp 
*	author: Eric J Martin
*
*	copyright: MBARI 2013
*
*	Prototypes and global definitions for the main server
*	program reside here. Three structures are define to 
*	hold thread specific data items for the three main threads:
*		- main thread (initialization and tcp server)
*		- trigger thread (for uart issued camera hardware triggering
*			on a fixed interval)
*		- camera thread (for camera USB PTPP interactions, including
*			configuration and image download.
*
*/
#pragma once

#ifndef NIKOND3SERVER_H_
#define NIKOND3SERVER_H_

#include "stdafx.h"

#pragma comment(lib, "Ws2_32.lib")

using namespace std;

extern "C" { /* Variables used in the nikon sdk functions which are written in C */
	LPMAIDEntryPointProc	g_pMAIDEntryPoint = NULL;
	UCHAR	g_bFileRemoved = false;
	ULONG	g_ulCameraType = 0;	// CameraType
	char	sNextFileName[128] ="img";
	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
#define ACK_MESG_RECV "Message received successfully"
#define MAXTCPTHREADS 10
#define MAXMUTEXWAIT 2000 //Milliseconds

// Globals and types

FILE *							fid;
FILE *							LOGFDS = stdout;
triggerSerialPort *				tspTrigger;
triggerSerialPort *				tspLaser;
nikonHandler *					nhCamera;
nikonServerMessageQueue *		msgQ;
stringQueue *					stringQ;
bool							bInMainLoop;
bool							bLasersPowered;
bool							bCameraLogging;
bool							bCameraConnected;
bool							bDeadAlready =false;
char							sConfigFile[NIKON_MESSAGE_STRING_LENGTH];

HANDLE statusMutex, msgMutex, logMutex; 
SOCKET ListenSocket;
HANDLE  camThread,trigThread,tcpThreads[MAXTCPTHREADS];


struct t_nikonServerData { // Data associated with the camera interaction thread.

	bool			cameraPreTrigger; //TODO marked for removal
	char			cameraFilePrefix[128];
	//Running Variables
	unsigned long	ulImageCount;

} sNikonServerData;

struct t_triggerServerData { // Data associated with the Trigger Thread

	unsigned long	triggerInterval;
	char			triggerPortName[12];
	unsigned long	triggerBaudRate;
	unsigned short	triggerBits;
	char			triggerParity[1];
	unsigned short	triggerStop;

	char			laserPortName[12];
	unsigned long   laserBaudRate;
	unsigned short	laserBits;
	char			laserParity[1];
	unsigned short  laserStop;


	//Running Variables
	unsigned long   ulTriggerCount;

} sTriggerServerData;


struct t_tcpServerData { // Data associated with the tcp thread.
	//INI Settings
	unsigned long	serverPort;
	unsigned long	serverMaxUsers;
	char			logFileName[128];
} sTcpServerData;


struct Connection { // structure to store socket specific data for implementation of a multi-user server.
	SOCKET sd;
	char acBuffer[ulMaxNikonTotalPacketSize_c];
	int nCharsInBuffer;

	Connection(SOCKET sd_) : sd(sd_), nCharsInBuffer(0) { }
};
typedef std::vector<Connection> ConnectionList; // vector definition for connected tcp clients

ConnectionList gConnections;


// initialization functions
BOOL importIniSettings(_TCHAR * cFname);
void printIniSettings(void);

// tcp server functions
BOOL SocketInitialize();
void AcceptConnections(SOCKET ListenSocket);			// Main loop that performs select on listening sockets and client sockets
bool ReadSocketData(Connection& conn) ;					// read data from selected socket.
int WriteSocketData(Connection& conn);					// write data to supplied socket.
void SetupFDSets(fd_set& fdRead, fd_set& fdWrite, fd_set& fdExcept, SOCKET ListeningSocket);


//Thread Functions
DWORD WINAPI AcceptHandler(void* Socket);				// main thread for server / client interactions.
DWORD WINAPI TriggerWorkerThread(LPVOID lpParam);		// thread for hardware triggering and timing.
DWORD WINAPI NikonWorkerThread(LPVOID );				// thread for camera USB PTPP interactions
void processNikonMessage(char* msgbuff, unsigned long msglen); // process the binary network command.
void WriteFileToLog(bool bCloseRequested);				// Write the last known image's name to file with the time of writing.

//Utility Functions
void siginthandler(int param);							// handles the interrupt signal
void logprintf(FILE * fds, const char *format, ...);	// log to a file pointer and tack on the time.

//Mutex Functions
bool inMainLoop();										// test for whether the program is in regular execution
bool inMainLoop(bool);									// set value for main loop interaction. 
bool cameraLogging();									// test for whether acquisition is occuring
bool cameraLogging(bool);								// set value for acquisition status
bool lasersPowered();										// test for dig output (true = high)
bool lasersPowered(bool);									// set value for dig output (true = high)
bool cameraConnected();									// test for whether the camera is seen on any usb port
bool cameraConnected(bool);								// set value for camera connection status
bool getInterval(unsigned long &ulInterval);			// retrieve value for interval between frame triggers in milliseconds
bool setInterval(unsigned long ulInterval);				// set value for interval between frame triggers in milliseconds

#endif
