/****************************************************************
 * LineDrawer by John M. Olsen. V1.0 July 5, 1987
 *
 * John M. Olsen
 * 1547 Jamestown Drive
 * Salt Lake City, UT  84121-2051
 *
 * Network addresses:
 * u-jmolse@ug.utah.edu  or  ...!{seismo,ihnp4}!utah-cs!utah-ug!u-jmolse
 *
 * This is public domain software.  Do whatever you want with it.
 * Just don't complain to me when it breaks after a few hundred people
 * have hacked on it. :^)
 *
 * This program takes a data file as a parameter and makes a line drawing
 * based on the commands in the file.  The instruction format is listed
 * below.  There should be two data files included.  One is a Mercator
 * projection of the USA, and the other is a really short demo of how to use
 * the color changing and line patterning commands.
 *
 * Manx Instructions:
 * cc LineDrawer.c
 * ln LineDrawer.o -lc
 *
 * It should (no guarantees) work fine with Lettuce C since I used only
 * longs, and have (hopefully) everything type cast correctly.
 ****************************************************************/
 
#include <exec/types.h>
#include <graphics/gfxbase.h>
#include <graphics/gfxmacros.h>
#include <intuition/intuition.h>
#include <stdio.h>

void *OpenLibrary();
struct Window *OpenWindow(), *w;
struct IntuiMessage *GetMsg(), *WaitPort(), *mesg;
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;

struct NewWindow nw =
{
	0, 10, 320, 100, /* window corner and size */
	-1, -1,
	CLOSEWINDOW | NEWSIZE, /* messages I want */
	ACTIVATE | NOCAREREFRESH | WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH
	| WINDOWSIZING | GIMMEZEROZERO,
	NULL, NULL, (UBYTE *) "LineDrawer by John M. Olsen V1.0",
	NULL, NULL,
	50,20,-1,-1,
	WBENCHSCREEN
};

main(argc,argv)
int argc;
char *argv[];
{
	char stuff[80];
	FILE *temp;

	if(!argc)
	{
		exit(1); /* not run from the cli */
	}
	if(!(temp = fopen(argv[1],"r")))
	{
		printf("Usage: %s <datafile>\n\n",argv[0]);
		puts("Valid instructions:");
		puts("1 minx miny maxx maxy");
		puts("2 x y   (draw to a point)");
		puts("3 x y   (move to a point)");
		puts("4 color (change foreground color)");
		puts("5 color (change background color)");
		puts("6 mode  (change drawmode)");
		puts("Lines beginning with a letter are comments.");
		puts("Comments may also follow instructions.");
		exit(1); /* file does not exist. */
	}
	fclose(temp);
	if(GfxBase = OpenLibrary("graphics.library",32L)) /* 1.1 is okay */
	{
		if(IntuitionBase = OpenLibrary("intuition.library",32L))
		{
			if(w = OpenWindow(&nw))
			{
				while(1)
				{
					body(argc,argv);
					if(!mesg)
					{ /* message not found in body */
						mesg = WaitPort(w->UserPort);
						mesg = GetMsg(w->UserPort);
					}
					if (mesg->Class == CLOSEWINDOW)
						break; /* die gracefully */
					ReplyMsg(mesg);
					mesg = NULL;
				}
				ReplyMsg(mesg);  /* reply after break */
				CloseWindow(w);
			}
			CloseLibrary(IntuitionBase);
		}
		CloseLibrary(GfxBase);
	}
	exit(0);
}

X/****************************************************************
 * All of the setup work is done, so do the picture now.  Argv and argc have
 * just been passed on to this routine for simplicity.
 *
 * Data file format:
 * lines may have white space just about anywhere.  Each command line begins
 * with a number followed by a number of parameters.  Any line not starting
 * with an appropriate number (after white space, if any) is considered to
 * be a comment.  Lines may also have a comment after the data.
 *
 * 1: minx miny maxx maxy.  These tell what range the coordinates fall into.
 * 2: x y.  Draw a line from current position to x,y.
 * 3: x y.  Move pen to position x,y.
 * 4: color.  Foreground pen color.
 * 5: color.  Background pen color.
 * 6: pattern.  Line pattern.  This is an unsigned word 0 to 65536 (0 to $ffff)
 * 7: mode.  This can change the way 4 to 6 appear by using only foreground,
 *           or complimenting colors, etc.  It can do some strange stuff.
 *           The current (unguaranteed values) usable here are:
 *           JAM1:       0
 *           JAM2:       1
 *           COMPLIMENT: 2
 *           INVERSVID:  4
 *           You can add these, so 3 = JAM2 and COMPLIMENT.
 ****************************************************************/

body(argc,argv)
int argc;
char *argv[];
{
	FILE *input;
	long minx, miny, maxx, maxy, cmd, x, y;
	struct RastPort *r;
	char str[100];

	r = w->RPort;
	SetRast(r,0L);
	SetAPen(r,1L);
	SetBPen(r,0L);
	if (input = fopen(argv[1],"r"))
	{
		while((cmd = fgetc(input)) != EOF)
		{
			mesg = GetMsg(w->UserPort);
			if(mesg) /* break out if a message recvd */
				break;
			switch(cmd)
			{
				case '1': /* min and max x,y */
				{
					fscanf(input,"%ld%ld%ld%ld",
					&minx,&miny,&maxx,&maxy);
					break;
				}
				case '2': /* draw to */
				{
					fscanf(input,"%ld%ld",&x,&y);
					Draw(r,(((x-minx)
					*(w->GZZWidth))/(maxx - minx)),
					(((y-miny)
					*(w->GZZHeight))/(maxy-miny)));
					break;
				}
				case '3': /* move to */
				{
					fscanf(input,"%ld%ld",&x,&y);
					Move(r,(((x-minx)
					*(w->GZZWidth))/(maxx - minx)),
					(((y-miny)
					*(w->GZZHeight))/(maxy-miny)));
					break;
				}
				case '4': /* foreground color */
				{
					fscanf(input,"%ld",&x);
					SetAPen(r, x);
					break;
				}
				case '5': /* background color */
				{
					fscanf(input,"%ld",&x);
					SetBPen(r,x);
					break;
				}
				case '6': /* draw pattern */
				{
					fscanf(input,"%ld",&x);
					SetDrPt(r,x);
					break;
				}
				case '7': /* draw mode  */
				{
					fscanf(input,"%ld",&x);
					SetDrMd(r,x);
					break;
				}
				case ' ': /* leading white space */
				case '\n':
				case '\t':
				case '\r':
				{
					break;
				}
				default: /* must be a comment */
				{
					fgets(str,100,input);
					break;
				}
			}
		}
		fclose(input);
	}
}
