# include "basic.h"
# define prompt    "if: "

int run_if (int argc, char **argv) {

  int ThisList, depth, done, status, BreakOnTrue;
  int logic, equals;
  char *input, *outline, *val;
  int nloop, size;

  BreakOnTrue = FALSE;

  if ((argc != 2) && (argc != 3)) {
    fprintf (stderr, "USAGE: if (conditional) [break], end with the word 'END'\n");
    return (FALSE);
  }
  if ((argc == 3) && strcmp (argv[2], "break")) {
    fprintf (stderr, "USAGE: if (conditional) [break], end with the word 'END'\n");
    return (FALSE);
  }
  if ((argc == 3) && !strcmp (argv[2], "break")) {
    BreakOnTrue = TRUE;
  }

  /* read in if-list */
  nloop = 0;
  depth = 0;
  ThisList = Nlists;

  /* determine value of conditional expression */
  val = dvomath (1, &argv[1], &size, 0);
  if (val == NULL) { /* try expression as string op string */
    char **stack;
    int Nstack;

    stack = isolate_elements (1, &argv[1], &Nstack); 
    if (Nstack != 5) goto syntax;
    if (strcmp (stack[0], "(")) goto syntax;
    if (strcmp (stack[4], ")")) goto syntax;
    equals = -1;
    if (!strcmp (stack[2], "==")) equals = TRUE;
    if (!strcmp (stack[2], "!=")) equals = TRUE;
    if (equals == -1) goto syntax;
    logic = FALSE;
    if (equals && !strcmp (stack[1], stack[3])) logic = TRUE;
    if (!equals && strcmp (stack[1], stack[3])) logic = TRUE;
  } else {
    logic = atof (val); /* warning: round-off error is a danger */ 
  }
  if (BreakOnTrue) {
    if (logic) {
      loop_break = TRUE;
      return (FALSE);
    } else {
      return (TRUE);
    }
  }    

  done = FALSE;
  while (!done) {

    nloop ++;
    /* get the next line (from correct place) */
    if (ThisList == 0) {
      input = readline (prompt);
    } else {
      input = get_next_listentry (ThisList);
    }

    if ((ThisList == 0) && (input == (char *) NULL)) {
      fprintf (stderr, "end if-block with 'END'\n");
      continue;
    }
    if ((ThisList >  0) && (input == (char *) NULL)) {
      fprintf (stderr, "missing 'END' in if-block\n");
      input = strcreate ("end");
    }

    stripwhite (input);

    /* test for new macro, search for "end" statement */
    if (!logic && is_list (input)) {
      depth ++;
      free (input);
      continue;
    }
    
    /* check for an "else", invert logic */
    if ((depth == 0) && !strncasecmp (input, "ELSE", 4)) {
      logic ^= TRUE;
      free (input);
      continue;
    }

    /* test for end of nested block -- if not nested, END refers to this if */
    if (!strncasecmp (input, "END", 3)) {
      depth --;
      if (depth < 0) { 
	/* we hit the last "END", if-block is done */
	free (input);
	return (TRUE);	
      }
      free (input);  /* a do-nothing line */
      continue;
    }

    if (logic) {
      if (*input) { 
	if (ThisList == 0) add_history (input);
	status = command (input, &outline);
	if (outline != (char *) NULL) free (outline);
	if (!status) return (FALSE);
      }
    } else {
      free (input);
    }
  }
  return (TRUE);

 syntax:
  fprintf (stderr, "syntax error in if-statement\n");
  return (FALSE);
}

/*
     If we are entering at the keyboard (Nlists == 0), use readline.
     Otherwise, read from the current list, remove list lines.
     End when we hit the final "END" (the true END -- we count macro defines!!) 
     */
