#ifndef INCLUDED_OPTIONS_
#define INCLUDED_OPTIONS_

#include <string>
#include <vector>
#include <memory>
#include <filesystem>

#include "../support/support.h"

#ifdef fbb
    #include <bobcat/arg>
#else
    #include "../../tmp/build/arg/arg"
#endif

class Options: private Support
{
    using Path          = std::filesystem::path;
    using StrVect       = std::vector<std::string>;

    FBB::Arg &d_arg;

    bool d_clean;
    bool d_dependencies;
    bool d_stdCout;
    bool d_verbose;

    unsigned d_markType;        // See enum MarkType
    unsigned d_show;            // See enum Show

    size_t d_libraryTime;       // 0 or the --library's last modification time

    std::string d_extension;    // the extension of the files to inspect
    std::string d_colors;       // by default no colors
    std::string d_objDir;       // the location of compiled files
    std::string d_filename;
    std::string d_markFile;     // file receiving names of files to compile

    StrVect d_ignore;           // directories to ignore
    StrVect d_externals;        // vector of dirs containing external module
                                // .gcm files

    static std::unique_ptr<Options> s_options;

    public:
        enum MarkType
        {
            NO_MARK = 0,            // mo marking action
            COMPILE_DEPENDING = 1,  // compile depending modules (+)
            UPDATE_USER_TIMES = 2,  // update times of using modules (++)
            WRITE_USER_NAMES = 4,   // write the names to file (filename)
        };

        enum Show
        {
            QUIET           = 0,
            COMPILER_CALLS  = 1,
            DEPENDENCIES    = 2,
            ALL             = 3
        };

        Options(Options const &other) = delete;

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

        bool clean() const;                                             // .f
        bool compile() const;                                           // .f
        bool compileDepending() const;                                  // .f
        bool dependencies() const;                                      // .f
        bool needObjStructs() const;                                    // .f
        bool noArgs() const;                                            // .f
        bool stdCout() const;                                           // .f
        bool setUsers() const;                                          // .f
        bool verbose() const;                                           // .f

        unsigned markType() const;                                      // .f
        unsigned show() const;                                          // .f

        bool cmpLibrary(Path const &source) const;

        std::string const &basename() const;                            // .f
        std::string const &colors() const;                              // .f
        std::string const &markFile() const;                            // .f
        std::string const &extension() const;                           // .f
        std::string const &filename() const;    // used with -f         // .f
        std::string const &objDir() const;                              // .f

        StrVect const &ignore() const;                                  // .f
        StrVect const &externals() const;                               // .f
        bool noExternals() const;                                       // .f
    
    private:
        Options(char const *optString, 
                FBB::Arg::LongOption const *const begin,  
                FBB::Arg::LongOption const *const end,  
                int argc, char **argv, char const *version, 
                void (*usage)(std::string  const  &));

        void fillIgnore();
        void inspectVerbose();
        void setExtension();
        void setExternals();
        void setLibrarytime();
        void setMarkType();
        void setShow();
};
        
#include "options.f"

#endif

