#ifndef INCLUDED_OPTIONS_
#define INCLUDED_OPTIONS_

#include <string>
#include <memory>

#include <bobcat/argconfig>
#include <bobcat/ranger>

#include "../enums/enums.h"

class Options
{
    FBB::ArgConfig &d_arg;

    bool        d_allDirs;
    TriState    d_addRoot;
    size_t      d_blockSize;
    bool        d_fromHome;
    std::string d_history;      // history filename
    size_t      d_historyLifetime;
    size_t      d_historyMaxSize;
    Position    d_historyPosition;
    std::string d_homeDir;
    size_t      d_now;
    bool        d_separate;         // separate previously made choices from 
                                    // new ones by a blank line

    static bool s_input;    

    static char s_defaultConfig[];
    static char s_defaultHistory[];

    static std::unique_ptr<Options> s_options;

    static bool s_fromHome[];
    static std::string const s_startAt[];
    static std::string const *s_endStartAt;

    static bool s_allDirs[];
    static std::string const s_dirs[];
    static std::string const *s_endDirs;

    static TriState s_addRoot[];
    static std::string const s_triState[];
    static std::string const *s_endTriState;

    public:
        Options(Options const &other) = delete;

        static Options &initialize(
                            char const *optString, 
                            FBB::ArgConfig::LongOption const *const begin,  
                            FBB::ArgConfig::LongOption const *const end,  
                            int argc, char **argv, char const *version, 
                            void (*usage)(std::string  const  &)
                        );
        static Options &instance();

        TriState addRoot() const;                               // .f

        bool all() const;           // option -a / --all        // .f

        bool allDirs() const;                                   // .f

        FBB::Ranger<char const **> args() const;                // .f

        size_t blockSize() const;                               // .f

        bool fromHome() const;                                  // .f

        bool generalized() const;   // --generalized-search / -g   .f

        std::string const &history() const;                     // .f
        size_t historyLifetime() const;                         // .f
        size_t historyMaxSize() const;                          // .f

        std::string const &homeDir() const;                     // .f

        int homedirChar() const;

        size_t icase() const;                                   // .f

        auto ignore() const;                                    // .f

        static bool input();                                    // .f

        size_t now() const;                                     // .f

        Position historyPosition() const;                       // .f

        bool separate() const;                                  // .f

        bool traditional() const;   // --traditional               .f

        std::string const &triStateStr() const;                 // .f
        
    private:
        Options(char const *optString, 
                FBB::ArgConfig::LongOption const *const begin,  
                FBB::ArgConfig::LongOption const *const end,  
                int argc, char **argv, char const *version, 
                void (*usage)(std::string  const  &));

        size_t find(char const *longOpt,
                    std::string const *begin, std::string const *end);

        static std::string getHome();

        std::string readConfigFile();       // ret. value not empty: imsg

        void setBlockSize();

        void setHistory();                  // history filename
        void setHistoryLifetime();
        void setMaxSize();
        void setPosition();

        void versionHelp(char const *version, 
                         void (*usage)(std::string  const  &)) const;

};

#include "options.f"

#endif



