#ifndef __LABJACK_H_INCLUDED__
#define __LABJACK_H_INCLUDED__

#include <stdint.h>
#include "socket.h"
#include "labjack_messages.h"

const uint16_t LabjackTCP_port = 52360;

class LabjackException : public exception {
public:

	//	Construct a SocketException with a explanatory message.
	//	message explanatory message
	//	incSysMsg true if system message (from strerror(errno))
	//	should be appended to the user provided message

	LabjackException(const string &message, bool inclSysMsg = false) throw();

	//	Provided just to guarantee that no exceptions are thrown.
	~LabjackException() throw();

	//	Get the exception message
	//	Returns exception message
	const char *what() const throw();

	private:
		string userMessage;  // Exception message
};

class Labjack {
public:

	Labjack(const string &LabjackIPAddress);
	~Labjack(void);

	// Set DAC values to Labjack, retrieve ADC values and switch positions
	void Update(double		winchDAC_voltage,
				double		levelWindDAC_voltage,
				double& 	motorTension,
			    double& 	flangeTension,
			    double&		busVoltage24,
			    bool&		isEndOfTravelLeftSwitchClosed,
			    bool&		isEndOfTravelRightSwitchClosed,
			    bool&		isCableLeftSwitchClosed,
			    bool&		isCableRightSwitchClosed) throw (LabjackException);

	void ConnectToLabjack(void);

private:

	void getCalibrationInfo(LabjackCalibrationInfo& calibrationInfo) throw(LabjackException);

	int32_t getCalibrationInfo(LabjackCalibrationInfo *caliInfo);

	double FPuint8ArrayToFPDouble(uint8_t *buffer, uint32_t startIndex);

	uint16_t analogToCalibratedBinaryVoltage(uint32_t whichDAC, double analogVoltage)
		throw (LabjackException);

	double binaryToCalibratedAnalogVoltage(uint8_t gain, uint16_t fixedPointVoltage)
		throw (LabjackException);

	bool isCalibrationInfoValid(void);

	//Adds checksum to a data packet for normal command format.
	void normalChecksum( uint8_t *packet, uint32_t bytesInPacket);

	//Adds checksum to a data packet for extended command format.
	void extendedChecksum( uint8_t *packet, uint32_t bytesInPacket);

	//Returns the Checksum8 for a normal command data packet
	uint8_t normalChecksum8( uint8_t *packet, uint32_t bytesInPacket);

	//Returns the Checksum16 for a extended command data packet.
	uint16_t extendedChecksum16(uint8_t *packet, uint32_t bytesInPacket);

	//Returns the Checksum8 for a extended command data packet
	uint32_t extendedChecksum8( uint8_t *packet);

	// Class data
	tcp_client_socket		m_LabjackSocket;
	LabjackCommandRequest	m_SendBuffer;
	LabjackCommandResponse	m_ReceiveBuffer;
	LabjackCalibrationInfo	m_CalibrationInfo;
};

#endif /* __LABJACK_H_INCLUDED__ */
