#include "PostPre.h"
#include "Global.h"

#define	TEMPLATE1			"STARTUP-FILES/M,X-PAGESIZE=X/K/N,Y-PAGESIZE=Y/K/N,\
X-OFFSET=XOFF/K/N,Y-OFFSET=YOFF/K/N,X-DENSITY=XDEN/K/N,Y-DENSITY=YDEN/K/N,\
DENSITY=DEN/K/N,BW/S,RGB/S,CMYK/S,FONTMEM/K/N,HALFTONEMEM/K/N,VIRTUALMEM/K/N,\
LINEMEM/K/N,BANDSIZE/K/N,IFF-FILE=IFF/K,PRINTER/S,FILE/K,FROM/K/N,TO/K/N,\
NOFORMFEED/S,CENTERPAGE/S,PRINT-DENSITY=PRDEN/K/N,TEMPPATH/K,GRAPHICCARD/S,\
VERBOSE/S,CONWIN/S,CUSTOMSCREEN/S,PUBSCREEN/K,OPTFILE/K,BUFSIZE/K/N"

#define	TEMPLATE2			"STARTUP-FILES/M,X-PAGESIZE=X/K/N,Y-PAGESIZE=Y/K/N,\
X-OFFSET=XOFF/K/N,Y-OFFSET=YOFF/K/N,X-DENSITY=XDEN/K/N,Y-DENSITY=YDEN/K/N,\
DENSITY=DEN/K/N,BW/S,RGB/S,CMYK/S,FONTMEM/K/N,HALFTONEMEM/K/N,VIRTUALMEM/K/N,\
LINEMEM/K/N"

#define	OPT_FILES			0
#define	OPT_X					1
#define	OPT_Y					2
#define	OPT_XOFF				3
#define	OPT_YOFF				4
#define	OPT_XDEN				5
#define	OPT_YDEN				6
#define	OPT_DEN				7
#define	OPT_BW				8
#define	OPT_RGB				9
#define	OPT_CMYK				10
#define	OPT_FONTM			11
#define	OPT_HALFTM			12
#define	OPT_VM				13
#define	OPT_LINEMEM			14
#define	OPT_BAND				15
#define	OPT_IFF				16
#define	OPT_PRINTER			17
#define	OPT_FILE				18
#define	OPT_FROM				19
#define	OPT_TO				20
#define	OPT_NOFF				21
#define	OPT_CENTER			22
#define	OPT_PRDEN			23
#define	OPT_PATH				24
#define	OPT_GRAPHICCARD	25
#define	OPT_VERBOSE			26
#define	OPT_CONWIN			27
#define	OPT_SCREEN			28
#define	OPT_PUBSCREEN		29
#define	OPT_OPTFILE			30
#define	OPT_BUFSIZE			31

#define	OPT_COUNT			32


/*#define	OUTPUT_OPTS*/

LONG	opts[OPT_COUNT];

