#pragma once
#ifndef    SERVER_H
#define    SERVER_H

//#define debug_msg
//#define simu

#include <windows.h>
#include <strsafe.h>
#include <stdio.h>
#include <math.h>
#include <winsock.h>

#pragma comment(lib,"ws2_32.lib")
#define BUF_SIZE 255
#define PORT_I2C_USB "COM5"
#define PORT_PIC "COM1"
#define PORT_GPS "COM2"

#define I2CD_CMD	0x53		// direct I2C control command
#define I2C_CMD		0x55		// registered I2C control command
#define USBI2C_CMD	0x5a		// Module command 

struct SensorData
	{
	int BatVoltage;
	int SpeedFront;
	int IR;
	int	IR2;
	};

struct WMutex 
{
	WMutex ();
	virtual ~WMutex ();

	virtual void acquire ();
	virtual int acquired ();
	virtual void release ();

private:
	void* wmutex;
};

class WifibotServer
{
public:

	WifibotServer(void);
	~WifibotServer(void);
	
	void runLab(void);	
	void runTrooper(void);
	void runSim(void);
	void runManualSim(void);
	void runManualLab(void);
	void runManualTrooper(void);
	
	HANDLE InitComTrooperRS232(void);
	HANDLE InitComTrooperGPS(void);
	HANDLE SetupI2CCommPort(LPCSTR comport);
	
	int GetFirmware(HANDLE hUSB);
	int GetI2cMotor(HANDLE hUSB, BYTE add,SensorData *data);
	int SetI2cMotor(HANDLE hUSB, BYTE add,BYTE speed);
	int GetADC(HANDLE hUSB,BYTE add);
	int StopMotor(HANDLE hUSB);
	
	void GetDataSimIn(char* L,char* R);
	void SetDataSimOut(int bat,int SpeedFrontR,int SpeedFrontL,int IRL,int IRR);

	void GetRobotSensor(SensorData* L,SensorData* R);
	void SetRobotSpeed(char speedL,char speedR,bool SideL,bool SideR,bool ctrl);

private:	

	enum cmds { nop=0, VERSION, NEW_ADDRESS, BATTERY,
				SCAN1, SCAN2, SCAN3, SCAN4, SCAN6, SCAN8, SCAN12, SCAN16,
				SETPINS=0x10, GETPINS, GETAD,
	};

	enum state { Done=0, Off, On };	

	HANDLE Handle_Of_Thread_TCP;
	HANDLE Handle_Of_Thread_TCP_trooper_In;
	HANDLE Handle_Of_Thread_TCP_trooper_Out;
	HANDLE Handle_Of_Thread_TCP_trooper_I2C;
	HANDLE Handle_Of_Thread_Trooper_RS232;
	HANDLE Handle_Of_Thread_Dog;
	HANDLE Handle_Of_Thread_GPS;
	HANDLE Handle_Of_Thread_SNR;

	
	static DWORD WINAPI Thread_TCP( LPVOID lpParam );
	static DWORD WINAPI Thread_TCP_Trooper_In( LPVOID lpParam );
	static DWORD WINAPI Thread_TCP_Trooper_Out( LPVOID lpParam );
	static DWORD WINAPI Thread_TCP_Trooper_I2C( LPVOID lpParam );
	static DWORD WINAPI Thread_Dog( LPVOID lpParam );
	static DWORD WINAPI Thread_Trooper_RS232( LPVOID lpParam );
	static DWORD WINAPI Thread_GPS( LPVOID lpParam );
	static DWORD WINAPI Thread_SNR( LPVOID lpParam );
			
	volatile bool Thread_TCP_Run;
	volatile bool Thread_TCP_Trooper_In_Run;
	volatile bool Thread_TCP_Trooper_Out_Run;
	volatile bool Thread_TCP_Trooper_I2C_Run;
	volatile bool Thread_Trooper_RS232_Run;
	volatile bool Thread_Dog_Run;
	volatile bool Thread_GPS_Run;
	volatile bool Thread_SNR_Run;

	void Thread_TCP(void);
	void Thread_TCP_Trooper_In(void);
	void Thread_TCP_Trooper_Out(void);
	void Thread_TCP_Trooper_I2C(void);
	void Thread_Trooper_RS232(void);
	void Thread_Dog(void);
	void Thread_GPS(void);
	void Thread_SNR(void);

	bool tcpon;
	SensorData dataL;
	SensorData dataR;

	SensorData userdataL;
	SensorData userdataR;
	
	int Data_Of_Thread_In;            
	char buffso_rcv[32]; 
	char buffso_send[7];

	//Trooper
	int servermode;
	int watchdog;
	int cycles;

	unsigned char speed1;
	unsigned char speed2;

	char buffso_rcvIN[100]; 
	char buffso_rcvOUT[100]; 
	char buffso_sendIN[100];
	char buffso_sendOUT[100];
	char buffer_address[sizeof(struct sockaddr)];
	char buffer_localip[sizeof(struct sockaddr)];

	DWORD  m_dwThreadID1;
	DWORD  m_dwThreadID2;
	DWORD  m_dwThreadID3;
	DWORD  m_dwThreadID4;
	DWORD  m_dwThreadID5;
	DWORD  m_dwThreadID6;
	DWORD  m_dwThreadID7;
	DWORD  m_dwThreadID8;

    HANDLE m_hThread1;
	HANDLE m_hThread2;
	HANDLE m_hThread3;
	HANDLE m_hThread4;
	HANDLE m_hThread5;
	HANDLE m_hThread6;
	HANDLE m_hThread7;
	HANDLE m_hThread8;

	HANDLE hUSB;
	HANDLE hCom_PIC;
	HANDLE hCom_GPS;
	
	WMutex mutexSend;
	WMutex mutexRcv;
};
#endif