
#ifndef RIMATERIAL_H
#define RIMATERIAL_H
/* Copyright 1996 
 * Wed May 14 15:28:43 1997  Brian Edward Smits  (bes@phoenix.cs.utah.edu)
 * 
 * RiMaterial.H
 * 
 *	
 * 
 * $Id: RiMaterial.H,v 1.7 1999/10/01 18:24:07 bes Exp $ 
 * 
 */
#ifndef RICOMMON_H
#include <RiCommon.H>
#endif

#ifndef RIVECTOR3_H
#include <RiVector3.H>
#endif

#ifndef RIVECTOR2_H
#include <RiVector2.H>
#endif

#ifndef RIMATERIALSAMPLE_H
#include <RiMaterialSample.H>
#endif

#ifndef RIMEDIA_H
#include <RiMedia.H>
#endif


#define RI_MATERIAL_POOL  512

/***************************************************************
CLASS
    RiMaterialRegion
     Data needed by the RiMaterial in order to create an RiBRDF.

DESCRIPTION
     This is the data the the RiMaterial uses to create an RiBRDF.  The
     RiMaterial includes all texture mapping, and the RiMaterialRegion holds the
     alterered texture-mapped data as the RiBRDF is being created.

****************************************************************/

class RiMaterialRegion {
  public:
    // GROUP: Constructors and assignment
    //// Default Constructor
    RiMaterialRegion();
    // GROUP: Accessors
				////
    const RiUnitVector3 	  &GetIncomingDirection() const;
				////
    void	  SetIncomingDirection(const RiUnitVector3 &);
				////
				////
    const RiVector3 	  &GetPoint() const;
				////
    void	  SetPoint(const RiVector3 &);
				////
    const RiVector2 	  &GetUV() const;
				////
    void	  SetUV(const RiVector2 &);
				////
    const RiUnitVector3   &GetNormal() const;
				////
    void	  SetNormal(const RiUnitVector3 &);
				////
    RiReal        GetRadius() const;
				////
    void 	  SetRadius(RiReal);
				////
    void	 *New(size_t size);
  private:
    RiVector3  	  pnt;
    RiVector2	  uv;
    RiUnitVector3 normal;
    RiUnitVector3 incoming;
    RiReal 	  radius;
    char          memPool[RI_MATERIAL_POOL];
    char	 *head;
};


/***************************************************************
CLASS
    RiMaterialSamplePointer
    Smart pointer to make garbage collection easier.

DESCRIPTION
    The responsibility for deleting the RiMaterialSample falls to the Shader,
    a routine with many early exit points.  This class encapsulates that
    responsibility, acting just like a pointer, but deleting the RiMaterialSample
    when it's destructor is called.  The user need not worry about memory leaks.
    This class transfers ownership when copied (using the copy constructor). This means
    that after passing by value, the original will contain NULL.
    
****************************************************************/

class RiMaterialSamplePointer {
  public:
    // GROUP: Constructors and assignment
    //// Default Constructor
    RiMaterialSamplePointer(RiMaterialSample *sample) {samp = sample;}
    ////Copy Constructor (transfers ownership to the copy)
    RiMaterialSamplePointer(RiMaterialSamplePointer &rhs) {samp = rhs.samp; rhs.samp = NULL;}
    //// Destructor
    ~RiMaterialSamplePointer() {delete samp;}
    // GROUP: Accessors
    ////
    RiMaterialSample *operator->() const {assert(samp != NULL); return samp;}
  private:
    //// Assignment
    RiMaterialSamplePointer &operator=(const RiMaterialSamplePointer &);

    RiMaterialSample *samp;
};




/***************************************************************
CLASS
    RiMaterial
     Describes the scattering characteristics of an object.

DESCRIPTION
     Description of the scattering characteristics of an object (as
     opposed to the scattering and emission characteristics of an point which is given by
     a RiMaterialSample.  The material must return a RiMaterialSample when given an RiRayHit

****************************************************************/

class RiMaterial {
  public:
    //// Destructor (It's for the children, dear)
    virtual ~RiMaterial() {}
    // GROUP: Members
    //// Evaluate all textures and compute a BRDF for the Shader to use.
    //   User is responsible for deleting the resulting BRDF.
    virtual RiMaterialSamplePointer  GetSample(RiMaterialRegion &) = 0;
    //// Returns true if material emits light
    virtual bool IsLuminaire() const;
				////
    static void SetWorldMedia(RiMedia *media);
				////
    static RiMedia *GetWorldMedia();
  private:
    static RiMedia *worldMedia;
};



#endif /* RIMATERIAL_H */

