#include <render/emitter.h>
#include "area.h"

PSDR_INACTIVE_CLASS(Emitter)

/* To let Enzyme differentiate the member functions in the derived class automatically,
we need to explicitly call these member functions of the derived class. */
#define PSDR_IMPLEMENT_EMITTER(...)                                                          \
    Spectrum Emitter::eval(const Intersection &its, const Vector &d) const                   \
    {                                                                                        \
        PSDR_MAP_STMT_F(eval(its, d), __VA_ARGS__);                                          \
        assert(false);                                                                       \
        return Spectrum();                                                                   \
    }                                                                                        \
    Float Emitter::pdf(const Intersection &its, const Vector &d) const                       \
    {                                                                                        \
        PSDR_MAP_STMT_F(pdf(its, d), __VA_ARGS__);                                           \
        assert(false);                                                                       \
        return 0.;                                                                           \
    }                                                                                        \
    Spectrum Emitter::eval(const Vector &norm, const Vector &d) const                        \
    {                                                                                        \
        PSDR_MAP_STMT_F(eval(norm, d), __VA_ARGS__);                                         \
        assert(false);                                                                       \
        return Spectrum();                                                                   \
    }                                                                                        \
    Float Emitter::evalDirection(const Vector &norm, const Vector &d) const                  \
    {                                                                                        \
        PSDR_MAP_STMT_F(evalDirection(norm, d), __VA_ARGS__);                                \
        assert(false);                                                                       \
        return 0;                                                                            \
    }                                                                                        \
    Float Emitter::sampleDirection(const Array2 &rnd, Vector &dir, Float *pdf) const         \
    {                                                                                        \
        PSDR_MAP_STMT_F(sampleDirection(rnd, dir, pdf), __VA_ARGS__);                        \
        assert(false);                                                                       \
        return 0;                                                                            \
    }                                                                                        \
    Spectrum Emitter::sampleDirect(const Vector2 &rnd, DirectSamplingRecord &dRec) const     \
    {                                                                                        \
        PSDR_MAP_STMT_F(sampleDirect(rnd, dRec), __VA_ARGS__);                               \
        assert(false);                                                                       \
        return Spectrum();                                                                   \
    }                                                                                        \
    Spectrum Emitter::samplePosition(const Vector2 &rnd, PositionSamplingRecord &pRec) const \
    {                                                                                        \
        PSDR_MAP_STMT_F(samplePosition(rnd, pRec), __VA_ARGS__);                             \
        assert(false);                                                                       \
        return Spectrum();                                                                   \
    }                                                                                        \
    Spectrum Emitter::getIntensity() const                                                   \
    {                                                                                        \
        PSDR_MAP_STMT_F(getIntensity(), __VA_ARGS__);                                        \
        assert(false);                                                                       \
        return Spectrum();                                                                   \
    }

//* insert an entry here when a new derived class is added
PSDR_IMPLEMENT_EMITTER(AreaLight)
/*
* for reference
Spectrum Emitter::eval(const Intersection &its, const Vector &d) const
{
    return static_cast<const AreaLight *>(this)->eval(its, d);
}
Spectrum Emitter::eval(const Vector &norm, const Vector &d) const
{
    return static_cast<const AreaLight *>(this)->eval(norm, d);
}
Float Emitter::evalDirection(const Vector &norm, const Vector &d) const
{
    return static_cast<const AreaLight *>(this)->evalDirection(norm, d);
}
Float Emitter::sampleDirection(const Array2 &rnd, Vector &dir, Float *pdf) const
{
    return static_cast<const AreaLight *>(this)->sampleDirection(rnd, dir, pdf);
}
Spectrum Emitter::sampleDirect(const Vector2 &rnd, DirectSamplingRecord &dRec) const
{
    return static_cast<const AreaLight *>(this)->sampleDirect(rnd, dRec);
}
Spectrum Emitter::samplePosition(const Vector2 &rnd, PositionSamplingRecord &pRec) const
{
    return static_cast<const AreaLight *>(this)->samplePosition(rnd, pRec);
}
Spectrum Emitter::getIntensity() const
{
    return static_cast<const AreaLight *>(this)->getIntensity();
}
*/