#pragma linesize(132)

/* getargs.c     a UNIX-like switch reading routine

Copyright 1991, 1992, Robert C. Becker, Lantern Systems */

/* version 2.0

22 July, 1992.  Added -70, -75 options for emulation of HP 7470 and 7475 
plotters.  These plotters start up with relative character sizing.  The
DraftPro and the HPGL/2 spec set the default char size to absolute.  Also
removed istok () as dead code and modified getflags () to make better
use of pointers.

/* version 1.5

Added -db flag to turn on debugging output */

/*
valid option flags:

A	8.5 x 11 inch paper
B	11 x 17 inch paper
C	17 x 22 inch paper
D	22 x 34 inch paper
E	34 x 44 inch paper

A4	210 x 297 mm paper
A3	297 x 420 mm paper
A2	420 x 594 mm paper
A1	594 x 841 mm paper
A0	841 x 1189 mm paper

c	force CGA 640 x 200 mode
e	force EGA 640 x 350 mode
v	force VGA 640 x 480 mode

dp	assume HP DraftPro coordinate system (center of page = (0,0)
db	turn on debugging output

Note that options are case sensitive.
*/

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include "graph.h"	/* need this for video device definitions */
#include "hpgl.h"


#ifndef TRUE
#define TRUE  1
#endif
#ifndef FALSE
#define FALSE 0
#endif

#define		ERR_F		0x1F
#define		FNAME_LEN	128	/* length of longest MSDOS filename */
#define		EXIT1		1

static void nfexit (int, char *);
static void clear_flags ( void );
static int setflags ( int );
static void setopt_values ( int );
static void getflags ( char * );

static char copyright[] = "Copyright 1991, Robert C. Becker, Lantern Systems";

static char cf, ef, vf, Af, Bf, Cf, Df, Ef, A4f, A3f, A2f, A1f, A0f, dbf, dpf,
		 f70, f75;

static char *progname;	/* pointer to program name */

static char **files;
static char *path;	/* file found at requested directory path */
static char *dpath;	/* directory pathname */
static char fname_bfr [FNAME_LEN];	/* handy buffer for file names */
static char tokens[] = "c e v A B C D A4 A3 A2 A1 A0 db dp 70 75";

struct _vid_x_parm_ *forced_video [] = { CGA_640x200, CGA_640x200, EGA_640x350, 
			VGA_640x480 };	/* use CGA_640x200 to fill space */

#define VIDEO_AUTO	0
#define CGA_mode	1
#define EGA_mode	2
#define	VGA_mode	3

struct option
	{
	char *opt;		/* option char. string */
	int length;		/* length of option char string to match */
	int opt_value;		/* value of option */
	};

static struct option optarray[] =
	{
	{ "c", 1, CGA_mode},		/* these values correspond to array indices in	*/
	{ "e", 1, EGA_mode},		/* in forced_video[] */
	{ "v", 1, VGA_mode},
	{ "A4", 2, A4_paper},
	{ "A3", 2, A3_paper},
	{ "A2", 2, A2_paper},
	{ "A1", 2, A1_paper},
	{ "A0", 2, A0_paper},
	{ "db", 2, Debug_flag},
	{ "dp", 2, DRAFTPRO},
	{ "A", 1, A_paper},
	{ "B", 1, B_paper},
	{ "C", 1, C_paper},
	{ "D", 1, D_paper},
	{ "E", 1, E_paper},
	{ "70", 2, F_70},
	{ "75", 2, F_75},
	{ "", 0, 0}	/* end of struct */
	};

static struct options cmd_options;

/*----------------------------------*/

static void nfexit (int val, char *opt)
 	{
 	printf ("\n%s: ", progname);
	printf ("unknown option:  %s\n", opt);
	printf ("usage: %s  [-%s]  <file>\n", progname, tokens);

	exit (val);
	}


/*----------------------------------*/

static void clear_flags ( void )
	{
	Af = Bf = Cf = Df = Ef = 0;
	A4f = A3f = A2f = A1f = A0f = 0;
	cf = ef = vf = 0;
	dbf = 0;
	dpf = 0;
	f70 = f75 = 0;

	return;
	}

/*----------------------------------*/

