#pragma once
#ifndef BSDF_DIFFUSE_H__
#define BSDF_DIFFUSE_H__

#include <render/bsdf.h>
#include <core/ptr.h>
#include <render/bitmap.h>
struct SpatialVertex;

struct DiffuseBSDF : BSDF
{
    DiffuseBSDF() {}
    DiffuseBSDF(const Spectrum &reflectance) : reflectance(reflectance) {}

    BSDF *clone() const override
    {
        return new DiffuseBSDF(*this);
    }
    void merge(BSDF *bsdf) override
    {
        DiffuseBSDF *diffuse = dynamic_cast<DiffuseBSDF *>(bsdf);
        reflectance += diffuse->reflectance;
    }

    void setZero() override
    {
        reflectance.setZero();
    }

    Spectrum eval(const Intersection &its, const Vector &wo,
                  EBSDFMode mode = EBSDFMode::ERadiance) const;

    Spectrum sample(const Intersection &its, const Array3 &rnd, Vector &wo,
                    Float &pdf, Float &eta,
                    EBSDFMode mode = EBSDFMode::ERadiance) const;
                    
    void sampleDual(const Intersection &its, const Array3 &sample,
                    Vector &wo, Vector &woDual, Float &pdf, Float &pdfDual, Float &eta, Float &etaDual, Spectrum &ret, Spectrum &retDual,
                    EBSDFMode mode = EBSDFMode::ERadiance) const {assert(false);}

    Float pdf(const Intersection &its, const Vector &wo) const;
    inline bool isTransmissive() const { return false; }

    inline bool isTwosided() const { return false; }

    inline bool isNull() const { return false; }

    inline bool isConductor() const { return false; }

    std::string toString() const override
    {
        std::ostringstream oss;
        oss << "BSDF_diffuse [" << std::endl
            << "  reflectance = "
            << reflectance.toString()
            << std::endl
            << "]" << std::endl;
        return oss.str();
    }

    std::unordered_map<std::string, ParamType> toMap() const override
    {
        return {{"reflectance", &(reflectance.m_data)}};
    }

    Bitmap reflectance;

    DECLEAR_BSDF_HELPER_FUNCTIONS()
    PSDR_DECLARE_CLASS(DiffuseBSDF)
    PSDR_IMPLEMENT_VIRTUAL_CLASS(DiffuseBSDF)
};

#endif