/* important to put all the doubles first
since the C compiler by default will align these at 8 byte boundaries */
extern struct cmdLineArgs {
  double betaQ4,errorQ4,KnLQ4;
  double betaQ3,errorQ3,KnLQ3;
  char plane[4];
  long verbose;
  char source[4];
} cmdlineargs_;

#include "mdb.h"
#include "scan.h"
#include "match_string.h"

#define PLANE 0
#define VERBOSE 1
#define Q3 2
#define Q4 3
#define SOURCE 4
#define N_OPTIONS 5
char *option[N_OPTIONS] = {
  "plane",
  "verbose",
  "q3",
  "q4",
  "source"
  };

#define XPLANE 0
#define YPLANE 1
#define PLANE_TYPES 2
char *planes[PLANE_TYPES] = {
  "x", "y" };

#define AMSOURCE 0
#define BMSOURCE 1
#define SOURCE_TYPES 2
char *sources[SOURCE_TYPES] = {
  "AM", "BM" };

static char *USAGE = "betaAtDipole  -verbose -plane={x|y} -source={BM|AM}\n\
   -Q4=beta=<value>[,error=<value>][,KnL=<value>] \n\
   -Q3=beta=<value>[,error=<value>][,KnL=<value>]";

static char *Q4Usage = "-Q4=beta=<value>[,error=<value>][,KnL=<value>]";
static char *Q3Usage = "-Q3=beta=<value>[,error=<value>][,KnL=<value>]";

char *plane = NULL;
char *source = NULL;
long verbose = 0;
double betaQ3 = 0.0;
double errorQ3 = 0.0;
double KnLQ3 = 0.0;
double betaQ4 = 0.0;
double errorQ4 = 0.0;
double KnLQ4 = 0.0;

/* since the function is called from fortran, all small letters
   is required */

void readcmdlineargs_(long *argc, char *argv, long length);
void init_stats_();
void report_stats_();

void readcmdlineargs_(long *argc, char *argv, long length) {
  SCANNED_ARG *scanned;
  long i, type_index, iterations;
  long unsigned dummyFlag;

  *argc  =  scanargs(&scanned, *argc, &argv);
  if (!*argc) {
    fprintf(stderr,"%s\n",USAGE);
    exit(1);
  }
  /* note that one one argument at a time is passed by the
     main fortran program. */
  for (i = 0; i<*argc; i++) {
    if (scanned[i].arg_type == OPTION) {
      delete_chars(scanned[i].list[0], "_");
      delete_chars(scanned[i].list[0], " ");
      switch(match_string(scanned[i].list[0], option, N_OPTIONS, UNIQUE_MATCH)) {
      case VERBOSE:
        verbose = 1;
        break;
      case PLANE:
        if (scanned[i].n_items > 1) {
          if (0>(type_index = match_string(scanned[i].list[1], 
                                            planes, PLANE_TYPES, UNIQUE_MATCH))) {
            fprintf(stderr, "Plane %s isn't valid.\n", scanned[i].list[1]);
            exit(1);
          }
          plane = (char *) malloc(sizeof(char)*4);
          strcpy(plane, strtok(planes[type_index], " ") );
          strcpy(cmdlineargs_.plane, plane);
        } 
        else {
          bomb("plane not specified", USAGE);
        }
        break;
      case SOURCE:
        if (scanned[i].n_items > 1) {
          if (0>(type_index = match_string(scanned[i].list[1], 
                                            sources, SOURCE_TYPES, UNIQUE_MATCH))) {
            fprintf(stderr, "Source %s isn't valid.\n", scanned[i].list[1]);
            exit(1);
          }
          source = (char *) malloc(sizeof(char)*4);
          strcpy(source, strtok(sources[type_index], " ") );
          strcpy(cmdlineargs_.source, source);
        } 
        else {
          bomb("source not specified", USAGE);
        }
        break;
      case Q4:
        if((scanned[i].n_items-=1)<0 ||
           !scanItemList(&dummyFlag, scanned[i].list+1, &scanned[i].n_items, 0,
                         "beta", SDDS_DOUBLE, &betaQ4, 1, 0,
                         "error", SDDS_DOUBLE, &errorQ4, 1, 0,
                         "KnL", SDDS_DOUBLE, &KnLQ4, 1, 0,
                         NULL) || betaQ4==0 ) {
          fprintf( stderr,"Q4: beta %lf error %lf KnL %lf\n", betaQ4, errorQ4, KnLQ4);
          bomb("bad -Q4 syntax", Q4Usage);
        }
        break;
      case Q3:
        if((scanned[i].n_items-=1)<0 ||
           !scanItemList(&dummyFlag, scanned[i].list+1, &scanned[i].n_items, 0,
                         "beta", SDDS_DOUBLE, &betaQ3, 1, 0,
                         "error", SDDS_DOUBLE, &errorQ3, 1, 0,
                         "KnL", SDDS_DOUBLE, &KnLQ3, 1, 0,
                         NULL) || betaQ3==0) {
          fprintf( stderr,"Q3: beta %lf error %lf KnL %lf\n", betaQ3, errorQ3, KnLQ3);
          bomb("bad -Q3 syntax", Q3Usage);
        }
        break;
      default:
        bomb("unknown option given.", USAGE);  
      }
    }
    else {
      bomb("bad argument", USAGE);
    }
  }
  cmdlineargs_.verbose = verbose;
  cmdlineargs_.betaQ3 = betaQ3;
  cmdlineargs_.errorQ3 = errorQ3;
  cmdlineargs_.KnLQ3 = KnLQ3;
  cmdlineargs_.betaQ4 = betaQ4;
  cmdlineargs_.errorQ4 = errorQ4;
  cmdlineargs_.KnLQ4 = KnLQ4;
  /*  fprintf( stdout, "verbose betaQ4 errorQ4 KnLQ4 betaQ3 errorQ3 KnLQ3\n%ld %lf %lf %lf %lf %lf %lf\n",cmdlineargs_.verbose,cmdlineargs_.betaQ4,cmdlineargs_.errorQ4,cmdlineargs_.KnLQ4,cmdlineargs_.betaQ3,cmdlineargs_.errorQ3,cmdlineargs_.KnLQ3);
      fflush(stderr);
      */

  return;
}

void init_stats_() {
  init_stats();
}

void report_stats_() {
  report_stats(stdout, "statistics: ");
}
