#pragma once
#ifndef EMITTER_H__
#define EMITTER_H__

#include <core/fwd.h>
#include <core/ptr.h>
#include <render/shape.h>

struct Intersection;

enum EEmitter
{
    EAreaLight = 0,
    EPoint,
    EAll
};

struct Emitter : Object
{
    Emitter() : shape_id(-1) {}
    Emitter(int shape_id) : shape_id(shape_id) {}
    virtual ~Emitter() {}
    virtual Emitter *clone() const = 0;
    virtual void merge(Emitter *emitter) = 0;
    virtual void setZero() = 0;
    
    Spectrum eval(const Intersection &its, const Vector &d) const;
    Spectrum eval(const Vector &norm, const Vector &d) const;
    Float evalDirection(const Vector &norm, const Vector &d) const;
    Float sampleDirection(const Array2 &rnd, Vector &dir, Float *pdf = nullptr) const;
    Float pdf(const Intersection &its, const Vector &d) const;
    Spectrum sampleDirect(const Vector2 &rnd, DirectSamplingRecord &dRec) const;
    Spectrum getIntensity() const;
    Spectrum samplePosition(const Vector2 &rnd, PositionSamplingRecord &pRec) const;

    inline int getShapeID() const { return shape_id; }

    virtual std::string toString() const
    {
        std::ostringstream oss;
        oss << "Emitter [ ]" << std::endl;
        return oss.str();
    }

    PSDR_DECLARE_VIRTUAL_CLASS()

    int shape_id;
    mutable const Shape *shape_ptr;
    
    PSDR_DECLARE_CLASS(Emitter)
};
#endif //EMITTER_H__
