/*
 * options.c
 *
 * Copyright (C) 1989, 1991, Craig E. Kolb
 * All rights reserved.
 *
 * This software may be freely copied, modified, and redistributed
 * provided that this copyright notice is preserved on all copies.
 *
 * You may not distribute this software, in whole or in part, as part of
 * any commercial product without the express consent of the authors.
 *
 * There is no warranty or other guarantee of fitness of this software
 * for any purpose.  It is provided solely "as is".
 *
 * $Id$
 *
 * $Log$
 */
#include "rayshade.h"
#include "options.h"
#include "stats.h"
#include "viewing.h"

RSOptions	Options;

static void usage();

void
OptionsSet(argc, argv)
int argc;
char **argv;
{
	extern void OpenStatsFile();

	Options.progname = strsave(argv[0]);

	while(--argc) {
		argv++;
		if(argv[0][0] != '-')
			break;
		switch(argv[0][1]) {
			case 'A':
				Options.cutoff = atof(argv[1]);
				Options.cutoff_set = TRUE;
				argv++; argc--;
				break;
#ifdef URT
			case 'a':
				Options.alpha = !Options.alpha;
				break;
#endif
			case 'C':
				Options.cppargs = argv[1];
				argv++; argc--;
				break;
#ifdef URT
			case 'c':
				Options.appending = TRUE;
				break;
#endif
			case 'D':
				Options.maxdepth = atoi(argv[1]);
				Options.maxdepth_set = TRUE;
				argv++; argc--;
				break;
			case 'E':
				Options.eyesep = atof(argv[1]);
				Options.eyesep_set = TRUE;
				argc--; argv++;
				break;
#ifdef URT
			case 'e':
				Options.exp_output = TRUE;
				break;
#endif
			case 'F':
				Options.report_freq = atoi(argv[1]);
				if (Options.report_freq < 1)
					Options.report_freq = 1;
				Options.freq_set = TRUE;
				argv++; argc--;
				break;
			case 'f':
				Options.flipnorm = !Options.flipnorm;
				break;
			case 'G':
				Options.gamma = atof(argv[1]);
				argv++; argc--;
				break;
			case 'h':
				usage();
				exit(0);
				break;
			case 'j':
				Options.jittered = TRUE;
				Options.jittered_set = TRUE;
				break;
			case 'l':
				Options.stereo = LEFT;
				break;
			case 'n':
				Options.no_shadows = !Options.no_shadows;
				break;
			case 'O':
				Options.imgname = strsave(argv[1]);
				argv++;
				argc--;
				break;
			case 'o':
				Options.shadowtransp = TRUE;
				break;
			case 'P':
				Options.pixel_div = atoi(argv[1]);
				if (Options.pixel_div < 0)
					Options.pixel_div = 0;
				Options.adaptive_set = TRUE;
				argv++;
				argc--;
				break;
			case 'p':
				/*
				 * Preview-quality rendering
				 * no shadows or textures
				 * max depth of 0
				 * 1 jittered sample/pixel
				 */
				Options.no_shadows = TRUE;
				Options.maxdepth = 0;
				Options.maxdepth_set = TRUE;
				Options.pixel_div = 0;
				Options.jittered = TRUE;
				Options.jittered_set = TRUE;
				Options.jit_samples = 1;
				Options.samples_set = TRUE;
				break;
			case 'q':
				Options.quiet = TRUE;
				break;
			case 'R':
				Screen.xres = atoi(argv[1]);
				Screen.yres = atoi(argv[2]);
				Options.resolution_set = TRUE;
				argv += 2;
				argc -= 2;
				break;
			case 'r':
				Options.stereo = RIGHT;
				break;
			case 'S':
				Options.jit_samples = atoi(argv[1]);
				if (Options.jit_samples < 1)
					Options.jit_samples = 1;
				Options.samples_set = TRUE;
				argv++; argc--;
				break;
			case 's':
				Options.cache = !Options.cache;
				break;
			case 'T':
				Options.contrast.r = atof(argv[1]);
				Options.contrast.g = atof(argv[2]);
				Options.contrast.b = atof(argv[3]);
				Options.contrast_set = TRUE;
				argv += 3;
				argc -= 3;
				break;
			case 'v':
				Options.verbose = TRUE;
				break;
			case 'V':
				Options.verbose = TRUE;
				if (argv[1][0] == '-') {
					/* User probably blew it, and
					 * it's difficult to remove a file
					 * that begins with '-'...
					 */
					usage();
					exit(2);
				}
				Options.statsname = strsave(argv[1]);
				OpenStatsFile();
				argv++; argc--;
				break;
#ifdef URT
			case 'W':
				Screen.minx = atoi(argv[1]);
				Screen.miny = atoi(argv[2]);
				Screen.maxx = atoi(argv[3]);
				Screen.maxy = atoi(argv[4]);
				Options.window_set = TRUE;
				argv += 4; argc -= 4;
				break;
#endif
#ifdef LINDA
			case 'X':
				Options.workers = atoi(argv[1]);
				if (Options.workers<0 || Options.workers>17) {
					RLerror(RL_PANIC, "%d workers?\n",
							Options.workers);
				}
				argv++; argc--;
				break;
			case 'w':
				Options.verbose_worker =
					!Options.verbose_worker;
				break;
#endif
			default:
				RLerror(RL_PANIC,"Bad argument: %s\n",argv[0]);
		}
	}

	if(argc > 1) {
		usage();
		exit(1);
	} else if(argc == 1)
		Options.inputname = strsave(argv[0]);
	else
		Options.inputname = (char *)NULL;
}

