/* Autoconf patching by David Hedbor, neotron@lysator.liu.se */
/*********************************************************************/
/* file: misc.c - misc commands                                      */
/*                             TINTIN III                            */
/*          (T)he K(I)cki(N) (T)ickin D(I)kumud Clie(N)t             */
/*                     coded by peter unold 1992                     */
/*********************************************************************/

/* note: a bunch of changes were made for readline support -- daw */

#ifdef HAVE_STRING_H
#include <string.h>
#else
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#endif

#include <ctype.h>
#include "tintin.h"

#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif

/* externs */
extern struct session *newactive_session();
extern struct listnode *common_aliases, *common_actions, *common_subs,
 *common_myvars;
extern struct listnode *common_highs, *common_antisubs, *common_pathdirs;
extern char *get_arg_in_braces();
/* extern void term_echo(); */
extern int redraw, is_split;
extern struct session *sessionlist;
extern struct completenode *complete_head;
extern char tintin_char;
extern int echo;
extern int speedwalk;
extern int presub;
extern int togglesubs;
extern char vars[10][BUFFER_SIZE];	/* the %0, %1, %2,....%9 variables */
extern int mesvar[7];
extern int verbatim;
/****************************/
/* the cr command           */
/****************************/
void cr_command(ses)
     struct session *ses;
{
	if (ses != NULL)
		write_line_mud("\n", ses);
}
/****************************/
/* the version command      */
/****************************/
void version_command()
{
	char temp[80];
	sprintf(temp, "#You are using TINTIN++ %s\n\r", VERSION_NUM);
	tintin_puts2(temp, NULL);
	prompt(NULL);
}

/****************************/
/* the verbatim command,    */
/* used as a toggle         */
/****************************/
void verbatim_command()
{
	verbatim = !verbatim;
	if (verbatim)
		tintin_puts2("#All text is now sent 'as is'.", (struct sesssion *) NULL);
	else
		tintin_puts2("#Text is no longer sent 'as is'.", (struct session *) NULL);
	prompt(NULL);
}

/********************/
/* the #all command */
/********************/
struct session *all_command(arg, ses)
     char *arg;
     struct session *ses;
{
	struct session *sesptr;
	if (sessionlist) {
		get_arg_in_braces(arg, arg, 1);
		for (sesptr = sessionlist; sesptr; sesptr = sesptr->next)
			parse_input(arg, sesptr);
	}
	else
		tintin_puts("BUT THERE ISN'T ANY SESSION AT ALL!", ses);
	return ses;
}

void redraw_command()
{
	redraw = !redraw;
	if (redraw)
		tintin_puts2("#Ok. I now redraw input line when text arrives.", (struct session *) NULL);
	else
		tintin_puts2("#Ok. I no longer redraw the input line.", (struct session *) NULL);
	prompt(NULL);
}

/*********************/
/* the #bell command */
/*********************/
void bell_command(ses)
     struct session *ses;

{
	char temp[2];
	temp[0] = 7;
	temp[1] = 0;
	write(1, temp, 1);
}


/*********************/
/* the #boss command */
/*********************/
void boss_command(ses)
     struct session *ses;
{
	char temp[80];
	int i;
	for (i = 0; i < 50; i++) {
		sprintf(temp, "in-order traverse of tree starting from node %d resulted in %d red nodes\n", i, 50 - i);
		tintin_puts2(temp, (struct session *) NULL);
	}
	getchar();		/* stop screen from scrolling stuff */
}

/*********************/
/* the #char command */
/*********************/
void char_command(arg, ses)
     char *arg;
     struct session *ses;
{
	char strng[80];
	get_arg_in_braces(arg, arg, 1);
	if (ispunct(*arg)) {
		tintin_char = *arg;
		sprintf(strng, "#OK. TINTIN-CHAR is now {%c}\n", tintin_char);
		tintin_puts2(strng, (struct session *) NULL);
	}
	else
		tintin_puts2("#SPECIFY A PROPER TINTIN-CHAR! SOMETHING LIKE # OR /!", (struct session *) NULL);
}


/*********************/
/* the #echo command */
/*********************/
void echo_command(ses)
     struct session *ses;
{
	echo = !echo;
	if (echo)
		tintin_puts("#ECHO IS NOW ON.", ses);
	else
		tintin_puts("#ECHO IS NOW OFF.", ses);
}

/*********************/
/* the #end command */
/*********************/
void end_command(command, ses)
     char *command;
     struct session *ses;
{
	if (strcmp(command, "end"))
		tintin_puts("#YOU HAVE TO WRITE #end - NO LESS, TO END!", ses);
	else {
		quitmsg(NULL);
		/* changed for readline
		   struct session *sesptr;
		   for(sesptr=sessionlist; sesptr; sesptr=sesptr->next) 
		   cleanup_session(sesptr);
		   ses=NULL;  
		   if (is_split) 
		   write(1, "c", 2);
		   tintin_puts2("TINTIN suffers from bloodlack, and the lack of a beating heart...", ses);
		   tintin_puts2("TINTIN is dead! R.I.P.", ses);
		   tintin_puts2("Your blood freezes as you hear TINTIN's death cry.", ses);
		   term_echo();
		   exit(0);
		 */
	}
}

