/*
 * setup.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 "defaults.h"
#include "rayshade.h"
#include "libsurf/surface.h"
#include "libsurf/atmosphere.h"
#include "liblight/light.h"
#include "liblight/infinite.h"
#include "libobj/list.h"
#include "options.h"
#include "stats.h"
#include "viewing.h"
#include "picture.h"

#ifdef MULTIMAX
#include <parallel.h>
#define SHARED_BYTES	23	/* 2^23 bytes of shared memory */
#endif

extern ObjList *Defstack;

static void SetupWorld();

/*
 * Set default parameters
 */
void
setup()
{
	extern SurfList *CurSurf;
	extern Medium TopMedium;
	extern void NoiseInit();
#ifdef MULTIMAX
	unsigned int bytes;

	/*
	 * Initialize shared memory stuff.
	 */
	bytes = 1 << SHARED_BYTES;
	if (share_malloc_init(bytes) == -1) {
		RLerror(RL_PANIC, "Cannot share_malloc %d bytes.\n",bytes);
	} else
		fprintf(fstats,"Malloced %d bytes of shared memory.\n",
				bytes);
#endif

	Camera.hfov = HFOV;
	Camera.vfov = UNSET;
	Camera.pos.x = EYEX;
	Camera.pos.y = EYEY;
	Camera.pos.z = EYEZ;
	Camera.lookp.x = LOOKX;
	Camera.lookp.y = LOOKY;
	Camera.lookp.z = LOOKZ;
	Camera.up.x = UPX;
	Camera.up.y = UPY;
	Camera.up.z = UPZ;
	Camera.focaldist = UNSET;
	Camera.aperture = 0.;

	Screen.xres = Screen.yres = UNSET;
	Screen.minx = Screen.miny = Screen.maxx = Screen.maxy = UNSET;

	Options.maxdepth = MAXDEPTH;
	Options.report_freq = REPORTFREQ;
	Options.pixel_div = UNSET;
	Options.jit_samples = UNSET;
	Options.contrast.r = UNSET;
	Options.cutoff = UNSET;
	Options.cache = TRUE;
	Options.shadowtransp = FALSE;
	Stats.fstats = stderr;
	Options.pictfile = stdout;
#ifdef URT
	Options.alpha = TRUE;
	Options.exp_output = FALSE;
#endif
	Options.gamma = GAMMA;
	Options.eyesep = UNSET;
#ifdef LINDA
	Options.workers = WORKERS;
#endif

	TopMedium.index = DEFAULT_INDEX;
	NoiseInit();			/* Initialize values for Noise() */

	/*
	 * Top of object definition stack points to the World object.
	 * The World object is always a list.
	 */
	Defstack = ObjStackPush(ObjListCreate(), (ObjList *)NULL);
	Defstack->obj->name = strsave("World");
	/* Initialize surface stack */
	CurSurf = SurfPush((Surface *)NULL, (SurfList *)NULL);
}

/*
 * cleanup()
 *
 * Initialize options/variables not set on command line or in input file.
 * Perform sanity checks on widow dimension, maxdepth, etc.
 */
void
cleanup()
{
	extern Light *Lights;
	extern void OpenStatsFile();
	extern FILE *yyin;

	yyin = (FILE *)NULL;	/* mark that we're done reading input */

	WorldSetup();

	OpenStatsFile();

	ViewingSetup();

	if (!Options.jittered && Options.pixel_div == UNSET)
		Options.pixel_div = PIXEL_DIV;

	if (Options.jit_samples == UNSET)
		Options.jit_samples = DEFJITSAMPLES;

	if (!Options.jittered && Options.jit_samples < 0) {
		RLerror(RL_PANIC, "Samples value must be at least 1.\n");
	}

	if (Options.cutoff == UNSET)
		Options.cutoff = DEFCUTOFF;

	/*
	 * Set contrast.
	 */
	if (Options.contrast.r == UNSET) {
		Options.contrast.r = DEFREDCONT;
		Options.contrast.g = DEFGREENCONT;
		Options.contrast.b = DEFBLUECONT;
	}

	/*
	 * Image gamma is inverse of display gamma.
	 */
	if (fabs(Options.gamma) > EPSILON)
		Options.gamma = 1. / Options.gamma;
	else
		Options.gamma = FAR_AWAY;

	if (Options.maxdepth < 0)
		Options.maxdepth = 0;

	/*
	 * Set sampling options.
	 */
	SamplingSetOptions(Options.jit_samples);

	LightSetup();
}
