//=========================================================================
// Summary  :
// Filename : MMNavigation.h
// Author   : paley
// Project  :
// Revision : 1
// Created  : 2001/05/01
// Modified : 2001/05/14
//=========================================================================
// Description :  Navigation messages
//=========================================================================
#ifndef _MMNAVIGATION_H
#define _MMNAVIGATION_H

#include "ModemMessage.h"
#include "MMUtils.h"

#define NavigationMessageTimeOut 30

//////////////////////////////////////////////
class MMNavigationPosition : public MMConvertible
{

public:
	MMNavigationPosition(const ModemMessage *pMM);
	MMNavigationPosition(float latitude, float longitude, float northingRate,
		float eastingRate, float speed, float depth, float altitude, int updateTime);

	virtual const char* pcRead(const char* sourceBuffer);
	virtual char* pcWrite(char* destBuffer) const;
	virtual ModemMessage::Type tGetMessageType() const
		{ return ModemMessage::tMMNavigationPosition; };
	virtual int iGetDefaultTimeout() const 
		{ return NavigationMessageTimeOut; };

	void setLatitude(float latitude)
		{ m_latitude = latitude; };
	void setLongitude(float longitude)
		{ m_longitude = longitude; }
	void setNorthingRate(float northingRate)
		{ m_northingRate = MMUtil::double2char(northingRate,MIN_SPEED,MAX_SPEED); };
	void setEastingRate(float eastingRate)
		{ m_eastingRate = MMUtil::double2char(eastingRate,MIN_SPEED,MAX_SPEED); };
	void setSpeed(float speed)
		{ m_speed = MMUtil::double2char(speed,MIN_SPEED,MAX_SPEED); };
	void setDepth(float depth)
		{ m_depth = MMUtil::double2short(depth,MIN_DEPTH,MAX_DEPTH); };
	void setAltitude(float altitude)
		{ m_altitude = MMUtil::double2short(altitude,MIN_DEPTH,MAX_DEPTH); };
	void setUpdateTime(int updateTime)
		{ m_updateTime = updateTime; };

	float getLatitude()
		{ return m_latitude; };
	float getLongitude()
		{ return m_longitude; };
	float getNorthingRate()
		{ return MMUtil::char2double(m_northingRate,MIN_SPEED,MAX_SPEED); };
	float getEastingRate()
		{ return MMUtil::char2double(m_eastingRate,MIN_SPEED,MAX_SPEED); };
	float getSpeed()
		{ return MMUtil::char2double(m_speed,MIN_SPEED,MAX_SPEED); };
	float getDepth()
		{ return MMUtil::short2double(m_depth,MIN_DEPTH,MAX_DEPTH); };
	float getAltitude()
		{ return MMUtil::short2double(m_altitude,MIN_ALTITUDE,MAX_ALTITUDE); };
	int getUpdateTime()
		{ return m_updateTime; };

	void toString(char* str);
	static int size() { return 19; };

protected:
	float m_latitude;
	float m_longitude;
	//WARNING! m_northingRate and m_eastingRate resolution will be limited to
	// (MAX_SPEED - MIN_SPEED)/255 m/s
	uchar m_northingRate;
	uchar m_eastingRate;
	//WARNING! m_speed resolution will be limited to
	// (MAX_SPEED - MIN_SPEED)/255 m/s
	uchar m_speed;
	//WARNING! m_depth resolution will be limited to
	// (MAX_DEPTH - MIN_DEPTH)/65536 meters
	ushort m_depth;
	//WARNING! m_altitude resolution will be limited to
	// (MAX_ALTITUDE - MIN_ALTITUDE)/65535 meters
	ushort m_altitude;
	int m_updateTime;
};


//////////////////////////////////////////////
class MMNavigationAttitude : public MMConvertible
{

public:
	MMNavigationAttitude() {};
	MMNavigationAttitude(const ModemMessage *pMM);
	MMNavigationAttitude(float roll, float pitch, float yaw, int updateTime);

	virtual const char* pcRead(const char* sourceBuffer);
	virtual char* pcWrite(char* destBuffer) const;
	virtual ModemMessage::Type tGetMessageType() const
		{ return ModemMessage::tMMNavigationAttitude; };
	virtual int iGetDefaultTimeout() const 
		{ return NavigationMessageTimeOut; };

	void setRoll(float roll)
		{ m_roll = MMUtil::double2char(roll,MIN_TIP_ANGLE,MAX_TIP_ANGLE); };
	void setPitch(float pitch)
		{ m_pitch = MMUtil::double2char(pitch,MIN_TIP_ANGLE,MAX_TIP_ANGLE); };
	void setYaw(float yaw)
		{ m_yaw = MMUtil::double2char(MMUtil::modPi(yaw-PI)+PI,0.,2.*PI); };
	void setUpdateTime(int updateTime)
		{ m_updateTime = updateTime; };

	float getRoll()
		{ return MMUtil::char2double(m_roll,MIN_TIP_ANGLE,MAX_TIP_ANGLE); };
	float getPitch()
		{ return MMUtil::char2double(m_pitch,MIN_TIP_ANGLE,MAX_TIP_ANGLE); };
	float getYaw()
		{ return MMUtil::char2double(m_yaw,0.,2.*PI); };
	int getUpdateTime()
		{ return m_updateTime; };

	void toString(char* str);
	static int size() { return 7; };

protected:
	//WARNING! m_roll and m_pitch resolution will be limited to
	// (MAX_TIP_ANGLE - MIN_TIP_ANGLE)/255 rad
	uchar m_roll;
	uchar m_pitch;
	//WARNING! m_yaw resolution will be limited to
	// 2PI/255 rad
	uchar m_yaw;
	int m_updateTime;
};

#endif
