#if !defined HAVE_NEXTARG_H__
#define      HAVE_NEXTARG_H__

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

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

// To suppress the echos such as
//   arg 1: val == explanation
// insert the following line
// #define FXT_SILENT_NXARG
// before the inclusion of this header file
// Note a few (harmless) warnings about
// unused variable will appear.

static int nextarg_act = 0;

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

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

//            if ( nextarg_x>0 )  cout << " :: UNsigned" << endl;
//            else   cout << " :: Signed" << endl;
        }
    }
#ifndef FXT_SILENT_NXARG
    cout << "arg " << nextarg_act << ": ";
    cout << v << " == " << vname;
    cout << "  [" << what << "]";
    cout << "  default=" << def;
    cout << endl;
#endif
}
// -------------------------

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

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

    ++nextarg_act;
    if ( argc > nextarg_act )  v = argv[nextarg_act];
    else  v = def;
#ifndef FXT_SILENT_NXARG
    cout << "arg " << nextarg_act << ": ";
    cout << '"' << v << '"' << " == " << vname;
    cout << "  [" << what << "]";
    cout << "  default=" << '"' << def << '"';
    cout << endl;
#endif
}
// -------------------------


#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) { ++nextarg_act; cout << "args " << nextarg_act << ","<< nextarg_act+1 << ",... : [" << what <<"]" << endl; }


#endif // !defined HAVE_NEXTARG_H__
