//=========================================================================
// Summary  :
// Filename : MMDynamicControl.h
// Author   : paley
// Project  :
// Revision : 1
// Created  : 2001/05/17
// Modified : 2001/05/17
//=========================================================================
// Description :  Dynamic control messages
//=========================================================================
#ifndef _MMDYNAMICCONTROL_H
#define _MMDYNAMICCONTROL_H

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

#define DynamicControlMessageTimeOut 60	//seconds

////////////////////////////////////////////////////
class MMDynamicControlCommand : public MMConvertible
{

public:
	MMDynamicControlCommand() {};
	MMDynamicControlCommand(const ModemMessage *pMM);
	MMDynamicControlCommand(float speed, float vertical, float horizontal,
		int time);

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

	void setPropellerRpm(float speed)
		{ m_speed = MMUtil::double2char(speed,MIN_PROP_RPM,MAX_PROP_RPM); };
	void setElevatorAngle(float vertical)
		{ m_vertical = MMUtil::double2short(vertical,MIN_ACT_ANGLE,MAX_ACT_ANGLE); };
	void setRudderAngle(float horizontal)
		{ m_horizontal = MMUtil::double2short(horizontal,MIN_ACT_ANGLE,MAX_ACT_ANGLE); };
	void setUpdateTime(int updateTime)
		{ m_updateTime = updateTime; };

	float getPropellerRpm()
		{ return MMUtil::char2double(m_speed,MIN_PROP_RPM,MAX_PROP_RPM); };
	float getElevatorAngle()
		{ return MMUtil::short2double(m_vertical,MIN_ACT_ANGLE,MAX_ACT_ANGLE); };
	float getRudderAngle()
		{ return MMUtil::short2double(m_horizontal,MIN_ACT_ANGLE,MAX_ACT_ANGLE); };

	float getSpeed(float min, float max)
		{ return MMUtil::char2double(m_speed,min,max); };
	float getVertical(float min, float max)
		{ return MMUtil::short2double(m_vertical,min,max); };
	float getHorizontal(float min, float max)
		{ return MMUtil::char2double(m_horizontal,min,max); };

	int getUpdateTime()
		{ return m_updateTime; };

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

protected:
	//WARNING! m_speed resolution will be limited
	uchar m_speed;			// defaults to prop rpm
	//m_vertical and m_horizontal need to be a short for precision
	ushort m_vertical;			// defaults to elevator rad
	ushort m_horizontal;		// defaults to rudder rad
	int m_updateTime;
};

////////////////////////////////////////////////////
class MMDynamicControlCommandFull : public MMDynamicControlCommand
{

public:

	enum VerticalMode { VmInitial = -1, Elevator, Pitch, Depth };
	enum HorizontalMode { HmInitial = -1, Rudder, Heading };
	enum SpeedMode { SmInitial = -1, Rpm, SpeedOpen, Speed };

	MMDynamicControlCommandFull(const ModemMessage *pMM);
	MMDynamicControlCommandFull(float speed, float vertical, float horizontal,
		int speedMode, int verticalMode, int horizontalMode, int time);

	virtual const char* pcRead(const char* sourceBuffer);
	virtual char* pcWrite(char* destBuffer) const;
	virtual ModemMessage::Type tGetMessageType() const
		{ return ModemMessage::tMMDynamicControlCommandFull; };

	void setSpeed(float speed);
	void setVertical(float vertical);
	void setHorizontal(float horizontal);

	float getSpeed();
	float getVertical();
	float getHorizontal();

	void setSpeedMode(int speedMode)
		{m_speedMode = MMUtil::int2char(speedMode); };
	void setVerticalMode(int verticalMode)
		{m_verticalMode = MMUtil::int2char(verticalMode); };
	void setHorizontalMode(int horizontalMode)
		{m_horizontalMode = MMUtil::int2char(horizontalMode); };

	int getSpeedMode()
		{ return MMUtil::char2int(m_speedMode); };
	int getVerticalMode()
		{ return MMUtil::char2int(m_verticalMode); };
	int getHorizontalMode()
		{ return MMUtil::char2int(m_horizontalMode); };

	void toString(char* str);
	static int size() { return 3+MMDynamicControlCommand::size(); };
protected:
	uchar m_speedMode;
	uchar m_verticalMode;
	uchar m_horizontalMode;
};

#endif