int	parse(int argc, struct RDArgs *rdargs)
{
	struct	RDArgs *argsptr;
	struct	DiskObject *diskobj;
	struct	startupnode *startupnode;
	char		**sptr, *line, *filename, diskobjname[256], diskobjpath[256-30];
	UBYTE		**toolarray;
	BOOL		bw = FALSE, rgb = FALSE, cmyk = FALSE, depth_error = FALSE;
	int		i;
#ifdef OUTPUT_OPTS
	struct	Node	*node;
#endif

	if(argc == 0)
	{
		if (_WBenchMsg && _WBenchMsg->sm_NumArgs)
		{
			NameFromLock(_WBenchMsg->sm_ArgList[_WBenchMsg->sm_NumArgs-1].wa_Lock, diskobjpath, 255-30);
			getfullfilename(diskobjname, diskobjpath, _WBenchMsg->sm_ArgList[_WBenchMsg->sm_NumArgs-1].wa_Name);
			IconBase = OpenLibrary("icon.library", 0);
			if (IconBase)
			{
				diskobj = GetDiskObject(diskobjname);
				if(diskobj)
				{
					toolarray = (UBYTE **) diskobj->do_ToolTypes;
					line = FindToolType(toolarray, "IFF");
					if(line)
					{
						argiff = TRUE;
						strcpy(Options.PostOpts.iffname, line);
						copy_options(&Options, &IffOptions);
						Options.PostOpts.allpages = TRUE;
						Options.PostOpts.bandrendering = FALSE;
					}
					argprint = (FindToolType(toolarray, "PRINTER")) ? TRUE : FALSE;
					if(argprint)
					{
						copy_options(&Options, &PrintOptions);
						Options.PostOpts.centerpage = FALSE;
						Options.PostOpts.formfeed = TRUE;
						Options.PostOpts.allpages = TRUE;
						Options.PostOpts.bandrendering = FALSE;
					}
					line = FindToolType(toolarray, "STARTUP-FILES");
					if(line)
					{
						free_list(&Options.startuplist);
						filename = strtok(line, ",");
						while(filename != NULL)
						{
							if(!strcmp(filename, "*"))
							{
								okmsg("'*' is not a valid filename!");
								filename = strtok(NULL, ",");								
								continue;
							}
							startupnode = (struct startupnode *) malloc(sizeof(struct startupnode));
							strcpy(startupnode->name, filename);
							startupnode->linknode.ln_Name = startupnode->name;
							AddTail(&Options.startuplist, (struct Node *) startupnode);
							filename = strtok(NULL, ",");
						}
					}
					argverbose = argcon = (FindToolType(toolarray, "VERBOSE")) ? TRUE : FALSE;
					Options.PostOpts.formfeed = (FindToolType(toolarray, "NOFORMFEED")) ? FALSE : TRUE;
					Options.PostOpts.centerpage = (FindToolType(toolarray, "CENTERPAGE")) ? TRUE : FALSE;
					if(FindToolType(toolarray, "CUSTOMSCREEN")) Options.Screen.custscreen = TRUE;
					line = FindToolType(toolarray, "PUBSCREEN");
					if(line)
					{
						if(strlen(line) > MAXPUBSCREENNAME)
						{
							okmsg("pubscreenname too long!");
						}
						else
						{
							Options.Screen.custscreen = FALSE;
							strcpy(pubscreenname, line);
						}
					}
					line = FindToolType(toolarray, "X");
					if(line)
					{
						Options.PostOpts.width = atoi(line);
					}
					line = FindToolType(toolarray, "Y");
					if(line) Options.PostOpts.height = atoi(line);
					line = FindToolType(toolarray, "BANDSIZE");
					if(line)
					{
						Options.PostOpts.bandsize = atoi(line);
						Options.PostOpts.bandrendering = TRUE;
					}
					line = FindToolType(toolarray, "XOFF");
					if(line) Options.PostOpts.xoff = atoi(line);
					line = FindToolType(toolarray, "YOFF");
					if(line) Options.PostOpts.yoff = atoi(line);
					line = FindToolType(toolarray, "XDEN");
					if(line) Options.PostOpts.xdpi = atoi(line);
					line = FindToolType(toolarray, "YDEN");
					if(line) Options.PostOpts.ydpi = atoi(line);
					line = FindToolType(toolarray, "DEN");
					if(line)
					{
						if(FindToolType(toolarray, "XDEN") ||
							FindToolType(toolarray, "XDEN"))
						{
							okmsg("You can't specify DEN when XDEN or YDEN is specified!");
						}
						else Options.PostOpts.xdpi = Options.PostOpts.ydpi = atoi(line);
					}
					line = FindToolType(toolarray, "PRDEN");
					if(line) Options.PostOpts.prden = atoi(line);
					bw = (FindToolType(toolarray, "BW")) ? TRUE : FALSE;
					rgb = (FindToolType(toolarray, "RGB")) ? TRUE : FALSE;
					cmyk = (FindToolType(toolarray, "CMYK")) ? TRUE : FALSE;
					line = FindToolType(toolarray, "FONTMEM");
					if(line) Options.PostOpts.fonts = atoi(line);
					line = FindToolType(toolarray, "HALFETONMEM");
					if(line) Options.PostOpts.htone = atoi(line);
					line = FindToolType(toolarray, "VIRTUALMEM");
					if(line) Options.PostOpts.vm = atoi(line);
					line = FindToolType(toolarray, "LINEMEM");
					if(line) Options.PostOpts.paths = atoi(line);
					line = FindToolType(toolarray, "TEMPPATH");
					if(line) strcpy(Options.temppath, line);
					line = FindToolType(toolarray, "BUFSIZE");
					if(line) Options.bufsize = atoi(line) > BUFSIZ ? atoi(line) : BUFSIZ;
					Options.graphiccard = (FindToolType(toolarray, "GRAPHICCARD")) ? TRUE : FALSE;
					FreeDiskObject(diskobj);
				}
				CloseLibrary((struct Library *) IconBase);
			}
			if(_WBenchMsg->sm_NumArgs > 1)
			{
				if(strlen((char *) diskobjname) > MAXFILENAME)
				{
					okmsg("filename is too long!");
				}
				else
				{
					strcpy(Options.lastfile, diskobjname);
					strcpy(Options.lastdir, diskobjpath);
					number_of_pages = splitpage(Options.lastfile);
					Options.PostOpts.from = 1;
					Options.PostOpts.to = number_of_pages;
					argfile = TRUE;
				}
			}
		}
	}
	else
	{
		for(i=0; i < OPT_COUNT; i++) opts[i] = 0;
		argsptr = ReadArgs(rdargs ? TEMPLATE2 : TEMPLATE1, opts, rdargs);
		if (argsptr == NULL)
		{
			if(rdargs) Fault(IoErr(), "parsing error", undobuff, 256);
			else PrintFault(IoErr(), NULL);
			return(20);
		}
		else
		{
			if (opts[OPT_IFF])
			{
				if(strlen((char *) opts[OPT_IFF]) > MAXFILENAME)
				{
					okmsg("iff-filename is too long!");
				}
				else
				{
					argiff = TRUE;
					copy_options(&Options, &IffOptions);
					strcpy(Options.PostOpts.iffname, (char *) opts[OPT_IFF]);
					Options.PostOpts.allpages = TRUE;
					Options.PostOpts.bandrendering = FALSE;
				}
			}
			if (opts[OPT_PRINTER])
			{
					argprint = TRUE;
					copy_options(&Options, &PrintOptions);
					Options.PostOpts.centerpage = FALSE;
					Options.PostOpts.formfeed = TRUE;
					Options.PostOpts.allpages = TRUE;
					Options.PostOpts.bandrendering = FALSE;
			}
			if (opts[OPT_OPTFILE])
			{
				LoadPostOptions((char *) opts[OPT_OPTFILE], &Options);
			}
			sptr = (char **) (opts[OPT_FILES]);
			if (sptr)
			{
				free_list(&Options.startuplist);
				while (*sptr)
				{
					if(strlen(*sptr) > MAXFILENAME)
					{
						okmsg("startup-filename is too long!");
					}
					else
					{
						if(!strcmp(*sptr, "*"))
						{
							okmsg("'*' is not a valid filename!");
							sptr++;
							continue;
						}
						startupnode = (struct startupnode *) malloc(sizeof(struct startupnode));
						strcpy(startupnode->name, *sptr);
						startupnode->linknode.ln_Name = startupnode->name;
						AddTail(&Options.startuplist, (struct Node *) startupnode);
					}
					sptr++;
				}
			}
			if (opts[OPT_NOFF]) 		Options.PostOpts.formfeed = FALSE;
			if (opts[OPT_CENTER])	Options.PostOpts.centerpage = TRUE;
			if (opts[OPT_SCREEN]) 	Options.Screen.custscreen = TRUE;
			if (opts[OPT_PUBSCREEN])
			{
				if(strlen((char *) opts[OPT_PUBSCREEN]) > MAXPUBSCREENNAME)
				{
					okmsg("pubscreenname is too long!");
				}
				else
				{
					strcpy(pubscreenname, (char *) opts[OPT_PUBSCREEN]);
					Options.Screen.custscreen = FALSE;
				}
			}
			if (opts[OPT_CONWIN])		argcon = TRUE;
			if (opts[OPT_X])				Options.PostOpts.width = *((LONG *) opts[OPT_X]);
			if (opts[OPT_Y])				Options.PostOpts.height = *((LONG *) opts[OPT_Y]);
			if (opts[OPT_BAND])
			{
				Options.PostOpts.bandsize = *((LONG *) opts[OPT_BAND]);
				Options.PostOpts.bandrendering = TRUE;
			}
			if (opts[OPT_XOFF])			Options.PostOpts.xoff = *((LONG *) opts[OPT_XOFF]);
			if (opts[OPT_YOFF])			Options.PostOpts.yoff = *((LONG *) opts[OPT_YOFF]);
			if (opts[OPT_XDEN])			Options.PostOpts.xdpi = *((LONG *) opts[OPT_XDEN]);
			if (opts[OPT_YDEN])			Options.PostOpts.ydpi = *((LONG *) opts[OPT_YDEN]);
			if (opts[OPT_DEN])
			{
				if (opts[OPT_XDEN] || opts[OPT_YDEN])
				{
					okmsg("You can't specify DEN when XDEN or YDEN is specified!");
				}
				else
				{
					Options.PostOpts.xdpi = *((LONG *) opts[OPT_DEN]);
					Options.PostOpts.ydpi = *((LONG *) opts[OPT_DEN]);
				}
			}
			if (opts[OPT_PRDEN])			Options.PostOpts.prden = *((LONG *) opts[OPT_PRDEN]);
			if (opts[OPT_BW])				bw = TRUE;
			if (opts[OPT_RGB])			rgb = TRUE;
			if (opts[OPT_CMYK])			cmyk = TRUE;


			if (opts[OPT_FONTM])			Options.PostOpts.fonts = *((LONG *) opts[OPT_FONTM]);
			if (opts[OPT_HALFTM])		Options.PostOpts.htone = *((LONG *) opts[OPT_HALFTM]);
			if (opts[OPT_VM])				Options.PostOpts.vm = *((LONG *) opts[OPT_VM]);
			if (opts[OPT_LINEMEM])		Options.PostOpts.paths = *((LONG *) opts[OPT_LINEMEM]);
			if (opts[OPT_FILE])
			{
				if(strlen((char *) opts[OPT_FILE]) > MAXFILENAME)
				{
					okmsg("filename is too long!");
				}
				else
				{
					strcpy(Options.lastfile, (char *) opts[OPT_FILE]);
					getpath(Options.lastdir, (char *) opts[OPT_FILE]);
					number_of_pages = splitpage(Options.lastfile);
					Options.PostOpts.from = 1;
					Options.PostOpts.to = number_of_pages;
					argfile = TRUE;
				}
			}
			if (opts[OPT_PATH])
			{
				if(strlen((char *) opts[OPT_PATH]) > MAXFILENAME)
				{
					okmsg("pathname is too long!");
				}
				else
				{
					strcpy(Options.temppath, (char *) opts[OPT_PATH]);
				}
			}
			if (opts[OPT_BUFSIZE])
			{
				if( *((LONG *) opts[OPT_BUFSIZE]) > BUFSIZ)
				{
					Options.bufsize = *((LONG *) opts[OPT_BUFSIZE]);
				}
			}
			if (opts[OPT_GRAPHICCARD]) Options.graphiccard = TRUE;
			if (opts[OPT_VERBOSE]) argverbose = TRUE;
			if (opts[OPT_FROM]) Options.PostOpts.from = *((LONG *) opts[OPT_FROM]);
			if (opts[OPT_TO]) Options.PostOpts.to = *((LONG *) opts[OPT_TO]);
			FreeArgs(argsptr);
		}
	}
	if(!argprint && !argiff)
	{
		argwindow = TRUE;
	}
	if(bw)
	{
		if(rgb || cmyk) depth_error = TRUE;
		else Options.PostOpts.depth = 1;
	}
	if(rgb)
	{
		if(bw || cmyk) depth_error = TRUE;
		else Options.PostOpts.depth = 3;
	}
	if(cmyk)
	{
		if(bw || rgb) depth_error = TRUE;
		else Options.PostOpts.depth = 4;
	}
	if(depth_error) okmsg("You can only specify one out of BW, RGB and CMYK!");
	depth_error = FALSE;
	if(argwindow)
	{
		if(argiff || argprint) depth_error = TRUE;
	}
	if(argiff)
	{
		if(argwindow || argprint) depth_error = TRUE;
	}
	if(argprint)
	{
		if(argwindow || argiff) depth_error = TRUE;
	}
	if(depth_error)
	{
		okmsg("You can only specify one out of WINDOW, PRINTER and IFF!");
		argwindow = TRUE;
		argiff = FALSE;
		argprint = FALSE;
	}
	if(Options.PostOpts.prden < 1 || Options.PostOpts.prden > 7) Options.PostOpts.prden = 7;
	if(argwindow) argcon = TRUE;

#ifdef OUTPUT_OPTS
	printf("Head: %x, Tail: %d, TailPred: %x\n", Options.startuplist.lh_Head,
				Options.startuplist.lh_Tail, Options.startuplist.lh_TailPred);
	for(node = Options.startuplist.lh_Head; node->ln_Succ; node = node->ln_Succ)
	{
		printf("node: %x, succ: %x, pred: %x name: %s\n",
				 node, node->ln_Succ, node->ln_Pred, node->ln_Name);
	}
	printf("argiff:      %6d iffname: %s\n", argiff, Options.PostOpts.iffname);
	printf("argprinter:  %6d\n", argprint);
	printf("argwindow:   %6d\n", argwindow);
	printf("xsize:       %6d\n", Options.PostOpts.width);
	printf("ysize:       %6d\n", Options.PostOpts.height);
	printf("bandsize:    %6d\n", Options.PostOpts.bandsize);
	printf("xoff:        %6d\n", Options.PostOpts.xoff);
	printf("yoff:        %6d\n", Options.PostOpts.yoff);
	printf("xden:        %6d\n", Options.PostOpts.xdpi);
	printf("yden:        %6d\n", Options.PostOpts.ydpi);
	printf("printden:    %6d\n", Options.PostOpts.prden);
	printf("depth:       %6d\n", Options.PostOpts.depth);
	printf("fontmem:     %6d\n", Options.PostOpts.fonts);
	printf("halftonemem: %6d\n", Options.PostOpts.htone);
	printf("vmem:        %6d\n", Options.PostOpts.vm);
	printf("linemem:     %6d\n", Options.PostOpts.paths);
#endif
	return(0);
}