/***********************/
/* the #ignore command */
/***********************/
void ignore_command(ses)
     struct session *ses;
{
	if (ses) {
		if (ses->ignore = !ses->ignore)
			tintin_puts("#ACTIONS ARE IGNORED FROM NOW ON.", ses);
		else
			tintin_puts("#ACTIONS ARE NO LONGER IGNORED.", ses);
	}
	else
		tintin_puts("#No session active => Nothing to ignore!", ses);
}

/**********************/
/* the #presub command */
/**********************/
void presub_command(ses)
     struct session *ses;
{
	presub = !presub;
	if (presub)
		tintin_puts("#ACTIONS ARE NOW PROCESSED ON SUBSTITUTED BUFFER.", ses);
	else
		tintin_puts("#ACTIONS ARE NO LONGER DONE ON SUBSTITUTED BUFFER.", ses);
}

/**************************/
/* the #togglesubs command */
/**************************/
void togglesubs_command(ses)
     struct session *ses;
{
	togglesubs = !togglesubs;
	if (togglesubs)
		tintin_puts("#SUBSTITUTES ARE NOW IGNORED.", ses);
	else
		tintin_puts("#SUBSTITUTES ARE NO LONGER IGNORED.", ses);
}

/***********************/
/* the #showme command */
/***********************/
void showme_command(arg, ses)
     char *arg;
     struct session *ses;
{
	char result[BUFFER_SIZE], strng[BUFFER_SIZE];
	get_arg_in_braces(arg, arg, 1);
	prepare_actionalias(arg, result, ses);
	sprintf(strng, "%s", result);
	tintin_puts(strng, ses);
}

/***********************/
/* the #loop command   */
/***********************/
void loop_command(arg, ses)
     char *arg;
     struct session *ses;
{
	char left[BUFFER_SIZE], right[BUFFER_SIZE];
	char result[BUFFER_SIZE];
	int flag, bound1, bound2, counter;
	arg = get_arg_in_braces(arg, left, 0);
	arg = get_arg_in_braces(arg, right, 1);
	flag = 1;
	if (sscanf(left, "%d,%d", &bound1, &bound2) != 2)
		tintin_puts2("#Wrong number of arguments in #loop", ses);
	else {
		flag = 1;
		counter = bound1;
		while (flag == 1) {
			sprintf(vars[0], "%d", counter);
			substitute_vars(right, result);
			parse_input(result, ses);
			if (bound1 < bound2) {
				counter++;
				if (counter > bound2)
					flag = 0;
			}
			else {
				counter--;
				if (counter < bound2)
					flag = 0;
			}
		}
	}
}
/************************/
/* the #message command */
/************************/
void message_command(arg, ses)
     char *arg;
     struct session *ses;
{
	char offon[2][20];
	int mestype;
	char ms[6][20], tpstr[80];
	sscanf("aliases actions substitutes antisubstitutes highlights variables",
	     "%s %s %s %s %s %s", ms[0], ms[1], ms[2], ms[3], ms[4], ms[5]);
	strcpy(offon[0], "OFF.");
	strcpy(offon[1], "ON.");
	get_arg_in_braces(arg, arg, 1);
	mestype = 0;
	while (!is_abrev(arg, ms[mestype]) && mestype < 6)
		mestype++;
	if (mestype == 6)
		tintin_puts2("#Invalid message type to toggle.", ses);
	else {
		mesvar[mestype] = !mesvar[mestype];
		sprintf(tpstr, "#Ok. messages concerning %s are now %s",
			ms[mestype], offon[mesvar[mestype]]);
		tintin_puts2(tpstr, ses);
	}
}

/**********************/
/* the #snoop command */
/**********************/
void snoop_command(arg, ses)
     char *arg;
     struct session *ses;
{
	char buf[100];
	struct session *sesptr = ses;

	if (ses) {
		get_arg_in_braces(arg, arg, 1);
		if (*arg) {
			for (sesptr = sessionlist; sesptr && strcmp(sesptr->name, arg); sesptr = sesptr->next);
			if (!sesptr) {
				tintin_puts("#NO SESSION WITH THAT NAME!", ses);
				return;
			}
		}
		if (sesptr->snoopstatus) {
			sesptr->snoopstatus = FALSE;
			sprintf(buf, "#UNSNOOPING SESSION '%s'", sesptr->name);
			tintin_puts(buf, ses);
		}
		else {
			sesptr->snoopstatus = TRUE;
			sprintf(buf, "#SNOOPING SESSION '%s'", sesptr->name);
			tintin_puts(buf, ses);
		}
	}
	else
		tintin_puts("#NO SESSION ACTIVE => NO SNOOPING", ses);
}

