#if !defined HAVE_NEXTARG_H__
#define      HAVE_NEXTARG_H__

#include "fxtiomanip.h"
#include "fxttypes.h"

#include <cstdlib>  // atol(), atof(), strtoul(), strtod()

#define x  nextarg_x

static int act = 0;

template <typename Type>
void next_arg(Type &v, const char *vname, const char *what,
              int argc, char **argv)
{
    Type def = v;
    ++act;
    if ( argc > act )
    {
        if ( argv[act][0] != '.' )
        {
            int b = 10;
            if ( (argv[act][0]=='0') && (argv[act][1]=='x') )  b = 16;
            if ( argv[act][0]=='_' )  { b = 2; argv[act]+=1; }

            Type x = 1;   x = -x; // check signed-ness
            if ( x>0 )  v = strtoul(argv[act], 0, b);
            else        v = strtol(argv[act], 0, b);

//            if ( x>0 )  cout << " :: UNsigned" << endl;
//            else   cout << " :: Signed" << endl;
        }
    }
    cout << "arg " << act << ": ";
    cout << v << " == " << vname;
    cout << "  [" << what << "]";
    cout << "  default=" << def;
    cout << endl;
}
// -------------------------

void
next_float_arg(double &v, const char *vname, const char *what,
               int argc, char **argv)
{
//    cout << " :: Float" << endl;
    double def = v;
    ++act;
    if ( argc > act )
    {
        if ( argv[act][0] != '.' )  v = strtod(argv[act], 0);
    }
    cout << "arg " << act << ": ";
    cout << v << " == " << vname;
    cout << "  [" << what << "]";
    cout << "  default=" << def;
    cout << endl;
}
// -------------------------

void
next_string_arg(char *&v, const char *vname, const char *what,
               int argc, char **argv, char *def)
{
//    cout << " :: String" << endl;

    ++act;
    if ( argc > act )  v = argv[act];
    else  v = def;

    cout << "arg " << act << ": ";
    cout << '"' << v << '"' << " == " << vname;
    cout << "  [" << what << "]";
    cout << "  default=" << '"' << def << '"';
    cout << endl;
}
// -------------------------

#undef x


#define NXARG(v, what) { next_arg(v, #v, what, argc, argv); }
#define NXARGFL(v, what) { next_float_arg(v, #v, what, argc, argv); }
#define NXARGSTR(v, what, def) { next_string_arg(v, ""#v, what, argc, argv, (char *)def); }
#define RESTARGS(what) { ++act; cout << "args " << act << ","<< act+1 << ",... : [" << what <<"]" << endl; }



#endif // !defined HAVE_NEXTARG_H__
