/* rendercommon.c: rendering stuff independent of the graphics library being used. */

#include "render.h"
#include "bounds.h"
#include "vector.h"
#include "camera.h"
#include "error.h"
#include "Boolean.h"
#include "color.h"

#ifndef DEFAULT_GAMMA
#define DEFAULT_GAMMA 1.0
#endif

RENDEROPTIONS renderopts = {
    FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, BC_ON,
    RED, YELLOW, BLACK, DEFAULT_GAMMA,
    0.
};

void RenderSetSmoothShading(char yesno)
{
  renderopts.smooth_shading = yesno;
}

void RenderSetBackfaceCulling(BACKFACECULLINGMODE mode)
{
  renderopts.backface_culling = mode;
}

void RenderSetOutlineDrawing(char draw_outlines)
{
  renderopts.draw_outlines = draw_outlines;
}

void RenderSetBoundingBoxDrawing(char yesno)
{
  renderopts.draw_bounding_boxes = yesno;
}

void RenderSetClusterDrawing(char yesno)
{
  renderopts.draw_clusters = yesno;
}

void RenderUseDisplayLists(char truefalse)
{
  renderopts.use_display_lists = truefalse;
}

void RenderSetOutlineColor(RGB *outline_color)
{
  renderopts.outline_color = *outline_color;
}

void RenderSetBoundingBoxColor(RGB *outline_color)
{
  renderopts.bounding_box_color = *outline_color;
}

void RenderSetClusterColor(RGB *cluster_color)
{
  renderopts.cluster_color = *cluster_color;
}

void RenderSetGamma(float gamma)
{
  renderopts.gamma = gamma;
}

static BOUNDINGBOX worldbounds = {-10., -10., -10, 10., 10., 10.};
void RenderSetBoundingBox(float *bounds)
{
  BoundsCopy(bounds, worldbounds);
}

/* computes distance to front- and backclipping plane */
void RenderGetNearFar(float *near, float *far)
{
  VECTOR b[2], d;
  int i, j, k;
  float z;

  b[0] = *(VECTOR *)&worldbounds[MIN_X];
  b[1] = *(VECTOR *)&worldbounds[MAX_X];
  
  *far = -HUGE; *near = HUGE;
  for (i=0; i<=1; i++)
    for (j=0; j<=1; j++)
      for (k=0; k<=1; k++) {
	VECTORSET(d, b[i].x, b[j].y, b[k].z);
	VECTORSUBTRACT(d, Camera.eyep, d);
	z = VECTORDOTPRODUCT(d, Camera.Z);
	
	if (z > *far) *far = z;
	if (z < *near) *near = z;
      }

  /* take 2% extra distance for near as well as far clipping plane */
  *far += 0.02 * (*far); *near -= 0.02 * (*near);
  if (*far < EPSILON) *far = Camera.viewdist;
  if (*near < EPSILON) *near = Camera.viewdist/100.;
}

#ifdef NEVER
void RenderBounds(BOUNDINGBOX bounds)
{
  POINT p[8];

  VECTORSET(p[0], bounds[MIN_X], bounds[MIN_Y], bounds[MIN_Z]);
  VECTORSET(p[1], bounds[MAX_X], bounds[MIN_Y], bounds[MIN_Z]);
  VECTORSET(p[2], bounds[MIN_X], bounds[MAX_Y], bounds[MIN_Z]);
  VECTORSET(p[3], bounds[MAX_X], bounds[MAX_Y], bounds[MIN_Z]);
  VECTORSET(p[4], bounds[MIN_X], bounds[MIN_Y], bounds[MAX_Z]);
  VECTORSET(p[5], bounds[MAX_X], bounds[MIN_Y], bounds[MAX_Z]);
  VECTORSET(p[6], bounds[MIN_X], bounds[MAX_Y], bounds[MAX_Z]);
  VECTORSET(p[7], bounds[MAX_X], bounds[MAX_Y], bounds[MAX_Z]);

  RenderLine(&p[0], &p[1]);
  RenderLine(&p[1], &p[3]);
  RenderLine(&p[3], &p[2]);
  RenderLine(&p[2], &p[0]);
  RenderLine(&p[4], &p[5]);
  RenderLine(&p[5], &p[7]);
  RenderLine(&p[7], &p[6]);
  RenderLine(&p[6], &p[4]);
  RenderLine(&p[0], &p[4]);
  RenderLine(&p[1], &p[5]);
  RenderLine(&p[2], &p[6]);
  RenderLine(&p[3], &p[7]);
}
#endif