/**************************/
/* the #speedwalk command */
/**************************/
void speedwalk_command(ses)
     struct session *ses;
{
	speedwalk = !speedwalk;
	if (speedwalk)
		tintin_puts("#SPEEDWALK IS NOW ON.", ses);
	else
		tintin_puts("#SPEEDWALK IS NOW OFF.", ses);
}

/***********************/
/* the #system command */
/***********************/
void system_command(arg, ses)
     char *arg;
     struct session *ses;
{
	get_arg_in_braces(arg, arg, 1);

	/* changed a little for readline support */
	if (!*arg) {
		tintin_puts2("#EXECUTE WHAT COMMAND?", ses);
		return;
	}
	system(arg);
	return;
}


/********************/
/* the #zap command */
/********************/
struct session *zap_command(ses)
     struct session *ses;
{
	tintin_puts("#ZZZZZZZAAAAAAAAPPPP!!!!!!!!! LET'S GET OUTTA HERE!!!!!!!!", ses);
	if (ses) {
		cleanup_session(ses);
		return newactive_session();
	}
	else {
		end_command("end", (struct session *) NULL);
	}
}




/************************/
/* the #wizlist command */
/************************/
/* void wizlist_command(ses)
   struct session *ses;
   {
   tintin_puts2("==========================================================================", ses);
   tintin_puts2("                           Implementor:", ses);
   tintin_puts2("                              Valgar ", ses);
   tintin_puts2("", ses);
   tintin_puts2("          Special thanks to Grimmy for all her help :)", ses);
   tintin_puts2("\n\r                         TINTIN++ testers:", ses);
   tintin_puts2(" Nemesis, Urquan, Elvworn, Kare, Merjon, Grumm, Tolebas, Winterblade ", ses); 
   tintin_puts2("\n\r A very special hello to Zoe, Oura, GODDESS, Reyna, Randela, Kell, ", ses);
   tintin_puts2("                  and everyone else at GrimneDIKU\n\r", ses);
   tintin_puts2("==========================================================================", ses);
   prompt(ses);
   } */

void wizlist_command(ses)
     struct session *ses;
{

	tintin_puts2("==========================================================================", ses);
	tintin_puts2("  There are too many people to thank for making tintin++ into one of the", ses);
	tintin_puts2("finest clients available.  Those deserving mention though would be ", ses);
	tintin_puts2("Peter Unold, Bill Reiss, Joann Ellsworth, Jeremy Jack, and the many people", ses);
	tintin_puts2("who send us bug reports and suggestions.", ses);
	tintin_puts2("            Enjoy!!!  And keep those suggestions coming in!!\n\r", ses);
	tintin_puts2("                       The Management...", ses);
	tintin_puts2("==========================================================================", ses);
}

/* deleted tab completion crap for readline; see rltab.c for new tab stuff */

void display_info(ses)
     struct session *ses;
{
	char buf[BUFFER_SIZE];
	int actions = 0;
	int aliases = 0;
	int vars = 0;
	int subs = 0;
	int antisubs = 0;
	int highs = 0;
	int ignore;

	actions = count_list((ses) ? ses->actions : common_actions);
	aliases = count_list((ses) ? ses->aliases : common_aliases);
	subs = count_list((ses) ? ses->subs : common_subs);
	antisubs = count_list((ses) ? ses->antisubs : common_antisubs);
	vars = count_list((ses) ? ses->myvars : common_myvars);
	highs = count_list((ses) ? ses->highs : common_highs);
	if (ses)
		ignore = ses->ignore;
	else
		ignore = 0;

	tintin_puts2("You have defined the following:", ses);
	sprintf(buf, "Actions : %d", actions);
	tintin_puts2(buf, ses);
	sprintf(buf, "Aliases : %d", aliases);
	tintin_puts2(buf, ses);
	sprintf(buf, "Substitutes : %d", subs);
	tintin_puts2(buf, ses);
	sprintf(buf, "Antisubstitutes : %d", antisubs);
	tintin_puts2(buf, ses);
	sprintf(buf, "Variables : %d", vars);
	tintin_puts2(buf, ses);
	sprintf(buf, "Highlights : %d", highs);
	tintin_puts2(buf, ses);
	sprintf(buf, "Echo : %d (1 - on, 0 - off)    Speedwalking : %d   Redraw: %d", echo, speedwalk, redraw);
	tintin_puts2(buf, ses);
	sprintf(buf, "Toggle Subs: %d   Ignore Actions : %d   PreSub-ing: %d", togglesubs, ignore, presub);
	tintin_puts2(buf, ses);

	prompt(ses);
}