/**
 * @file config.h
 *
 * Config - Class for maintaining program configuration.
 *
 * Copyright: 2005 Thomas Wintergerst. All rights reserved.
 *
 * $Id: config.h,v 1.1.2.1 2006/02/28 21:35:48 thomas Exp $
 * $Project:    CAPI for BSD $
 * $Target:     IX1 active ISDN board control program $
 * @date        03.01.2005
 * @author      "Thomas Wintergerst" <twinterg@gmx.de>
 * <p>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * </p>
 */

#ifndef CONFIG_H
#define CONFIG_H

#include <stddef.h>             // size_t
#include <string>

#ifndef CMDOPT2_H
#  include "cmdopt2.h"
#endif





// === Public declarations ===============================================





// === Class declarations ================================================





/**
 * Class for a command line option with a scalar value without an argument.
 */
template<class T>
class CValNoArgCmdOpt: public thwutil::CCmdOptBase
{
   public:
      /**
       * Constructor.
       *
       * @param cmdLineEvaluator
       *                        I: The command line evaluator object this option
       *                           object will be a member of. It is forwarded
       *                           to the constructor of the base class.
       * @param pszName         I: The name of the option.
       * @param iFlags          I: A bitmask of flags controlling the behaviour
       *                           of this class and of the command line
       *                           evaluator. It is a combination of the values
       *                           of the enumeration Flags_t.
       * @param ptValueTarget   I: The address of a memory location to copy the
       *                           current option value to. If this feature is
       *                           not needed, this parameter may be NULL.
       * @param tNotFoundValue  I: The value for the option if it is found on
       *                           the command line. With this parameter You
       *                           can query the option value without prior
       *                           checking if the option is found.
       * @param tFoundValue     I: The value for the option if it is found on
       *                           the command line.
       */
      CValNoArgCmdOpt
         (thwutil::CCmdLineEvaluator &cmdLineEvaluator,
          const char                 *pszName,
          int                         iFlags,
          T                          *ptValueTarget,
          T                           tNotFoundValue,
          T                           tFoundValue);
      
      /**
       * Destructor.
       */
      virtual ~CValNoArgCmdOpt (void);
   
      /**
       * Copy the current value to the internally managed address.
       *
       * This function simply copies the current option value to the memory
       * location specified in the constructor call. If it was given as the NULL
       * pointer, no copy operation will take place.
       *
       * @param None.
       *
       * @retval None.
       */
      virtual void CopyValue (void);
      
      /**
       * Get a string representation of the current value.
       *
       * This function returns the current value of the member strings
       * m_strPosValue and m_strNegValue respectively, according to the current
       * option value. The two strings may be specified in the constructor or
       * set later by using SetPositiveString() or SetNegativeString().
       *
       * @param None.
       *
       * @result A string representing the current (parameter) value of the
       *         option.
       */
      virtual std::string GetValueString (void);
      
      /**
       * Get the current value of the option.
       */
      virtual T GetValue (void);
      
   
   
   protected:
      /// The not-found value for the option.
      T m_tNotFoundValue;
      
      /// The value for the option if it was found on the command line.
      T m_tFoundValue;
      
      /// The reference to the target for the option value.
      T *m_ptValueTarget;
      
   
   
   
   private:
      /// No assignment operator supported (only declared, not implemented).
      CValNoArgCmdOpt & operator= (const CValNoArgCmdOpt &);
   
   
   
}; // CValNoArgCmdOpt<T>



/**
 * Class for maintaining program configuration.
 */
class CConfig
{
   public:
      /// The tasks that can be executed by the program.
      enum Task_t
      {
         TASK_UNKNOWN,          ///< No task to execute.
         TASK_ERROR,            ///< An error occurred evaluating the command
                                ///< line.
         TASK_USAGE,            ///< Only print usage information.
         TASK_LIST,             ///< List all available controllers and mark
                                ///< IX1 active ISDN controllers in the output.
         TASK_INIT,             ///< Create a config file from scratch.
         TASK_INIT_FORCE,       ///< Create a config file from scratch and
                                ///< overwrite an existing one.
         TASK_UPDATE,           ///< Update an existing config file.
         TASK_UPDATE_REMOVE,    ///< Update an existing config file and remove
                                ///< non-existing boards from it.
         TASK_RESET,            ///< Reset one or all boards.
         TASK_LOAD              ///< Load one or all boards.
      };
      
      
      
      /**
       * Constructor.
       */
      CConfig (void);
      
      /**
       * Destructor.
       */
      ~CConfig (void);
      
