// PhBAppearance.H: PhBAppearance nodes.

// This file has been generated using nodegen 0.5a.
// Restrict manual editing to the sections delimited by
// . the comments "utility includes" and "end of utility includes"
// . the comments "utility members" and "end of utility members"

#ifndef _PhBAppearance_H_
#define _PhBAppearance_H_

#include "xrml.H"
#include "AppearanceBase.H"
#include "PhBSurface.H"
#include "PhBMedium.H"
#include "PhBDistortion.H"
#include "PhBTextureProjection.H"
#include "TextureTransform.H"
#include "PhB3DTextureTransform.H"

// utility includes
#include "texture_projection.H"
// end of utility includes

namespace xrml {
#define PhBAppearanceTypeId 	"PhBAppearance"
extern bool IsPhBAppearance(SFNode*);

class PhBAppearance: public virtual SFNode, public AppearanceBase {
private:
  //
  void clone_here(const PhBAppearance&);
  void destruct(void);
  
  // field/eventOut update status bits
  // Use xxx_is_updated() and xxx_clear_update() to inspect/reset.
  enum status_bits {
    surface_updated = 0x1,
    medium_updated = 0x2,
    bumpMap_updated = 0x4,
    displacementMap_updated = 0x8,
    textureProjection_updated = 0x10,
    textureTransform_updated = 0x20,
    textureTransform3D_updated = 0x40 
  };
  
protected:
  // raw children nodes (can be PROTO) + synchronize methods:
  SFNode* 	_surface;
  void 	synchronize_surface(void);
  SFNode* 	_medium;
  void 	synchronize_medium(void);
  SFNode* 	_bumpMap;
  void 	synchronize_bumpMap(void);
  SFNode* 	_displacementMap;
  void 	synchronize_displacementMap(void);
  SFNode* 	_textureProjection;
  void 	synchronize_textureProjection(void);
  SFNode* 	_textureTransform;
  void 	synchronize_textureTransform(void);
  SFNode* 	_textureTransform3D;
  void 	synchronize_textureTransform3D(void);

public:
  //
  int major_version(void), minor_version(void);
  bool is_leaf_class(void);
  
  PhBAppearance();
  PhBAppearance(const PhBAppearance&);
  PhBAppearance& operator=(const PhBAppearance&);
  virtual ~PhBAppearance();
  
  //
  SFNode*          	instantiate(Proto * =0);
  void             	render(void);
  
  // state values:
  // Do not assign directly unless you know very well what you are doing.
  PhBSurface*      	surface;
  PhBMedium*       	medium;
  PhBDistortion*   	bumpMap;
  PhBDistortion*   	displacementMap;
  PhBTextureProjection* 	textureProjection;
  TextureTransform* 	textureTransform;
  PhB3DTextureTransform* 	textureTransform3D;
  
  // set_<exposedField> eventIns: with forwarding and eventOut generation
  void             	set_surface(SFNode*);
  void             	set_medium(SFNode*);
  void             	set_bumpMap(SFNode*);
  void             	set_displacementMap(SFNode*);
  void             	set_textureProjection(SFNode*);
  void             	set_textureTransform(SFNode*);
  void             	set_textureTransform3D(SFNode*);
  
  // field assignement: no forwarding or eventOut generation!
  bool             	assign_surface(SFNode*);
  bool             	assign_medium(SFNode*);
  bool             	assign_bumpMap(SFNode*);
  bool             	assign_displacementMap(SFNode*);
  bool             	assign_textureProjection(SFNode*);
  bool             	assign_textureTransform(SFNode*);
  bool             	assign_textureTransform3D(SFNode*);
  
  // update status
  inline bool      	surface_is_updated(void) { return (status & surface_updated); }
  inline void      	surface_clear_update(void) { status &= ~surface_updated; }
  inline bool      	medium_is_updated(void) { return (status & medium_updated); }
  inline void      	medium_clear_update(void) { status &= ~medium_updated; }
  inline bool      	bumpMap_is_updated(void) { return (status & bumpMap_updated); }
  inline void      	bumpMap_clear_update(void) { status &= ~bumpMap_updated; }
  inline bool      	displacementMap_is_updated(void) { return (status & displacementMap_updated); }
  inline void      	displacementMap_clear_update(void) { status &= ~displacementMap_updated; }
  inline bool      	textureProjection_is_updated(void) { return (status & textureProjection_updated); }
  inline void      	textureProjection_clear_update(void) { status &= ~textureProjection_updated; }
  inline bool      	textureTransform_is_updated(void) { return (status & textureTransform_updated); }
  inline void      	textureTransform_clear_update(void) { status &= ~textureTransform_updated; }
  inline bool      	textureTransform3D_is_updated(void) { return (status & textureTransform3D_updated); }
  inline void      	textureTransform3D_clear_update(void) { status &= ~textureTransform3D_updated; }
  
  // utility members
  void    	begin_render(void);
  void    	end_render(void);

  complex get_indexOfRefraction(void);

  bool isLightSource(void);

  bool isScatterer(void);

  bool isTextured(void);

  class phbcontext *initquery(const Mat4 *world2object,// world to object transform, or null
			      const Mat4 *object2world,// object to world transform, or null
			      const Vec3& point, // query point (world co's if world2object 
			                         // is not null), object co's otherwise.
			      const Vec3& gnorm, // geom. normal
			      const complex& indexOut, // refractive index of
			                         // medium outside surface
			      texture_projection *default_projection);
                              // default texture projection (can be null)

  void endquery(class phbcontext* ctx);

  Spectrum evaluateEDF(class phbcontext* ctx,
		       const Vec3& direction,
		       const Spectrum& specWeight,
		       int range,
		       float *pdf);

  Vec3 sampleEDF(class phbcontext* ctx,
		 const Spectrum& specWeight,
		 float xi1, float xi2,
		 int range,
		 Spectrum *value, float *pdf);

  Spectrum emittance(class phbcontext* ctx, int range);

  Spectrum evaluateBSDF(class phbcontext* ctx,
			const Vec3& inDir,
			const Vec3& outDir,
			const Spectrum& inSpec,
			int modes,
			float *pdf);

  Vec3 sampleBSDF(class phbcontext* ctx,
		  const Vec3& inDir,
		  const Spectrum& inSpec,
		  float xi1, float xi2,
		  int modes,
		  Spectrum *value, float *pdf);



  Spectrum albedo(class phbcontext* ctx,
		  const Vec3& inDir,
		  int modes);

  Mat3& get_shadingframe(class phbcontext* ctx);
  
protected:
  inline void util_init(void) { }
  inline void util_clone(const PhBAppearance& src) { }
  inline void util_destruct(void) { }
};

// end of utility members
} // namespace xrml
#endif /*_PhBAppearance_H_*/
