/* 
*	file: nikonMessage.h
*	author: Eric J Martin
*	
*	copyright: MBARI 2013
*
*	Creates a class for handling binary messages passed in the 
*	tcp server and clients
*
*/
#pragma once
#ifndef _NIKONMESSAGE_H_
#define _NIKONMESSAGE_H_



#ifdef _QNX
#include <mem.h>
#endif
#ifndef _QNX
#include <memory.h>
#endif
#include <string.h>
#include <assert.h>
#include <stdio.h>
#include <time.h>


#pragma pack( push, 1 )      /* Set single byte alignment */
#include "nikonD3Messages.h"

const unsigned long ulMaxNikonDynamicDataSize_c  = NIKON_MESSAGE_MAXDATALENGTH;
const unsigned long ulMaxNikonTotalPacketSize_c  = ulMaxNikonDynamicDataSize_c + sizeof( NikonMessageHeaderType );

#pragma pack( pop )          /* Restore pervious byte alignment. */

class NikonMessage
{
public:
	
	~NikonMessage(void);

	//ENCODING SERVICES
	NikonMessage(
		unsigned short unMessage = NIKON_MESSAGE_NONE,
		unsigned char  ucCommand = NIKON_COMMAND_GET,
		unsigned char  ucCameraID = 0);
	bool SetHeader(
		unsigned short unMessage = NIKON_MESSAGE_NONE,
		unsigned char  ucCommand = NIKON_COMMAND_GET,
		unsigned char  ucCameraID = 0);
	bool SetMessage(
		unsigned short unMessage = NIKON_MESSAGE_NONE, 
		unsigned char ucCommand = NIKON_COMMAND_GET, 
		unsigned char *pbyMessage = NULL, 
		unsigned long ulBytesInMessage = 0, 
		unsigned char ucCameraID = 0);

	//DECODING 
	NikonMessage(NikonMessageHeaderType * pHeader);
	bool SetHeader(NikonMessageHeaderType * pHeader);

	// Copy and assignment.
	NikonMessage(const NikonMessage &rRhs);
	NikonMessage & operator =(const NikonMessage &rRhs);

	static unsigned long HeaderSize(void);

	// Conversion operators for the message data itself.

	unsigned long MessageSize(void) const;			// return the size in bytes
	unsigned char *	Message(void) const;			// return a pointer to the message in memory
	unsigned short NikonCameraMessage(void) const;	// return the header's message constant
	unsigned char  NikonCommand(void) const;		// return the header's command constant
	
	operator char *(void) const;					// return a string points at the end of the message
	operator long(void) const;						// return the assumed long contained at the end of the message.
	operator unsigned long(void) const;				// return the assumend ulong contain at the end of the message.
	operator NikonMessageHeaderType *(void) const;	// return the pointer to the header
	operator NikonMessageStatusType *(void) const;	// return the point to a status structure at the end of the message
	operator NikonMessageUARTType *(void) const;	// return the point to the uart structure at the ean of the message

private:
	///////////////
	// Definitions.

	unsigned char * OptionalData(void) const;

	// Sub-class for handling message data in memory.
	class CBufferManager { 
	public:

		CBufferManager(void);
		CBufferManager(const CBufferManager &rRhs);

		virtual	~CBufferManager(void);

		CBufferManager & operator =(const CBufferManager &rRhs);

		bool SetBuffer(unsigned char *pbyBuffer, const unsigned long &rulMaxSize, const bool &rbAllocate = false);

		unsigned char *	GetMessage(void);

		unsigned long MessageSize(void) const;

	private:

		void Release(void);

		unsigned char *m_pbyBuffer;
		unsigned long m_ulBufferSize;
		bool m_bIsOwner;



	};

	const unsigned long m_ulMessageHeaderSize;
	const unsigned long m_ulMaxMessageLength;
	CBufferManager * m_pMessageBuffer;

					
};

#endif