
//! \file DtCigiBaseDiGuyExecuteGesture.h
//! \brief Contains makVrv::DtCigiBaseDiGuyExecuteGesture class
//! \ingroup vrvCigi

#pragma once

#include <makCigiExtensions/makCigiExtensions.h>

#include <CigiBaseVariableSizePckt.h>

#include <string>

namespace makCigiExt
{

   const int CIGI_DI_GUY_EXECUTE_GESTURE_PACKET_ID = 241;

   // This is the size of the FIXED portion of the packet
   const int CIGI_DI_GUY_EXECUTE_GESTURE_PACKET_SIZE = 16;

   const int CIGI_DI_GUY_EXECUTE_GESTURE_PACKET_ID_V4 = 0xf001;

   // This is the size of the FIXED portion of the packet
   const int CIGI_DI_GUY_EXECUTE_GESTURE_PACKET_SIZE_V4 = 24;

   //=========================================================
   //! The base class for all execute gesture packets.
   //!
   class DT_DLL_MAKCIGIEXTENSIONS DtCigiBaseDiGuyExecuteGesture :
      public CigiBaseVariableSizePckt
   {
   public:

      //==> Management

      //=========================================================
      //! General Constructor
      //!
      DtCigiBaseDiGuyExecuteGesture(void);

      //=========================================================
      //! General Destructor
      //!
      virtual ~DtCigiBaseDiGuyExecuteGesture(void);

      //=========================================================
      //! Copy Constructor
      //!
      DtCigiBaseDiGuyExecuteGesture(const DtCigiBaseDiGuyExecuteGesture &BaseIn);

      //=========================================================
      //! Assignment operator
      //!
      DtCigiBaseDiGuyExecuteGesture& operator=(const DtCigiBaseDiGuyExecuteGesture& BaseIn);

      //==> Buffer Packing/Unpacking

      //=========================================================
      //! A pure virtual Pack function.  
      //! This function is not implemented in this class.
      //! \param Base - A pointer to the instance of the packet 
      //!          to be packed. (Downcast to CigiBasePacket)
      //! \param Buff - A pointer to the current pack point.
      //! \param Spec - A pointer to special data.
      //!
      //! \return This returns CIGI_SUCCESS or an error code 
      //!   defined in CigiErrorCodes.h
      //!
      virtual int Pack(CigiBasePacket * Base, Cigi_uint8 * Buff, void *Spec) const = 0;

      //=========================================================
      //! A pure virtual Unpack function.
      //! This function is not implemented in this class.
      //! \param Buff - A pointer to the current pack point.
      //! \param Swap - N/A for V1 & V2
      //! \param Spec - A pointer to special data.
      //!
      //! \return This returns CIGI_SUCCESS or an error code 
      //!   defined in CigiErrorCodes.h
      //!
      virtual int Unpack(Cigi_uint8 * Buff, bool Swap, void *Spec) = 0;

      //=========================================================
      //! A virtual function to determine the size that the
      //!  packet will take up when packed.
      //! \param refPacket - A pointer to the packet being checked.
      //!
      //! \return The size that the packet will take up when packed
      //!
      virtual int GetTruePacketSize(CigiBaseVariableSizePckt &refPacket)
      { return(PacketSize + refPacket.GetVariableDataSize()); }

      //==> Accessing Member Variable Values functions

      //+> EntityID

      //=========================================================
      //! Sets the Entity ID with bound checking control
      //! \param EntityIDIn - Uniquely identifies the specific entity
      //!   0 - The ownship
      //!   All other values - An Application defined entity
      //! \param bndchk - Enables (true) or disables (false) bounds checking
      //!
      //! \return This returns CIGI_SUCCESS or an error code 
      //!   defined in CigiErrorCodes.h
      //!
      int SetEntityID(const Cigi_uint16 EntityIDIn, bool bndchk=true)
      {
         myEntityID = EntityIDIn;
         return(CIGI_SUCCESS);
      }

      //=========================================================
      //! Gets the Entity ID value
      //! \return EntityID uniquely identifies the specific entity
      //!   0 - The ownship
      //!   All other values - An Application defined entity
      //!
      Cigi_uint16 GetEntityID(void) const { return(myEntityID); }

      //+> PostureEn

      //=========================================================
      //! Sets the RepetitionsEn with bound checking control
      //! \param RepetitionsEnIn - Specifies if the repetition data is valid
      //!   and to be used.
      //! \param bndchk - Enables (true) or disables (false) bounds checking.
      //!
      //! \return This returns CIGI_SUCCESS or an error code
      //!   defined in CigiErrorCodes.h
      int SetRepetitionsEn(const bool RepetitionsEnIn, bool bndchk=true)
      {
         myRepetitionsEn = RepetitionsEnIn;
         return(CIGI_SUCCESS);
      }

      //=========================================================
      //! Gets the RepetitionsEn value.
      //! \return the current PostureEn.
      bool GetRepetitionsEn(void) const { return(myRepetitionsEn); }

      //+> Repetitions

      //=========================================================
      //! Sets the Repetitions with bound checking control
      //! \param RepetitionsIn - Specifies the number of times the 
      //! gesture should be repeated
      //!
      //! \param bndchk - Enables (true) or disables (false) bounds checking
      //!
      //! \return This returns CIGI_SUCCESS or an error code 
      //!   defined in CigiErrorCodes.h
      //!
      int SetRepetitions(const Cigi_uint16 RepetitionsIn, bool bndchk=true);

      //=========================================================
      //! Gets the Repetitions value
      //! \return Repetitions specifies the number of repetitions for the gesture
      //!
      Cigi_uint16 GetRepetitions(void) const { return(myRepetitions); }

      //+> WeaponStateEn

      //=========================================================
      //! Sets the DurationEn with bound checking control
      //! \param DurationEnIn - Specifies if the duration data is valid
      //!   and to be used.
      //! \param bndchk - Enables (true) or disables (false) bounds checking.
      //!
      //! \return This returns CIGI_SUCCESS or an error code
      //!   defined in CigiErrorCodes.h
      int SetDurationEn(const bool DurationEnIn, bool bndchk=true)
      {
         myDurationEn = DurationEnIn;
         return(CIGI_SUCCESS);
      }

      //=========================================================
      //! Gets the DurationEn value.
      //! \return the current DurationEn.
      bool GetDurationEn(void) const { return(myDurationEn); }

      //+> Duration

      //=========================================================
      //! Sets the Duration with bound checking control
      //! \param DurationIn - Specifies the gesture duration
      //!
      //! \param bndchk - Enables (true) or disables (false) bounds checking
      //!
      //! \return This returns CIGI_SUCCESS or an error code 
      //!   defined in CigiErrorCodes.h
      //!
      int SetDuration(float DurationIn, bool bndchk=true);

      //=========================================================
      //! Gets the duration value
      //! \return duration specifies the gesture's duration
      //! 0 Stowed 
      //! 1 Deployed
      //!
      float GetDuration(void) const { return(myDuration); }

      //+> ChannelAWeightEn

      //=========================================================
      //! Sets the ChannelAWeightEn with bound checking control
      //! \param ChannelAWeightEnIn - Specifies if the channel A Weight data is valid
      //!   and to be used.
      //! \param bndchk - Enables (true) or disables (false) bounds checking.
      //!
      //! \return This returns CIGI_SUCCESS or an error code
      //!   defined in CigiErrorCodes.h
      int SetChannelAWeightEn(const bool ChannelAWeightEnIn, bool bndchk=true)
      {
         myChannelAWeightEn = ChannelAWeightEnIn;
         return(CIGI_SUCCESS);
      }

      //=========================================================
      //! Gets the ChannelAWeightEnEn value.
      //! \return the current ChannelAWeightEn.
      bool GetChannelAWeightEn(void) const { return(myChannelAWeightEn); }

      //+> ChannelAWeight

      //=========================================================
      //! Sets the ChannelAWeight with bound checking control
      //! \param ChannelAWeightIn - Specifies the gesture's channel A weight
      //! 
      //! \param bndchk - Enables (true) or disables (false) bounds checking
      //!
      //! \return This returns CIGI_SUCCESS or an error code 
      //!   defined in CigiErrorCodes.h
      //!
      int SetChannelAWeight(float ChannelAWeightIn, bool bndchk=true);

      //=========================================================
      //! Gets the ChannelAWeight value
      //! \return ChannelAWeight specifies the gesture's channel A weight
      //!
      float GetChannelAWeight(void) const { return(myChannelAWeight); }

      //+> Gesture

      //! \return This returns CIGI_SUCCESS or an error code
      //!   defined in CigiErrorCodes.h
      int SetGesture(const std::string &GestureIn, bool bndchk=true);

      //! \return The current size of the gesture string.
      //!
      int GetGestureSize(void) const { return(VariableDataSize); }

      //=========================================================
      //! Gets the Animation (Action) string
      //! \return The current animation
      const std::string & GetGesture(void) const { return(myGesture); }

   protected:

      Cigi_uint16 myEntityID;
      Cigi_uint16 myRepetitions;
      float myDuration;
      float myChannelAWeight;
      std::string myGesture;

      bool myRepetitionsEn;
      bool myDurationEn;
      bool myChannelAWeightEn;

      //=========================================================
      //! MaxCharCnt<br>
      //! The maximum number of bytes not including NULLs for
      //! the gesture string.  This is (((248 - CIGI_DI_GUY_EXECUTE_GESTURE_PACKET_SIZE_V4) / 8) * 8)) - 1 
      //! for the null character
      //!
      static const int MaxCharCnt = 221;
   };
}

