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

//! \file baseConfigVariable.h
//! \brief Contains the DtBaseConfigVariable class declaration.
//! \ingroup vl

#pragma once

#include <mtl/environment.h>
#include <list>
#include <set>

#ifdef DtUSE_UTILITIES_NAMESPACE
namespace DtUSE_UTILITIES_NAMESPACE
{
#endif

namespace DtCmdLine
{
   class Arg;
   class CmdLine;
}

class DtString;
class DtVariableGroup;

//! \brief Bar Var class, used to access variables in a type neutral manner.
class DT_DLL_MTL DtBaseConfigVariable
{
public:

   typedef std::set<DtString> TypeSet;

   enum DtVariableScope
   {
      DtScopeInternal,
      DtScopeConfigFile,
      DtScopeCommandLine,
      DtScopeBoth
   };

public:

   //! \brief CTOR
   DtBaseConfigVariable( DtVariableGroup* settings,
      DtVariableScope aScope, const DtString& aDescription );

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

   //! \brief Assignment operator.
   //! Assigns all defining attributes of the variable.
   //! The variable's group that it belongs to remains unchanged.
   DtBaseConfigVariable& operator = ( const DtBaseConfigVariable& other );

   //! \brief Get the scope of this variable
   inline DtVariableScope scope() const
   {
      return myScope;
   }

   inline const DtString& description() const
   {
      return myDescription;
   }

   //! \brief Is this var used in the config line.
   inline bool inConfigFile() const
   {
      return scope() == DtScopeConfigFile || scope() == DtScopeBoth;
   }

   //! \brief Is this var used in the command line.
   inline bool inCommandLine() const
   {
      return scope() == DtScopeCommandLine || scope() == DtScopeBoth;
   }

   //! \brief Check to see if the value has been set.
   inline bool isSet() const { return mySetFlag; }

   //@name Abstract Interface
   //@{

   //! \brief Get the Var's name.
   virtual const DtString& name() const = 0;

   //! \brief Check to see if the value is required.
   virtual bool isRequired() const = 0;

   //! \brief Get an arg. If this var doesn't support Arguments return a
   //! NULL pointer.
   virtual void getCommandLineArg( DtCmdLine::CmdLine& cmdLine ) = 0;

   //! \brief Update the value by its argument.  This function will not be
   //! called if getCommandLineArg returns NULL.
   virtual void updateFromCommandLineArg() = 0;

   //! \brief Get an environment value which represents the XML scheme type.
   //! The var should check the type set before created type to eliminate
   //! duplicates.
   virtual void getEnvironmentSchemaType( DtEnvironment env,
      TypeSet& usedTypes ) const = 0;

   //! \brief Get an environment value which represent the value of the var.
   //! If the var type does not support environment representation a NULL smart
   //! pointer should be returned.
   virtual DtEnvValueSP getEnvironmentValue( DtEnvironment env ) = 0;

   //! \brief Synchronize the var with an environment.  This function will not
   //! be called if getEnvironmentValue() returns NULL.
   virtual void updateFromEnvironment( DtEnvironment env ) = 0;

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

   //@}

   static DtEnvValueSP createSchemaDeclaration( DtEnvironment env,
      const DtString& name,const DtString& type );

   //! \brief Help function for simple types.
   static DtEnvValueSP createSimpleSchemaType( DtEnvironment env,
      const DtString& typeName, const DtString& xsType );

   //! \brief Create a complex schema type.
   static DtEnvValueSP createComplexSchemaType( DtEnvironment env,
      const DtString& typeName, bool ordered,
      const std::list<DtBaseConfigVariable*>& members );

protected:

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

protected:

   //! \brief My scope
   DtVariableScope myScope;

   //! \brief Stores a flag to determine if this var has been set yet.
   bool mySetFlag;

   //! \brief Stores the argument relating with this var.
   DtCmdLine::Arg* myArg;

   //! \brief Stores a description of the variable.
   DtString myDescription;

};

#ifdef DtUSE_UTILITIES_NAMESPACE
}
#endif
