/*
Bongfilter $Revision: 2.1 $ (C) Copyleft Junya Ho. (of the GNU flavour)

This is bongfilter $Revision: 2.1 $.  Character substitutions can
be made easily by substituting into the table caps[] and lowr[]
below - a few substitutions have already been made as a 
demonstration.

This version does not support substitutions involving more than
one character at a time.

For usage information, type bongfilt without any arguments.  The
revision log is at the end of the source.

(more usage information)
- bongfilter can take input from the command line, or it can take
	info from a pipe, eg: "ls -al | bongfilt -none"
- the option -none adds no characters for inverse/underline/bold.
- for your ircII clients, probably the easiest way to incorporate
	bongfilter is to add an alias:
		/ALIAS bongf exec -out [path]/bongfilt -irc
	and invoking it by: /bongf text here
	from within your ircII client.

Questions and comments can be directed towards hojunya@ecf.toronto.edu
or glasshead on IRC.

*/

#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>

#define NOEMU 0
#define IRCEMU 1
#define VT100EMU 2

static char id[]="$Id: bongfilt.c,v 2.1 1994/05/05 03:56:25 hojunya Exp hojunya $";

static char caps[]="ABCD3FGHiJKLMN0PQRSTUVWXYZ";
static char lowr[]="abcdefghijk1mn0pqrs+uvwxyz";

char mangle(char ch)
{
	if (isupper(ch))
		return(caps[ch-'A']);
	else if (islower(ch))
		return(lowr[ch-'a']);
	else return(ch);
}

main (int argc, char **argv) {
	int emu;
	char oink[512];
	char *p_oink[3];
	p_oink[0]=NULL;
	p_oink[1]=oink;
	if (argc < 2) {
		fprintf(stderr,"Usage: bongfilt -none|-irc|-vt100 [text]\n");
		exit(1);}
	if (!strcmp(argv[1],"-none"))	emu=NOEMU;
	else if(!strcmp(argv[1],"-irc"))	emu=IRCEMU;
	else if(!strcmp(argv[1],"-vt100"))	emu=VT100EMU;
	else {
		fprintf(stderr,"Usage: bongfilt -none|-irc|-vt100 [text]\n");
                exit(1);}
	if (argc < 3)  {
		char *ret=gets(oink);
		while (ret != NULL) {
			do_mangle(2, &p_oink, emu);
			ret=gets(oink); } }
	else do_mangle(argc, argv, emu);
}

do_mangle(int arc, char **arv, int emu) {
	int vnum=2;
	int outnum=0;
	int inum=0;
	int bold=0;
	int inverse=0;
	int underline=0;
	struct timeval tp;
	char out[512];

	while (outnum < 511) {
		if (inum==(strlen(arv[vnum]))) {
			if (vnum<(arc-1)) {
				vnum++; inum=0;
				out[outnum]=' '; outnum++;
				continue;}
			else break; }
		out[outnum]=mangle(arv[vnum][inum]);
		outnum++;
		inum++;
		gettimeofday(&tp, NULL);
		if(tp.tv_usec%3) outnum+=boldify(&(out[outnum]), &bold, emu);
		gettimeofday(&tp, NULL);
		if(tp.tv_usec%3) outnum+=inversify(&(out[outnum]), &inverse, emu);
	        gettimeofday(&tp, NULL);
                if(tp.tv_usec%3) outnum+=underlinify(&(out[outnum]), &underline, emu);
	}
	if (bold) outnum+=boldify(&(out[outnum]), &bold, emu);
	if (inverse) outnum+=inversify(&(out[outnum]), &inverse, emu);
	out[outnum]='\0';
	printf("%s\n", out);
	fflush(stdout);
}
int underlinify (char *cpr, int *underline, int emu) {
	if (emu==NOEMU)
		return(0);
	else if (emu==VT100EMU)
	         if (!(*underline)) {
                        *cpr=27;cpr++; *cpr='[';cpr++;
                        *cpr='4';cpr++; *cpr='m';cpr++;
                        *underline=!(*underline);
                        return(4);
                }
                else {
                        *cpr=27;cpr++; *cpr='[';cpr++;
                        *cpr='m';cpr++;
                        *underline=!(*underline);
                        return(3);
                }
	else if (emu==IRCEMU) {
		*cpr=31;cpr++;
		*underline=!(*underline);
		return(1);
	}
}
int inversify (char *cpr, int *inverse, int emu) {
	if (emu==NOEMU)
		return(0);
        else if (emu==VT100EMU)
	        if (!(*inverse)) {
                        *cpr=27;cpr++; *cpr='[';cpr++;
                        *cpr='7';cpr++; *cpr='m';cpr++;
                        *inverse=!(*inverse);
                        return(4);
                }
		else {
                        *cpr=27;cpr++; *cpr='[';cpr++;
                        *cpr='m';cpr++;
                        *inverse=!(*inverse);
                        return(3);
 		}
	else if (emu==IRCEMU) {
		*cpr=22;cpr++;
		*inverse=!(*inverse);
		return(1);
	}
}
int boldify (char *cpr, int *bold, int emu) {
	if (emu==NOEMU)
		return(0);
        else if (emu==VT100EMU)
	        if(!(*bold)) {
                        *cpr=27;cpr++; *cpr='[';cpr++;
                        *cpr='1';cpr++; *cpr='m';cpr++;
                        *bold=!(*bold);
			return(4);
                }
                else {
                        *cpr=27;cpr++; *cpr='[';cpr++;
                        *cpr='m';cpr++; *cpr=15;cpr++;
                        *bold=!(*bold);
			return(4);
                }
	else if (emu==IRCEMU) {
		*cpr=2;cpr++;
		*bold=!(*bold);
		return(1);
	}
}

/*
$Log: bongfilt.c,v $
 * Revision 2.1  1994/05/05  03:56:25  hojunya
 * added much more usage information in the comments, because..
 *
 * Revision 2.0  1994/05/05  03:50:22  hojunya
 * added a substitution table instead previous (inefficient) method
 *
 * Revision 1.5  1994/05/04  04:52:14  hojunya
 * properly returns 0 when emu==NOEMU
 *
 * Revision 1.4  1994/05/04  04:48:16  hojunya
 * merged inverse and bold for different emus
 *
 * Revision 1.3  1994/05/04  04:37:52  hojunya
 * merged underline for all emu's
 *
 * Revision 1.2  1994/05/03  18:19:45  hojunya
 * added options for picking emulation
 *
 * Revision 1.1  1994/05/03  18:06:00  hojunya
 * Initial revision
 *
*/

