#include "generator.h"

#include <sstream>
#include <iomanip>
#include <fstream>
#include <cstring>
#include <filesystem>

#include <bobcat/exception>
#include <bobcat/datetime>
#include <bobcat/mstream>
#include <bobcat/pattern>
#include <bobcat/indent>
#include <bobcat/string>

#include "../options/options.h"
#include "../rules/rules.h"
#include "../terminal/terminal.h"
#include "../production/production.h"

extern char version[];

using namespace std;
using namespace filesystem;
using namespace FBB;

struct Generator::At
{
    char const *key;
    size_t size;
    std::string const &(Generator::*function)() const;

    At(char const *keyArg = "", 
        std::string const &(Generator::*fun)() const = 0)
    :
        key(keyArg),
        size(strlen(keyArg)),
        function(fun)
    {}
};

struct Generator::AtBool
{
    char const *key;
    size_t size;
    void (Generator::*function)(bool &accept) const;

    AtBool(char const *keyArg = "", void (Generator::*fun)(bool &) const = 0)
    :
        key(keyArg),
        size(strlen(keyArg)),
        function(fun)
    {}
};

template <typename AtType> 
typename vector<AtType>::const_iterator Generator::find(
    string const &line, 
    size_t pos, 
    vector<AtType> const &atVector
) const
{
    for (
        auto iter = atVector.begin(), end = atVector.end(); 
            iter != end; 
                ++iter
    )
    {
        if (line.find(iter->key, pos) == pos)
            return iter;
    }
    return atVector.end();
}