      /**
       * Perform general initialization.
       *
       * As this class is designed to create a static object, the constructor
       * will not get enough information for initializing the object. This will
       * thus be done by calling this member function.
       *
       * The main task is to set all internal member variables to reasonable
       * defaults. In addition the short program name is determined from the
       * argument specified. It is expected to be a file name, possibly
       * including some path specification. The basename of this file name will
       * be set as the program name.
       *
       * @param pszProgFileName I: The file name of the current program, maybe
       *                           including a path specification.
       *
       * @retval None.
       *
       * @throws std::invalid_argument
       *                        The argument is the NULL pointer or the empty
       *                        string.
       */
      void Init
         (const char *pszProgFileName);

      /**
       * Get the program name.
       */
      const char *GetProgName (void);
      
      /**
       * Print usage information.
       */
      void Usage (void);
      
      /**
       * Evaluate command line parameters.
       */
      void EvalCommandLine
         (int    iArgc,
          char **papszArgv);

      /**
       * Get the task selected through the command line parameters.
       */
      Task_t GetTask (void);
      
      /**
       * Get the name of the IX1A board driver.
       */
      const std::string &GetDriverName (void);
      
      /**
       * Get the base directory for download files.
       */
      const std::string &GetBaseDirectory (void);
      
      /**
       * Get the file suffix for backup files.
       */
      const std::string &GetBackupSuffix (void);
      
      /**
       * Get the setting for quiet operation.
       */
      bool Quiet (void);
      
      /**
       * Get the name for the configuration file.
       */
      const std::string GetConfigFileName (void);
      
      /**
       * Get the number of a specifically set controller number to handle.
       */
      unsigned GetControllerNumber (void);
      
      /**
       * Get the name of a specifically set controller name to handle.
       */
      const std::string &GetControllerName (void);
      
   
   
   protected:
   
   
   
   private:
      /// The short program file name.
      std::string m_strProgName;
      
      
      
      // --- command line options for the program ---
      
      /// The command line evaluator object.
      thwutil::CCmdLineEvaluator m_cmdLineEvaluator;
      
      /// The option for the task to list available controllers.
      CValNoArgCmdOpt<Task_t> m_cmdOptTaskList;
      
      /// The option for the task to create an initial configuration file.
      CValNoArgCmdOpt<Task_t> m_cmdOptTaskInit;
      
      /// The option for the task to create an initial configuration file and
      /// overwrite an existing one.
      CValNoArgCmdOpt<Task_t> m_cmdOptTaskInitForce;
      
      /// The option for the task to update an existing configuration file.
      CValNoArgCmdOpt<Task_t> m_cmdOptTaskUpdate;
      
      /// The option for the task to update an existing configuration file and
      /// remove any non-existing boards.
      CValNoArgCmdOpt<Task_t> m_cmdOptTaskUpdateRemove;
      
      /// The option for the task to reset one or all controllers.
      CValNoArgCmdOpt<Task_t> m_cmdOptTaskReset;
      
      /// The option for the task to load one or all controllers.
      CValNoArgCmdOpt<Task_t> m_cmdOptTaskLoad;
      
      /// The option for quiet operation.
      thwutil::CBooleanCmdOpt m_cmdOptQuiet;
      
      /// The option for a specific controller name to operate on.
      thwutil::CStringParamCmdOpt m_cmdOptCtlrName;
      
      /// The option for a specific controller number to operate on.
      thwutil::CUIntParamCmdOpt m_cmdOptCtlrNum;
      
      /// The option for specifying the configuration file name.
      thwutil::CStringParamCmdOpt m_cmdOptConfigFileName;
      
      /// The option for specifying a different firmware base directory.
      thwutil::CStringParamCmdOpt m_cmdOptBaseDir;
      
      /// The first option for usage output.
      CValNoArgCmdOpt<Task_t> m_cmdOptHelp1;
      
      /// The second option for usage output.
      CValNoArgCmdOpt<Task_t> m_cmdOptHelp2;
      
      
      
      // --- configuration data for the program
      
      /// The task to execute. By default it is set to TASK_LOAD.
      Task_t m_task;
      
      /// The name of a specific controller to handle if not all. The default
      /// value as an empty strings means to handle all controllers (if no
      /// specific controller number is set).
      std::string m_strCtlrName;
      
      /// The CAPI controller number for a specific controller to handle if not
      /// all. The default value null means to handle all controllers (if no
      /// specific controller name is set).
      unsigned m_uCtlrNum;
      
      /// Flag for quiet operation, i.e. to suppress normal output.
      bool m_fQuiet;
      
      /// The base directory for the boot code and firmware files.
      std::string m_strBaseDir;
      
      /// The name of the configuration file.
      std::string m_strConfigFileName;
   
   
   
}; // CConfig





// === Prototypes of interface functions =================================





#endif // CONFIG_H
