#include <stdio.h>
#include <ctype.h>
#include "common.h"

extern ARGLIST ArgList[];

static BOOL use_case;

static void remove_arg(int pos, int *count, char *list[])
{
  int i;

  // Decrement length of list
  (*count)--;

  // move items down
  for (i=pos; i<*count; i++)
    list[i] = list[i+1];

}
static BOOL cmatch(char t1, char t2)
{
  if (use_case)
    return(t1 == t2);

  return(toupper(t1) == toupper(t2));
}
// Callbacks of the form
//   void boolcallback( char selectchar, BOOL value)
//   void switchcallback( char selectchar, BOOL value)  ;; value always true
//   void stringcallback( char selectchar, char *string)
static int scan_args(char *string, int index, char *arg)
{
  int i=-1;
  while (ArgList[++i].id) {
    switch( ArgList[i].mode) {
      case ARG_SWITCH:
              if (cmatch(string[index], ArgList[i].id)) {
		(* ArgList[i].routine)(string[index],(char *)TRUE);
		 return (ARG_NEXTCHAR);
	      }
	      break;
      case ARG_BOOL:
	      if (cmatch(string[index], ArgList[i].id)) {
		if (string[0] == ARG_SEPTRUE)
		  (* ArgList[i].routine)(string[index],(char *)TRUE);
		else
		  (* ArgList[i].routine)(string[index],(char *)FALSE);
		return(ARG_NEXTCHAR);
	      }
	      break;
      case ARG_CONCATSTRING:
	      if (cmatch(string[index], ArgList[i].id)) {
		(* ArgList[i].routine)(string[index], string+index+1);
		return(ARG_NEXTARG);
	      }
	      break;
      case ARG_NOCONCATSTRING:
	      if (cmatch(string[index], ArgList[i].id)) {
		if (!arg)
		  return(ARG_NOARG);
                (* ArgList[i].routine)(string[index], arg);
                return(ARG_NEXTNOCAT);
              }
              break;
    }
  }
  return(ARG_NOMATCH);
}
BOOL parse_args(int *argc, char *argv[], BOOL case_sensitive)
{
  int pos = -1;

  BOOL retval = TRUE;
  use_case = case_sensitive;

  while(++pos < *argc) {
    if ((argv[pos][0] == ARG_SEPSWITCH) || (argv[pos][0] == ARG_SEPFALSE)
          || (argv[pos][0] == ARG_SEPTRUE)) {
      int argmode;
      int index = 1;
      int done = FALSE;
      do {
        // Scan the present arg
        if (pos < *argc - 1)
          argmode = scan_args(argv[pos], index, argv[pos+1]);
        else
          argmode = scan_args(argv[pos], index, 0);

        switch(argmode) {
          case ARG_NEXTCHAR:
                  // If it was a char, go to the next one
                  if (!argv[pos][++index])
                    done = TRUE;
                  break;
          case ARG_NEXTNOCAT:
                  // Otherwise if it was a nocat, remove the extra arg
                  remove_arg(pos, argc, argv);
                  // Fall through to NEXTARG
          case ARG_NEXTARG:
                  // Just a next arg, go do it
                  done = TRUE;
                  break;
          case ARG_NOMATCH:
                  // No such arg, spit an error
                  fprintf(stderr,"Invalid Arg: %s\n", argv[pos]);
                  done = TRUE;
                  retval = FALSE;
                  break;
          case ARG_NOARG:
                  // Missing the arg for a CONCAT type, spit the error
                  fprintf(stderr,"Missing string for Arg %s\n", argv[pos]);
                  done = TRUE;
                  retval = FALSE;
                  break;
        };

      } while (!done);
      // We'll always get rid of the present arg
      // And back up one
      remove_arg(pos--, argc, argv);
    }
  }
  return(retval);
}