static int setflags (int flag)
	{
	switch(flag)
		{
		case  0: cf = TRUE;	/* force CGA mode */
			cmd_options.video = optarray[flag].opt_value;
			break;
		case  1: ef = TRUE;	/* force EGA mode */
			cmd_options.video = optarray[flag].opt_value;
			break;
		case  2: vf = TRUE;	/* force VGA mode */
			cmd_options.video = optarray[flag].opt_value;
			break;
		case  3: A4f = TRUE;	/* A4 paper */
			setopt_values (flag);
			break;
		case  4: A3f = TRUE;	/* A3 paper */
			setopt_values (flag);
			break;
		case  5: A2f = TRUE;	/* A2 paper */
			setopt_values (flag);
			break;
		case  6: A1f = TRUE;	/* A1 paper */
			setopt_values (flag);
			break;
		case  7: A0f = TRUE;	/* A0 paper */
			break;
		case  8: dbf = TRUE;	/* debug mode */
			cmd_options.debug = optarray[flag].opt_value;
			break;
		case  9: dpf = TRUE;	/* draftpro mode */
			cmd_options.plotter = optarray[flag].opt_value;
			break;
		case 10: Af = TRUE;	/* A paper */
			setopt_values (flag);
			break;
		case 11: Bf = TRUE;	/* B paper */
			setopt_values (flag);
			break;
		case 12: Cf = TRUE;	/* C paper */
			setopt_values (flag);
			break;
		case 13: Df = TRUE;	/* D paper */
			setopt_values (flag);
			break;	
		case 14: Ef = TRUE;	/* E paper */
			setopt_values (flag);
			break;
		case 15: f70 = TRUE;	/* 7470 flag */
			cmd_options.plotter = optarray[flag].opt_value;
			break;
		case 16: f75 = TRUE;	/* 7475 flag */
			cmd_options.plotter = optarray[flag].opt_value;
			break;
		default: break;
		}
	return (TRUE);	/* return constant value for cheap programming simplification */
	}
 
/*----------------------------------*/

static void setopt_values (int index)
	{

	cmd_options.paper = optarray[index].opt_value;

	return;
	}
	

/*----------------------------------*/

static void getflags (char *args)
	{
 	int i, j, index, ind=FALSE;

	while (*args != '\0')
		{
		for (j = 0; ; j++)
			{

			if (optarray[j].opt[0] == *args)
				{
				if (optarray[j].length == 1)
					{
					ind = setflags (j);
					++args;
					break;
					}

				if (optarray[j].opt[1] == *(args + 1))
					{
					ind = setflags (j);
					args += 2;	/* skip to next char */
					break;
					}
				}
			if ( !optarray[j].length ) nfexit (EXIT1, args);	/* flag not found in list */
			}
		}

	return;
	}
 
/*----------------------------------*/

struct options *getargs (int argc, char **argv)
 	{
	char *s;

	path = (char *) calloc (1, 215);
	dpath = (char *) calloc (1, 215);
	cmd_options.paper = A_paper;	/* set default paper type to A-size */
	cmd_options.video = 0;		/* initialize video and papersize to defaults */
	cmd_options.plotter = 0;	/* no plotter specified: default to HPGL/2 spec */
	cmd_options.debug = 0;		/* no debugging output */

	s = progname = *argv++;
	--argc;
	while (*s)	/* get program name */
		{
		if (*s == ':' || *s == '\\' || *s == '/')
			progname = s + 1;
		++s;
		}
	strlwr (progname);

	clear_flags ();		/* zero all flags */

	if (**argv == '-')
		{
		while ( *(s = *argv) && (*s == '-'))	/* if we have command line flags, */
			{				/*ignore environment defaults */
			++argv;
			--argc;
			++s;	/* skip leading '-' */
			getflags (s);
			}
		}
	else
		{
		if ((s=getenv ("HPGL")) != NULL)
			{
			getflags (s);	/* get environment default flags */
			}
		}

	/* check for more than one paper size selected */
	if (Af + Bf + Cf + Ef + A4f + A3f + A2f + A1f + A0f > 1)
		{
		printf ("%s:  more than one paper size options selected\n", progname);
		exit (1);
		}

	if ((dpf != 0 && (f70 != 0 || f75 != 0)) || (f70 != 0 && f75 != 0))
		{
		printf ("%s:  more than one plotter type selected\n", progname);
		exit (1);
		}

	if (cf + ef + vf > 1)
		{
		printf ("%s: ignoring multiple video adapter modes\n", progname);
		cmd_options.video = VIDEO_AUTO;	/* use automatic mode selection */
		}

	if (argc < 1)
		{	/* use stdin */
		cmd_options.infile = stdin;
		}
	else
		{	/* get filename */
		strcpy (path, *argv);
		cmd_options.infile = fopen (path, "r");	/* returns NULL if no file */
		}

	return (&cmd_options);
	}