void
OptionsList()
{
	fprintf(Stats.fstats,"Screen resolution: %d x %d\n",
		Screen.xres,Screen.yres);
	fprintf(Stats.fstats,"Image window: (%d - %d), (%d - %d).\n",
			Screen.minx, Screen.maxx, Screen.miny, Screen.maxy);
	if (Options.jittered) {
		fprintf(Stats.fstats,"Using jittered sampling, %d %s/pixel.\n",
			Options.jit_samples*Options.jit_samples,
			Options.jit_samples == 1 ? "sample" : "samples");
	} else { /* adaptive subdivistion */
		fprintf(Stats.fstats,
			"Maximum adaptive subdivision level: %d.\n",
			Options.pixel_div);
		fprintf(Stats.fstats,
			"Maximum contrast: %g red, %g green, %g blue.\n",
			Options.contrast.r, Options.contrast.g,
			Options.contrast.b);
	}
	fprintf(Stats.fstats,"Maximum ray depth: %d.  Cutoff threshold: %g.\n",
			Options.maxdepth, Options.cutoff);
	if (Options.stereo == LEFT)
		fprintf(Stats.fstats,"Rendering image for left eye.\n");
	else if (Options.stereo == RIGHT)
		fprintf(Stats.fstats,"Rendering image for right eye.\n");
	if (Options.no_shadows) {
		fprintf(Stats.fstats,"No shadows are rendered.\n");
	} else if (Options.shadowtransp) {
		fprintf(Stats.fstats,
			"Object opacity affects depth of shadowing.\n");
	}
	if (!Options.cache)
		fprintf(Stats.fstats,"Shadow caching is disabled.\n");
}

static void
usage()
{
	fprintf(stderr,"usage: %s [options] [filename]\n", Options.progname);
	fprintf(stderr,"Where options include:\n");
	fprintf(stderr,"\t-A thresh\t(Set adaptive ray tree cutoff value.)\n");
#ifdef URT
	fprintf(stderr,"\t-a \t\t(Toggle writing of alpha channel.)\n");
#endif
	fprintf(stderr,"\t-C cpp-args\t(Options to pass to C pre-processor.\n");
#ifdef URT
	fprintf(stderr,"\t-c \t\t(Continue interrupted rendering.)\n");
#endif
	fprintf(stderr,"\t-D depth\t(Set maximum ray tree depth.)\n");
	fprintf(stderr,"\t-E eye_sep\t(Set eye separation in stereo pairs.)\n");
#ifdef URT
	fprintf(stderr,"\t-e \t\t(Write exponential RLE file.)\n");
#endif
	fprintf(stderr,"\t-F freq\t\t(Set frequency of status report.)\n");
	fprintf(stderr,"\t-G gamma\t(Use given gamma correction exponent.)\n");
	fprintf(stderr,"\t-h \t\t(Print this message.)\n");
	fprintf(stderr,"\t-j \t\t(Antialias using jittered sampling.)\n");
	fprintf(stderr,"\t-l \t\t(Render image for left eye view.)\n");
	fprintf(stderr,"\t-n \t\t(Do not render shadows.)\n");
	fprintf(stderr,"\t-O outfile \t(Set output file name.)\n");
	fprintf(stderr,"\t-o \t\t(Object opacity affects shadowing.)\n");
	fprintf(stderr,"\t-P pixel_divs\t(Set max depth for supersampling.)\n");
	fprintf(stderr,"\t-p \t\t(Preview-quality rendering.)\n");
	fprintf(stderr,"\t-q \t\t(Run quietly.)\n");
	fprintf(stderr,"\t-R xres yres\t(Render at given resolution.)\n");
	fprintf(stderr,"\t-r \t\t(Render image for right eye view.)\n");
	fprintf(stderr,"\t-S samples\t(Use samples^2 jittered samples.)\n");
	fprintf(stderr,"\t-s \t\t(Don't cache shadowing information.)\n");
	fprintf(stderr,"\t-T r g b\t(Set contrast threshold (0. - 1.).)\n");
	fprintf(stderr,"\t-V filename \t(Write verbose output to filename.)\n");
	fprintf(stderr,"\t-v \t\t(Verbose output.)\n");
#ifdef URT
	fprintf(stderr,"\t-W x y x y \t(Render subwindow.)\n");
#endif
#ifdef LINDA
	fprintf(stderr,"\t-X workers\t(Number of workers.)\n");
	fprintf(stderr,"\t-w \t\t(Verbose worker output.)\n");
#endif
}
