/****************************************************************************
 * Copyright (c) 1992-2026 MAK Technologies, Inc
 * All rights reserved.
 ****************************************************************************/

//! \file configVariable.h
//! \brief Contains the DtConfigVariable class declaration.
//! \ingroup vl

#pragma once

#include "baseConfigVariable.h"
#include "variableGroup.h"
#include "varType.h"

#include <mtl/environment.h>
#include <vlutil/vlExceptions.h>
#include <cmdLine/cmdLine.h>
#include <matrix/vlVector.h>

#ifdef DtUSE_UTILITIES_NAMESPACE
namespace DtUSE_UTILITIES_NAMESPACE
{
#endif

class DtTaitBryan;

DtDeclareVarType( DtString, DtString )
DtDeclareVarType( int, int )
DtDeclareVarType( unsigned int, unsigned int )
DtDeclareVarType( double, double )
DtDeclareVarType( float, float )
DtDeclareVarType( DtVector, DtString )
DtDeclareVarType( bool, bool )
DtDeclareVarType( DtTaitBryan, DtString )
DtDeclareVarType( std::string, std::string );

template <typename T>
class DtConfigVariable : public DtBaseConfigVariable
{
public:

   //! \brief Var CTOR, using Group pointer.
   DtConfigVariable( DtVariableGroup* group, const DtString& aName, T aDefault,
      const DtString& aDescription = "", DtVariableScope aScope = DtBaseConfigVariable::DtScopeBoth,
      bool isRequired = false, const DtString& aShortcut = "" );

   //! \brief Var CTOR, using Group reference.
   DtConfigVariable( DtVariableGroup& group, const DtString& aName, T aDefault,
      const DtString& aDescription = "", DtVariableScope aScope = DtBaseConfigVariable::DtScopeBoth,
      bool isRequired = false, const DtString& aShortcut = "");
   
   //! \brief Var CTOR, using Group reference. Must use initializer function with this constructor
   //! to set the name and shortcut (if applicable)
   DtConfigVariable(DtVariableGroup& group, T aDefault,
      const DtString& aDescription = "", DtVariableScope aScope = DtBaseConfigVariable::DtScopeBoth,
      bool isRequired = false);

   //! \brief Var Copy CTOR, using Group pointer.
   DtConfigVariable( DtVariableGroup* group, const DtConfigVariable<T>& orig );

   //! \brief Var Copy CTOR, using Group reference.
   DtConfigVariable( DtVariableGroup& group, const DtConfigVariable<T>& orig );

   //! \brief DTOR
   virtual ~DtConfigVariable();

   //! \brief Assignment operator
   DtConfigVariable& operator=(const DtConfigVariable& rhs);

   //! \brief Create a command line argument for the native value.
   virtual void getCommandLineArg(DtCmdLine::CmdLine&);

   //! \brief Update the native value from the command line argument.
   virtual void updateFromCommandLineArg();

   //! \brief Get Environment schema type.
   virtual void getEnvironmentSchemaType(DtEnvironment env,TypeSet& usedTypes) const;

   //! \brief Create an Environment Value from the native value.
   virtual DtEnvValueSP getEnvironmentValue(DtEnvironment env);

   //! \brief Update the native value from the Environment Value.
   virtual void updateFromEnvironment(DtEnvironment env);

   //! \brief Get the Var's type.
   virtual DtString type() const;

   //! \brief Get if the var is required.
   virtual bool isRequired() const;

   //! @name Get/Set the variable name.
   //! @{

   virtual const DtString& name() const;
   void setName(const DtString& name);

   //! @}

   //! @name Get/Set the variable value.
   //! @{

   T value() const;
   void setValue(T aValue);

   //! @}

   //! @name Get/Set the variable's shortcut
   //! @{
   const DtString& shortcut() const;
   void setShortcut(const DtString& aShortcut);
   //! @}


   //! @name Set the variable's name and shortcut
   //! where aName is the string with an & indicating the letter
   //! for the shortcut. Example: "e&xercise" would have a shortcut of 'x'
   //! @{
   void setNameAndShortcut(const DtString& aName);
   //! @}

   //! @name Get/Set the default value.
   //! @{

   T defaultValue() const;
   void setDefaultValue(T aDefault);

   //! @}

   T* getInternalPtrValue();

protected:

   //! \brief Copy CTOR (not implemented).
   DtConfigVariable( const DtConfigVariable& other );

protected:

   //Internal Type
   typedef typename DtVarType<T>::ArgType ArgType;

   DtString myName;
   DtString myShortcut;
   bool myRequiredFlag;

   DtVariableGroup* myGroup;

   T myDefault;
   T myValue;
};

template <>
DT_DLL_MTL void DtConfigVariable<bool>::updateFromCommandLineArg();

template <>
DT_DLL_MTL void DtConfigVariable<bool>::getCommandLineArg(DtCmdLine::CmdLine& cmdLine);

#include "configVariable.inl"

#ifdef DtUSE_UTILITIES_NAMESPACE
}
#endif
