/* basis.h: datastructures and routines related to basis functions */

#ifndef _BASIS_H_
#define _BASIS_H_

#include "patch.h"

/* no basis consists of more than BASISMAXSIZE functions */
#define BASISMAXSIZE 10

typedef struct BASIS {
/* for debugging purposes */
	char	*description;	

/* some general basis related stuff */
	int size;	/* number of basis functions */
	int orthogonal;	/* TRUE of FALSE wether the basis is an orthogonal basis or not */

	/* function[alpha](u,v) evaluates phi_\alpha at (u,v) */
	double (*function[BASISMAXSIZE])(double u, double v);
	/* norm[alpha](patch) computes the norm of phi_\alpha on
	 * the patch */
	double (*norm[BASISMAXSIZE])(struct PATCH *patch);	
	/* overlap[alpha][beta](P) computes the overlap of basisfunctions phi_\alpha
	 * and phi_\beta on the patch P (overlap = integral over the patch of the product) */
	double (*overlap[BASISMAXSIZE][BASISMAXSIZE])(struct PATCH *patch);
	/* inverse of the basisfunctions overlap matrix on the standard domain, divide
	 * by th area to get the inverse of the overlap matrix on any regular patch --
	 * coefficients are stored by rows left to right top to bottom (the usual
	 * practice in C). */
	Float	standard_inverse_overlap[BASISMAXSIZE*BASISMAXSIZE];

/* routines to set/add a constant radiance ... to a patch */
	void (*SetConstant)(COLOR *coeff, COLOR *color);
	void (*AddConstant)(COLOR *coeff, COLOR *color);

/* routines to retrieve the radiance,power,importance... of a patch */
	COLOR (*GetValueAtVertex)(COLOR *coeff, int whichvertex);
	COLOR (*GetValueAtPoint)(COLOR *coeff, double u, double v);
	COLOR (*GetPower)(struct PATCH *patch);
	COLOR (*GetUnshotPower)(struct PATCH *patch);
	COLOR (*GetImportance)(struct PATCH *patch);
	COLOR (*GetUnshotImportance)(struct PATCH *patch);

/* routines to maintain the hierarchical representation of radiance,... */
	/* pushes radiance, unshot radiance, importance and unshot importance
	 * down one level from a patch to its subpatches, called when refining 
	 * a patch (PatchRefine() in patch.c) */
	void (*PushRadianceImportance)(struct PATCH *patch);
	/* Makes sure that the representation of radiance/importance is
	 * consistent over all levels in the patch hierarchy */
	void (*GatherPushPullRadiance)(struct PATCH *patch);	/* gathering */
	void (*GatherPushPullImportance)(struct PATCH *patch);
	void (*ShootPushPullRadiance)(struct PATCH *patch);	/* shooting */
	void (*ShootPushPullImportance)(struct PATCH *patch);
	/* update the radiances at each level of the hierarchy after
	 * a change in emissivity or reflectivity */
	void (*PushPullEmissivityChange)(struct PATCH *patch, COLOR delrad);
	void (*PushPullReflectivityChange)(struct PATCH *patch, COLOR delrho);
} BASIS;

extern BASIS *quadBasis, *triBasis;	/* the basis that is currently being used for
					 * quadrilaterals and for triangles */

/* Sets the current basis */
extern void SetBasis(BASIS *quadbasis, BASIS *tribasis);

/* the available basis sets are declared in bases.h, a separate header
 * file since only very few source files depend on it, unlike this
 * header file. */

#endif /* _BASIS_H_ */
