/*
** getargs.c  Copyright 1991 Kent Paul Dolan,
**            Mountain View, CA, USA 94039-0755
**
** Written to satisfy an inquiry on USENet's rec.games.programmer newsgroup.
** May be freely used or modified in any non-commercial work.  Copyrighted
** only to prevent patenting by someone else.
*/


#include <stdio.h>
#include "townmaze.h"
#include "townproto.h"


#ifdef __STDC__
void getargs(int argc,char *argv[])
#else
int getargs(argc,argv)
  int argc;
  char *argv[];
#endif
{
  int scantemp;
  int i;

/*
** The next two data items and the code at the bottom to use them are
** adapted, and mostly stolen wholesale and reformatted, from suggestions
** submitted by "GLENN E. HOST" <host@ccf4.nrl.navy.mil> along with a
** very prompt bug report.  Besides, his changes made me go back and look
** harder at this interface; I hope this error reporting is more useful.
** Thanks, Glenn!
*/

  int errctr;

  static char *quit_messages[] =
  {
    " (-h): Maze height must be 11 or greater",
    " (-h): Maze height must be an odd number",
    " (-w): Maze width must be 11 or greater",
    " (-w): Maze width must be an odd number",
    " (-g): Maze gates must be a non-negative number",
    " (-g): Too many maze gates to fit",
    " (-l): Gates left must be a non-negative number",
    "s: Gates left (-l) must be no greater than gates at start (-g)",
    " (-c): Maze courts must be a non-negative number",
    " (-c): Too many maze courts to fit",
    "s: At least one court (-c) or one gate (-g) must exist",
    " (-u): Maze unused must be a non-negative number",
    " (-u): Too many unused cells to fit",
    " (-s): Straightness must be a non-negative number",
    " (-s): Straightness must be less than 999"
  };

#if PROGRESS
  fprintf(stderr,"Get arguments ");
#endif

  if (argc > 1)
  {
    if ((argc%2) != 1)
    {
      fprintf(stderr,"\n*** Parameters must come in flag/value pairs\n\n");
      usage();
      exit(1);
    }
    i = 1;
    while (i < argc)
    {
      if ((*argv[i]) != '-')
      {
        fprintf(stderr,
          "\n*** Expected flag, didn't see '-' for argument %d\n\n",i);
   
        usage();
        exit(1);
      }
      switch (*(argv[i]+1))
      {
      case 'h':
        if (   ((scantemp = sscanf(argv[i+1],"%d",&mazeheight)) == EOF)
            || (scantemp == 0))
        {
          fprintf(stderr,"\n*** Unable to read value after '-h'\n\n");
          usage();
          exit(1);
        }
        break;

      case 'w':
        if (   ((scantemp = sscanf(argv[i+1],"%d",&mazewidth)) == EOF)
            || (scantemp == 0))
        {
          fprintf(stderr,"\n*** Unable to read value after '-w'\n\n");
          usage();
          exit(1);
        }
        break;

      case 'g':
        if (   ((scantemp = sscanf(argv[i+1],"%d",&mazegates)) == EOF)
            || (scantemp == 0))
        {
          fprintf(stderr,"\n*** Unable to read value after '-g'\n\n");
          usage();
          exit(1);
        }
        break;

      case 'l':
        if (   ((scantemp = sscanf(argv[i+1],"%d",&leftgates)) == EOF)
            || (scantemp == 0))
        {
          fprintf(stderr,"\n*** Unable to read value after '-l'\n\n");
          usage();
          exit(1);
        }
        break;

      case 'c':
        if (   ((scantemp = sscanf(argv[i+1],"%d",&mazecourts)) == EOF)
            || (scantemp == 0))
        {
          fprintf(stderr,"\n*** Unable to read value after '-c'\n\n");
          usage();
          exit(1);
        }
        break;

      case 'u':
        if (   ((scantemp = sscanf(argv[i+1],"%d",&mazeunused)) == EOF)
            || (scantemp == 0))
        {
          fprintf(stderr,"\n*** Unable to read value after '-u'\n\n");
          usage();
          exit(1);
        }
        break;

      case 's':
        if (   ((scantemp = sscanf(argv[i+1],"%d",&mazestraightness)) == EOF)
            || (scantemp == 0))
        {
          fprintf(stderr,"\n*** Unable to read value after '-s'\n\n");
          usage();
          exit(1);
        }
        break;

      case 'r':
        if (   ((scantemp = sscanf(argv[i+1],"%ld",&randomseed)) == EOF)
            || (scantemp == 0))
        {
          fprintf(stderr,"\n*** Unable to read value after '-r'\n\n");
          usage();
          exit(1);
        }
        SEEDRANDOM(randomseed); /* override clock seed in main() */
        break;

      default:
        usage();
        exit(1);
      }
      i += 2;
    }
  }
/*
** Thanks to "GLENN E. HOST" <host@ccf4.nrl.navy.mil> for the idea, and
** most of the new code here, to dump out the reason a command line
** failed when it does. The functionality was pretty obviously needed
** with this many parameters and ways to fail.  Don't blame Glenn for the
** way the code looks now, it's back in what he called my "interesting
** coding style".
*/
  if (   (errctr=0, mazeheight < 11)
      || (errctr++, (mazeheight%2) != 1)
      || (errctr++, mazewidth < 11)
      || (errctr++, (mazewidth%2) != 1)
      || (errctr++, mazegates < 0)
      || (errctr++, mazegates > (  2*((mazeheight - 5)/6)
                                 + 2*((mazewidth - 5)/6)))
      || (errctr++, leftgates < 0)
      || (errctr++, leftgates > mazegates)
      || (errctr++, mazecourts < 0)
      || (errctr++, mazecourts > (((mazeheight - 5)/6)*((mazewidth - 5)/6)))
      || (errctr++, (mazecourts + mazegates) < 1)
      || (errctr++, mazeunused < 0)
      || (errctr++, mazeunused > (((mazeheight - 5)/14)*((mazewidth - 5)/14)))
      || (errctr++, mazestraightness < 0)
      || (errctr++, mazestraightness > 998)
     )
  {
    fprintf(stderr,"\n*** Bad argument%s. You said:\n\n",
                   quit_messages[errctr]);
    fprintf(stderr,"ht %d wd %d gates %d left %d courts %d",
                    mazeheight,mazewidth,mazegates,leftgates,mazecourts);
    fprintf(stderr," unused %d straight %d seed %ld\n\n",
                   mazeunused, mazestraightness,randomseed);
    usage();
    exit(1);
  }
  listsize = ((mazeheight - 1)/2)*((mazewidth - 1)/2);

#if HEADER
  fprintf(stdout,
   "ht %d wd %d gates %d left %d courts %d unused %d straight %d seed %ld\n",
   mazeheight,mazewidth,mazegates,leftgates,mazecourts,mazeunused,
   mazestraightness,randomseed);
#endif
  return;
}
