/* background_edf.c: edf for backgrounds */

/*********************************************************************/
/* WARNING!! unlike a normal EDF, all the HITREC here are NOT on the */
/*           lightsource, but on the TARGETTED area!!!               */
/*           This HITREC only has to contain a position! so that     */
/*           position dependend background radiation is possible.    */
/*********************************************************************/

#include "background_edf.h"

/* returns the emittance */
static COLOR BackgroundEdfEmittance(void *bkg, HITREC *hit , XXDFFLAGS )
{
  return(BackgroundPower((BACKGROUND *)bkg, hit ? &(hit->point) : NULL));
}

static int BackgroundEdfIsTextured(void *)
{
  return TRUE;
}

/* evaluates the edf */
static COLOR BackgroundEdfEval(void *bkg, HITREC *hit, VECTOR *out, XXDFFLAGS , double *pdf)
{
  float fpdf;
  COLOR result = BackgroundRadiance((BACKGROUND *)bkg, hit ? &(hit->point) : NULL, out, &fpdf);
  if(pdf) *pdf = fpdf;

  return(result);
}

/* samples the edf */
static VECTOR BackgroundEdfSample(void *bkg, HITREC *hit, XXDFFLAGS , double xi1, double xi2, COLOR *emitted_radiance, double *pdf)
{
  float fpdf;

  VECTOR result = BackgroundSample((BACKGROUND *)bkg, hit ? &(hit->point) : NULL, xi1, xi2, emitted_radiance, &fpdf);
  if(pdf) *pdf = fpdf;

  return(result);
}

/* Computes shading frame at hit point. Returns TRUE if succesful and
 * FALSE if not. X and Y may be null pointers. */
static int BackgroundEdfShadingFrame(void *, HITREC *, VECTOR *X, VECTOR *Y, VECTOR *Z)
{
  VECTORSET(*X, 1, 0, 0);
  VECTORSET(*Y, 0, 1, 0);
  VECTORSET(*Z, 0, 0, 1);
  return(TRUE);
}

/* prints the EDF data to the specified file */
static void BackgroundEdfPrint(FILE *, void *)
{
  // do nothing
}

/* creates a duplicate of the EDF data */
static void *BackgroundEdfDuplicate(void *data)
{
  return(data);
}

/* creates a EDF editor widget (included in the material editor implemented
 * in ui_material.c whenever appropriate). Returns the Widget, casted to a
 * void * in order not to have to include all X window header files. */
static void *BackgroundEdfCreateEditor(void *parent, void *data)
{
  // do nothing
  return NULL;
}

/* disposes of the EDF data */
static void BackgroundEdfDestroy(void *)
{
  // do nothing
}


static struct EDF_METHODS BackgroundEdfMethods = {
  (COLOR (*)(void *bkg, HITREC *hit, XXDFFLAGS flags))BackgroundEdfEmittance,
  (int (*)(void *bkg))BackgroundEdfIsTextured,
  (COLOR (*)(void *bkg, HITREC *hit, VECTOR *out, XXDFFLAGS flags, double *pdf))BackgroundEdfEval,
  (VECTOR (*)(void *bkg, HITREC *hit, XXDFFLAGS flags, double xi1, double xi2, COLOR *emitted_radiance, double *pdf))BackgroundEdfSample,
  (int (*)(void *bkg, HITREC *hit, VECTOR *X, VECTOR *Y, VECTOR *Z))BackgroundEdfShadingFrame,
  (void (*)(FILE *out, void *bkg))BackgroundEdfPrint,
  (void *(*)(void *bkg))BackgroundEdfDuplicate,
  (void *(*)(void *parent, void *bkg))BackgroundEdfCreateEditor,
  (void (*)(void *bkg))BackgroundEdfDestroy,
};

EDF *BackgroundEdfCreate(BACKGROUND *bkg)
{     
  return(EdfCreate(bkg, &BackgroundEdfMethods));
}
