/*
 * if.c: handles the IF command for IRCII 
 *
 * Written By Michael Sandrof
 *
 * Copyright(c) 1990, 1991 
 *
 * See the COPYRIGHT file, or do a HELP IRCII COPYRIGHT 
 */
#include <ctype.h>
#include "irc.h"
#include "alias.h"
#include "ircaux.h"
#include "window.h"
#include "vars.h"
#include "output.h"

/*
 * next_expr finds the next expression delimited by brackets. The type
 * of bracket expected is passed as a parameter. Returns NULL on error.
 */
char	*next_expr(args, type)
char	**args;
char	type;
{
	char	*ptr,
		*ptr2,
		*ptr3;

	if (!*args)
		return NULL;
	ptr2 = *args;
	if (!*ptr2)
		return NULL;
	if (*ptr2 != type)
	{
		say("Expression syntax");
		return NULL;
	}
	ptr = MatchingBracket(ptr2 + 1, type, (type == '(') ? ')' : '}');
	if (!ptr)
	{
		say("Unmatched '%c'", type);
		return ptr2+1;
	}
	*ptr = '\0';
	do
		ptr2++;
	while (isspace(*ptr2));
	ptr3 = ptr+1;
	while (isspace(*ptr3))
		ptr3++;
	*args = ptr3;
	if (*ptr2)
	{
		ptr--;
		while (isspace(*ptr))
			*ptr-- = '\0';
	}
	return ptr2;
}

/*ARGSUSED*/
void	ifcmd(command, args, subargs)
char	*command,
	*args;
char	*subargs;
{
	char	*exp;
	char	*sub;
	int	flag = 0;
	int	result;

	if (!(exp = next_expr(&args, '(')))
	{
		yell("Missing CONDITION in IF");
		return;
	}
	sub = parse_inline(exp, subargs?subargs:empty_string, &flag);
	if (get_int_var(DEBUG_VAR) & DEBUG_EXPANSIONS)
		yell("If expression expands to: (%s)", sub);
	if (!*sub || *sub == '0')
		result = 0;
	else
		result = 1;
	new_free(&sub);
	if (!(exp = next_expr(&args, '{')))
	{
		yell("Missing THEN portion in IF");
		return;
	}
	if (!result && !(exp = next_expr(&args, '{')))
		return;
	parse_line(null(char *), exp, subargs ? subargs : empty_string, 0, 0);
		return;
}

/*ARGSUSED*/
void	whilecmd(command, args, subargs)
char	*command,
	*args;
char	*subargs;
{
	char	*exp = null(char *),
		*ptr,
		*body = null(char *),
		*newexp = null(char *);
	int	args_used;	/* this isn't used here, but is passed
				 * to expand_alias() */

	if ((ptr = next_expr(&args, '(')) == null(char *))
	{
		yell("WHILE: missing boolean expression");
		return;
	}
	malloc_strcpy(&exp, ptr);
	if ((ptr = next_expr(&args, '{')) == null(char *))
	{
		say("WHILE: missing expression");
		new_free(&exp);
		return;
	}
	malloc_strcpy(&body, ptr);
	while (1)
	{
		malloc_strcpy(&newexp, exp);
		ptr = parse_inline(newexp, subargs ? subargs : empty_string,
			&args_used);
		if (*ptr && *ptr !='0')
		{
			new_free(&ptr);
			parse_line(null(char *), body, subargs ?
				subargs : empty_string, 0, 0);
		}
		else
			break;
	}
	new_free(&newexp);
	new_free(&ptr);
	new_free(&exp);
	new_free(&body);
}

/*ARGSUSED*/
void	foreach(command, args, subargs)
char	*command,
	*args;
char	*subargs;
{
	char	*struc = null(char *),
		*ptr,
		*body = null(char *),
		*var = null(char *);
	char	**sublist;
	int	total;
	int	i;
	int	slen;
	int	old_display;

	if ((ptr = new_next_arg(args, &args)) == null(char *))
	{
		yell("FOREACH: missing structure expression");
		return;
	}
	malloc_strcpy(&struc, ptr);
	malloc_strcat(&struc, ".");
	upper(struc);
	if ((var = next_arg(args, &args)) == null(char *))
	{
		new_free(&struc);
		yell("FOREACH: missing variable");
		return;
	}
	if ((body = next_expr(&args, '{')) == null(char *))
	{
		new_free(&struc);
		yell("FOREACH: missing statement");
		return;
	}
	sublist=match_alias(struc, &total, VAR_ALIAS);
	slen=strlen(struc);
	old_display=window_display;
	for (i=0;i<total;i++)
	{
		window_display=0;
		add_alias(VAR_ALIAS, var, sublist[i]+slen);
		window_display=old_display;
		parse_line(null(char *), body, subargs ?
			subargs : empty_string, 0, 0);
		new_free(&sublist[i]);
	}
	new_free(&sublist);
	new_free(&struc);
}
