/******************************************************************************
** Copyright (c) 2025 MAK Technologies, Inc.
** All rights reserved.
******************************************************************************/

//! \file DtObserverSettingsRecord.h
//! \brief Contains makArchives::DtObserverSettingsRecord class.
//! \ingroup makArchives

#pragma once

#include <makArchives/makArchives.h>

#include <string>

namespace makArchives
{
   //! \brief A DtObserverSettingsRecord contains the settings of an observer. 
   //! \ingroup makArchives
   class DT_DLL_MAKARCHIVES DtObserverSettingsRecord
   {
   public:

      enum AttachType
      {
         AttachTypeTether,
         AttachTypeMimic,
         AttachTypeFollow,
         AttachTypeTrack,
         AttachTypeTetherTrack,
         AttachTypeMimicTrack,
         AttachTypeModelView,
         AttachTypeSpaceFollow,
         AttachTypeTetherLocationTrack,
         AttachTypeMimicLocationTrack
      };

      //! \brief CTOR
      DtObserverSettingsRecord();

      //! \brief Copy CTOR
      DtObserverSettingsRecord(const DtObserverSettingsRecord& orig);

      //! \brief Assignment OP
      DtObserverSettingsRecord& operator=(const DtObserverSettingsRecord& orig);

      //! \brief DTOR
      ~DtObserverSettingsRecord();

      //! \name Accessors/ mutators:
      //@{

      void setObserverMode( const std::string& observerMode );
      const std::string& observerMode() const;

      void setAttachType( AttachType type );
      AttachType attachType() const;

      void setHideModelOnAttach( bool hide );
      bool hideModelOnAttach() const;

      void setOrientToTargetConstraint( bool orient );
      bool orientToTargetConstraint() const;

      void setOrbitSpeedGain( int gain );
      int orbitSpeedGain() const;

      void setRotationSpeedGain( int gain );
      int rotationSpeedGain() const;

      void setLinearScaledSpeedGain( int gain );
      int linearScaledSpeedGain() const;

      void setLinearUnscaledSpeedGain( int gain );
      int linearUnscaledSpeedGain() const;

//!       void setGainPrecision( int amt );
//!       int gainPrecision() const;

      void setOrbitSpeed( double speed );
      double orbitSpeed() const;

      void setRotationSpeed( double speed );
      double rotationSpeed() const;

      void setLinearSpeed( double speed );
      double linearSpeed() const;

      //@{
      //! \brief Get and set the speed scaling mode
      void setSpeedScalingMode( unsigned mode );
      unsigned speedScalingMode() const;
      //@}

      //@{
      //! \brief Get and set the speed scaling MSL mode offset
      void setSpeedScalingMslModeOffset( double offset );
      double speedScalingMslModeOffset() const;
      //@}

      //@{
      //! \brief Get and set whether the observer mode is a 2D or 3D projection.
      //! We need this for the saved view panel when an application loads an observer
      //! views file that contains observer modes that it doesn't know about (and so
      //! can't look this up
      void setProjectionIs2D( bool is2D );
      bool projectionIs2D() const;
      //@}

      //@{
      //! \brief Get and set the whether or not an effective zoom is calculated.
      //! \see DtOsgChannel::calculateEffectiveViewMagnification
      virtual void setIsFrustumBasedViewMagnificationEnabled(bool isEnabled);
      virtual bool isFrustumBasedViewMagnificationEnabled() const;
      //@}
      
      //@{
      //! \brief Get and set the north type
      void setNorthType(unsigned int northType);
      unsigned int northType() const;
      //@}

   protected:

      friend class boost::serialization::access;

      //! When the class Archive corresponds to an output archive, the
      //! & operator is defined similar to <<.  Likewise, when the class Archive
      //! is a type of input archive the & operator is defined similar to >>.
      template<class Archive>
         void serialize(Archive & ar, const unsigned int version)
      {
         ar & BOOST_SERIALIZATION_NVP(myAttachType);
         ar & BOOST_SERIALIZATION_NVP(myHideModelOnAttach);
         ar & BOOST_SERIALIZATION_NVP(myOrientToTargetConstraint);
         // no longer used
         ar & BOOST_SERIALIZATION_NVP(mySpeedScaling);
         // no longer used
         ar & BOOST_SERIALIZATION_NVP(myConstrainToTerrain);
         ar & BOOST_SERIALIZATION_NVP(myOrbitSpeedGain);
         ar & BOOST_SERIALIZATION_NVP(myRotationSpeedGain);
         ar & BOOST_SERIALIZATION_NVP(myLinearScaledSpeedGain);
         ar & BOOST_SERIALIZATION_NVP(myLinearUnscaledSpeedGain);
         //ar & BOOST_SERIALIZATION_NVP(myGainPrecision);
         ar & BOOST_SERIALIZATION_NVP(myOrbitSpeed);
         ar & BOOST_SERIALIZATION_NVP(myRotationSpeed);
         ar & BOOST_SERIALIZATION_NVP(myLinearSpeed);
         if ( version >= 2 )
         {
            ar & BOOST_SERIALIZATION_NVP(myObserverMode);
         }
         if ( version >= 3 )
         {
            ar & BOOST_SERIALIZATION_NVP(mySpeedScalingMode);

            if (version == 3)
            {
               double mySpeedScalingAslModeOffset = 0;
               ar & BOOST_SERIALIZATION_NVP(mySpeedScalingAslModeOffset);
               mySpeedScalingMslModeOffset = mySpeedScalingAslModeOffset;
            }
         }
         if (version >= 4)
         {
            ar & BOOST_SERIALIZATION_NVP(mySpeedScalingMslModeOffset);
         }
         if (version >= 5)
         {
            ar & BOOST_SERIALIZATION_NVP(myProjectionIs2D);
         }
         if (version >= 6 && version <= 8)
         {
            ar & BOOST_SERIALIZATION_NVP(myLodScaleCenterEnabled);
            ar & BOOST_SERIALIZATION_NVP(myLodScaleCenterMagMinLimit);
         }
         if (version >= 7)
         {
            ar & BOOST_SERIALIZATION_NVP(myNorthType);
         }
         if (version >= 8)
         {
            ar & BOOST_SERIALIZATION_NVP(myIsFrustumBasedViewMagnificationEnabled);
         }
      }

   protected:

      std::string myObserverMode;
      AttachType myAttachType;
      bool myHideModelOnAttach;
      bool myOrientToTargetConstraint;
      bool mySpeedScaling;
      bool myConstrainToTerrain;
      int myOrbitSpeedGain;
      int myRotationSpeedGain;
      int myLinearScaledSpeedGain;
      int myLinearUnscaledSpeedGain;
      //int myGainPrecision;
      double myOrbitSpeed;
      double myRotationSpeed;
      double myLinearSpeed;
      unsigned mySpeedScalingMode;
      double mySpeedScalingMslModeOffset;
      bool myProjectionIs2D;
      bool myIsFrustumBasedViewMagnificationEnabled;
      unsigned int myNorthType;

      // deprecated, exists in observer mode record
      bool myLodScaleCenterEnabled;
      double myLodScaleCenterMagMinLimit;
   };
}

BOOST_CLASS_VERSION(makArchives::DtObserverSettingsRecord, 8)


