// -*- C++ -*-
#ifndef RIRADFLATHIERARCHY_H
#define RIRADFLATHIERARCHY_H
/* Copyright 1996 
 * Mon Jul 28 10:37:58 1997  Brian Smits  (bes@phoenix.cs.utah.edu)
 * 
 * RiRadFlatHierarchy.H
 * 
 *	
 * 
 * $Id: RiRadFlatHierarchy.H,v 1.2 1998/10/02 16:48:14 bes Exp $ 
 * 
 */
#ifndef RICOMMON_H
#include <RiCommon.H>
#endif

#ifndef RIRADOBJECT_H
#include <RiRadObject.H>
#endif


/***************************************************************
CLASS
    RiRadFlatHierarchyBuilder
     <one line summary> 

DESCRIPTION
     <Detailed description with any warnings>

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

class RiRadFlatHierarchyBuilder : public RiRadHierarchyBuilder {
  public:
				// GROUP: Constructors and assignment
				//// Default Constructor
    RiRadFlatHierarchyBuilder();
				//// Destructor
    virtual ~RiRadFlatHierarchyBuilder();
				// GROUP: Members
				//// Add an object to the future accelerator
    virtual void 	 AddObject(RiRadObject *);
				//// Build the RiRadObject and return it.
				// Each call to Build will build and return the next object.
    virtual RiRadObject *Build();
				//// Some situations result in a RiRadObjectBuilder
				// building more than a single object.  As long as IsDone
				// returns false, there are more objects that need to be built
    virtual bool	 IsDone();
  private:
				////Copy Constructor (Unimplemented)
    RiRadFlatHierarchyBuilder(const RiRadFlatHierarchyBuilder &);
				//// Assignment (Unimplemented)
    RiRadFlatHierarchyBuilder &operator=(const RiRadFlatHierarchyBuilder &);
};


/***************************************************************
CLASS
    RiRadFlatHierarchy
     <one line summary> 

DESCRIPTION
     <Detailed description with any warnings>

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

class RiRadFlatHierarchy : public RiRadObject {
    friend class RiRadFlatHierarchyBuilder;
  public:
				// GROUP: Constructors and assignment
				//// Default Constructor
    RiRadFlatHierarchy();
				// GROUP: Members
				//// Fills in the data in sample, and returns the Area Weight
				//   for the sample (area of the object.
    virtual RiReal GetSample(RiRadRegion &sample, const RiVector2 &uv);
				//// Fills in the data in sample, and returns the Form Factor weight
				//   for the sample to the interestedSample.  interestedSample is used to 
				//   direct the object so that it will hopefully pick a point visible to
				//   the intersted point, reducing variance.
    virtual RiReal GetFormFactorSample(RiRadRegion &sample, const RiMaterialRegion &interestedSample,
				       const RiVector2 &uv);
				//// Get the Rad Data from the object
    virtual RiRadData  *GetRadData();
				//// Get a convex hull containing the object
    virtual RiConvexHull GetConvexHull();
				//// Can the object see the convex hull.  Note that this operation ONLY
				//   involves the object and the hull, not the environment.  This is
				//   the equivalent of back face culling.
    virtual bool	 IsVisible(const RiConvexHull &hull);
				//// Compute transfer data for links and lighting
    virtual void	 ComputeTransfer(const RiMaterialRegion &sample, RiTransferData &data);
				// GROUP: Structural
				//// Determine the number of children this object has. (0 if no
				//     subdivision has been done	
    virtual int		 GetNumChildren();
				//// Get the ith child (i MUST be less than GetNumChildren)
    virtual RiRadObject *GetChild(int i);
				//// Subdivide if possible.  If already subdivided, do nothing. Return
				//  true if subdividable.
    virtual bool	 Subdivide();
				//// Compute the surface area (or a good estimate of it) of the object
    virtual RiReal	 GetArea();
//  protected:
				//// Add an object to the list.
    void AddObject(RiRadObject *obj);
    void DoneBuilding();
  private:
    class ObjNode {
      public:
	RiReal       area;
	RiRadObject *obj;
	bool operator==(const ObjNode &n) const {return obj == n.obj;}
    };
    RWTValOrderedVector<ObjNode>  objList;
    RiReal 			  totalArea;
    RiRadData			  data;
};



#endif /* RIRADFLATHIERARCHY_H */

