#ifndef IMSVRCFG_HH_
#define IMSVRCFG_HH_
#include <string>
#include "basictype.hh"
#include "IMSvr.hh"
#include "IMUtil.hh"
#include "lexmlconf.h"
#include "SunIM.h"

class IMSvrCfg
{
  public:
    enum IMSvrCfgOpt {
	    IMDIR = 0,
	    BASICLOCALE,
	    IFPATHNAME,
	    IFNAME,
	    PORT,
	    HOSTNAME,
	    NSMAP_CFG_FILE,
	    CONFIGFILE,
	    LECONFFILE,
	    CONVERSIONKEYS,
	    LABEL,
	    SETTRIGGEROFFKEYS,
	    IMCONFIG,
	    DIRECT_XSUNIM,
	    LOG_FACILITY,
	    LOG_LEVEL,
	    MESSAGE_LOCALE,
	    LOOKUPROW,
	    LOOKUPCOL,
	    NODAEMON,
	    DEBUGFLAG,
	    USER,
	    VARDIR,
#if defined(HAVE_UNIX_SOCKET)
	    UDSFILE,
#endif /* HAVE_UNIX_SOCKET */
	    DESKTOP,
	    PREFERRED_LOADING,
	    CFGOPT_LAST
    };

  protected:
    enum CfgType {
	    ARG_UNINIT = 0,
	    ARG_INVALID,
	    ARG_BOOL,
	    ARG_NUMBER,
	    ARG_STRING
    };

  private:
    struct CfgVal {
	enum IMSvrCfgOpt opt;
	string description;
	struct {
	    bool b;
	    int n;
	    string s;
	} v;
	enum CfgType type;
    };
    const IMSvrCfg *pbase;
    CfgVal *popts;

  protected:
    enum CfgType get_type(enum IMSvrCfgOpt opt)
    { return popts[opt].type; }
    const string& get_description(enum IMSvrCfgOpt opt)
    { return popts[opt].description; }
    void setbool(
	enum IMSvrCfgOpt opt,
	bool boolval
    );
    void setnum(
	enum IMSvrCfgOpt opt,
	int numval
    );
    void setstr(
	enum IMSvrCfgOpt opt,
	const char* strval
    );
    bool get_process_user(
        string &user
    );
    bool get_home_dir(
        string &dir
    );

  private:
    string command_name;

    void initbool(
    	enum IMSvrCfgOpt opt,
	const char* desc,
	bool boolval
    );
    void initnum(
    	enum IMSvrCfgOpt opt,
	const char* desc,
	int boolval
    );
    void initstr(
	enum IMSvrCfgOpt opt,
	const char* desc,
	const char* strval
    );
    void initialize();

  protected:
    /* methods for manipulating IMSvr. */
    IMUserMgr* get_usermgr(IMSvr *pimsvr)
    { return &pimsvr->usermgr; }
    bool config_lepath(IMSvr *pimsvr, const char* lepath)
    { return pimsvr->config_lepath(lepath); }
    bool config_listenaddress(IMSvr *pimsvr, IMSocketAddressVec &addrvec)
    { return pimsvr->config_listenaddress(addrvec); }
    bool config_le(IMSvr *pimsvr, const char* lepath, IIIMLEXMLConf &xml, bool preferred_loading)
	{ return pimsvr->config_le(lepath, xml, preferred_loading); }
    bool set_nsmap_config(IMSvr *pimsvr, IMNsMapStruct *nsm, int num_entries)
    { return pimsvr->set_nsmap_config(nsm, num_entries); }

  public:

    bool get_boolval(
	enum IMSvrCfgOpt opt
    ) const;
    int get_numval(
	enum IMSvrCfgOpt opt
    ) const;
    const char* get_strval(
	enum IMSvrCfgOpt opt
    ) const;
    void showall() const;

    const char* get_command_name()
    { return command_name.c_str(); }

    virtual bool configure(
	IMSvr *pimsvr
    ) = 0;

  protected:
    IMSvrCfg(
	const IMSvrCfg& base
    );
    IMSvrCfg(
	string cmdname
    );
    virtual ~IMSvrCfg();
};

#endif /* not IMSVRCFG_HH_ */

/* Local Variables: */
/* c-file-style: "iiim-project" */
/* End: */
