/* Copyright ) Darin Johnson, 1989 */

#include <exec/types.h>
#include <intuition/intuition.h>
#include <stdio.h>
#include <ctype.h>
#include "mymenu.h"

#define STR 1

#define SYNTAX(msg) { fprintf(stderr, "Error parsing MyMenu.conf: %s\n"); \
			return FALSE; }

#ifdef AZTEC_C
#define strcmp _BUILTIN_strcmp
#define strcpy _BUILTIN_strcpy
#define strlen _BUILTIN_strlen
#endif

FILE *conf;
char tok[256], menustr[256], itemstr[256], substr[256];

extern UBYTE menu_pen;

make_action(mi, typ, action)
  struct ext_MenuItem *mi;
  char typ, *action;
{
  register char *p, *index(), *rindex(), *copystr();

  mi->args = mi->cmd = NULL;
  if (typ=='c') {	/* CLI */
    if (*action == '"') {
      action++;
      p = index(action, '"');
    } else {
      p = index(action, ' ');
    }
    if (p) {	/* if arguments */
      *p++ = NULL;
      mi->args = copystr(p);
    }
    mi->cmd = copystr(action);
    mi->type = 'C';
  } else if (typ=='w') {
    if (*action=='"') {
      action++;
      p = rindex(action, '"');
      *p = NULL;
    }
    mi->cmd = copystr(action);
    mi->type = 'W';
  }
}

char get_token()
{
  char quote;
  register char c, *p;
retry:
  c = fgetc(conf);
  while(isspace(c)) c=fgetc(conf);	/* skip extra spaces */
  if (c=='#') {				/* comment */
    while((c=fgetc(conf))!='\n' && c!=EOF);
    goto retry;
  }
  if (!isalnum(c) && c!='"')
    return c;
	/* scan string */
  if (c=='"') {
    c = fgetc(conf);
    quote = TRUE;
  } else
    quote = FALSE;
  p = tok;
  do {
    if ((quote && c=='"') || (!quote && isspace(c)))
      break;
    if (c=='\\')
      c = fgetc(conf);
    if (isspace(c))
      c = ' ';
    *p++ = c;
  } while ((c=fgetc(conf))!=EOF);
  *p = NULL;
  return STR;
}

int parse_conf() {
  register char t;
  char *p, c, flag, cmd;
  struct ext_MenuItem *mi;
    
  while ((t=get_token()) != EOF) {
    if (t==STR) {
      if (stricmp(tok, "MENU")==0) {
        cmd = NULL;
        if ((t=get_token())=='<') {	/* command char */
	  cmd = fgetc(conf);
	  if (get_token() != '>')
	    SYNTAX("Missing closing'>'");
	  t=get_token();
	}
        if (t==STR)
	  strcpy(menustr, tok);
	else
	  SYNTAX("Missing menu name");
        if (get_token()==STR)
	  strcpy(itemstr, tok);
	else
          SYNTAX("Missing menu item name");
	if ((t=get_token())==STR) {
	  strcpy(substr, tok);
          t=get_token();
	} else {
	  substr[0] = NULL;
	}
	if (t != '|')
	  SYNTAX("Missing '|' separator");
	mi = add_menu(menustr, itemstr, substr, cmd);
	if (get_token() != STR)
	  SYNTAX("Syntax error after '|'");
		/* find out type */
	if (stricmp(tok, "CLI")==0)
	  flag = 'c';
	else if (stricmp(tok, "WB")==0)
	  flag = 'w';
	else
	  flag = NULL;
		/* read in command (rest of line */
	p = tok;
	while ((c=fgetc(conf)) != '\n' && c!=EOF)
	  *p++ = c;
	*p = NULL;
	make_action(mi, flag, tok);
      } else if (stricmp(tok, "COLOR")==0) {
        if ((t=get_token())!=STR)
          SYNTAX("Expected number after COLOR keyword");
        menu_pen = (UBYTE)atoi(tok);
      } else
        SYNTAX("Didn't find keyword");
    } else
      SYNTAX("Didn't find keyword");
  }
  return TRUE;
}

int parse_menus() {
  int stat;
  conf = fopen("S:MyMenu.conf", "r");
  if (conf==NULL) {
    conf = fopen("MyMenu.conf", "r");
    if (conf==NULL) {
      fprintf(stderr, "Can't open MyMenu.conf!\n");
      return FALSE;
    }
  }
  start_menu();
  menu_pen = 2;
  stat = parse_conf();
  end_menu();
  if (conf)
    fclose(conf);
  return stat;
}
