// -*- C++ -*-
#ifndef RIRAYSHADESTRATEGY_H
#define RIRAYSHADESTRATEGY_H
/* Copyright 1998 
 * Mon Dec  7 14:48:16 1998  Brian Smits  (bes@phoenix.cs.utah.edu)
 * 
 * RiRayShadeStrategy.H
 * 
 *	
 * 
 * $Id: RiRayShadeStrategy.H,v 1.2 1999/10/01 18:26:29 bes Exp $ 
 * 
 */
#ifndef RICOMMON_H
#include <RiCommon.H>
#endif

#ifndef RIMATERIAL_H
#include <RiMaterial.H>
#endif

#ifndef RILIGHTOBJECT_H
#include <RiLightObject.H>
#endif

#ifndef RIRAYOBJECT_H
#include <RiRayObject.H>
#endif

#ifndef RISAMPLEPATTERN_H
#include <RiSamplePattern.H>
#endif



#include <rw/tvordvec.h>


class RiRayShader;
class RiRayShadeData {
  public:
    RiRayShadeData(RiRay3 &ray, RiRayHit &hit, Ri2DSamplePatternIterator &samps,
			       RiMaterialSamplePointer &brdf, RiMedia *media, RiRayShader *sh, int td);
    RiRayHit  			&hit;
    Ri2DSamplePatternIterator   &samps;
    RiMaterialSamplePointer 	&brdf;
    RiRayShader			*shader;
    int				 treeDepth;
    RiRay3			&ray;
    RiMedia			*media;
};


/***************************************************************
CLASS
    RiRayShadeStrategy
     Default strategy, do nothing

DESCRIPTION
     Returns the zero spectrum.

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

class RiRayShadeStrategy {
    public:
				//// Default implementation is to return 0
    virtual RiSpectrum GetRad(RiRayShadeData *d);
};

/***************************************************************
CLASS
    RiRayShadeEmission
     Returns the emission based on BRDF

DESCRIPTION
     Gets the emitted radiance in the direction of the viewer.

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

class RiRayShadeEmission : public RiRayShadeStrategy {
  public:
				////  Default implementation is to return the emission
				// of the BRDF in the incident direction.
    virtual RiSpectrum GetRad(RiRayShadeData *d);
};


/***************************************************************
CLASS
    RiRayShadeDirectLighting
     Do direct lighting

DESCRIPTION
     Computes direct lighting with shadows from every light.

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

class RiRayShadeDirectLighting : public RiRayShadeStrategy {
  public:
				//// Direct lighting with shadows
    virtual RiSpectrum GetRad(RiRayShadeData *d);
				////
    void    AddLight(RiLightObject *lt);
				////
    int	    GetNumLights();
  protected:
				////
    RWTValOrderedVector<RiLightObject *> lights;
};

/***************************************************************
CLASS
    RiRayShadeTermination
     What to return when the ray is at it's maximum depth

DESCRIPTION
     Returns the value of the background (in the direction the ray came from)
****************************************************************/

class RiRayShadeTermination : public RiRayShadeStrategy {
  public:
				//// No more ray bounces allowed, return something
    virtual RiSpectrum GetRad(RiRayShadeData *d);
};

/***************************************************************
CLASS
    RiRayShadeSecondary
     Determine indirect illumination at this point

DESCRIPTION
     Determines indirect illumination by casting a random ray over the hemisphere

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

class RiRayShadeSecondary : public RiRayShadeStrategy {
  public:
				////  Set corl to false for brute force path tracing
    RiRayShadeSecondary(bool corl = true);
				//// Shoot a single random ray, and shade it.
    virtual RiSpectrum GetRad(RiRayShadeData *d);
  private:
				////
    bool corl;
};

/***************************************************************
CLASS
    RiRayShadeSpecular
     Do specular component

DESCRIPTION
     Do specular rays (both transmitted and reflected)

WARNINGS
     Currently only does reflected
****************************************************************/

class RiRayShadeSpecular : public RiRayShadeStrategy {
  public:
				//// Shoot a reflected ray and shade it
    virtual RiSpectrum GetRad(RiRayShadeData *d);
};



/**********************************************************
// Misc derived classes
// 
// ********************************************************/

/***************************************************************
CLASS
    RiRayShadeBlurDirect
     Blurs direct illumination a fixed amount

DESCRIPTION
     Currently only blurs on the xy (or xz..) plane by displacing the hit point a small amount.

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

class RiRayShadeBlurDirect :public RiRayShadeDirectLighting {
  public:
    //// Default Constructor
    RiRayShadeBlurDirect(RiRayShadeStrategy *direct, RiReal perturbDistance);
	//// Blur the shadow
    virtual RiSpectrum GetRad(RiRayShadeData *d);
  private:
				////
    RiReal purturb;
				////
    RiRayShadeStrategy	*direct;
};

/***************************************************************
CLASS
    RiRayShadeNoDirect
     Eliminate direct lighting until some number of bounces have been taken.

DESCRIPTION
     Start doing direct lighting at startDirect bounces.  This means indirect only
     at 1.

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

class RiRayShadeNoDirect : public RiRayShadeDirectLighting {
  public:
				////
    RiRayShadeNoDirect(RiRayShadeStrategy *direct, int startDirect = 1);
				////
    virtual RiSpectrum GetRad(RiRayShadeData *d);
  private:
				////
    int	startDirect;
				////
    RiRayShadeStrategy	*direct;
};

/***************************************************************
CLASS
    RiRayShadeNoShadows
     Direct lighting without shadows

DESCRIPTION
     Direct lighting without any shadows

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

class RiRayShadeNoShadows : public RiRayShadeDirectLighting {
  public:
				////
    virtual RiSpectrum GetRad(RiRayShadeData *d);
};



#endif /* RIRAYSHADESTRATEGY_H */

