#pragma once
#include <render/bsdf.h>
#include "microfacet.h"
#include <core/ptr.h>

struct RoughDielectricBSDF : BSDF
{
    BSDF *clone() const override;
    void merge(BSDF *bsdf) override
    {
        RoughDielectricBSDF *_bsdf = dynamic_cast<RoughDielectricBSDF *>(bsdf);
        m_eta += _bsdf->m_eta;
        m_distr.m_alpha += _bsdf->m_distr.m_alpha;
    }

    void setZero() override
    {
        m_distr.setZero();
        m_eta = 0;
    }

    inline RoughDielectricBSDF(Float alpha, Float intIOR, Float extIOR) : m_distr(alpha)
    {
        m_eta = intIOR / extIOR;
        m_invEta = 1.0f / m_eta;
    }

    inline RoughDielectricBSDF(Float alpha, Float intIOR, Float extIOR,
                               Spectrum specularReflectance, Spectrum specularTransmittance)
        : m_distr(alpha),
          m_specularReflectance(specularReflectance),
          m_specularTransmittance(specularTransmittance)
    {
        m_eta = intIOR / extIOR;
        m_invEta = 1.0f / m_eta;
    }

    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 true; }
    inline bool isTwosided() const { return true; }
    inline bool isNull() const { return false; }
    inline bool isConductor() const { return false; }

    std::string toString() const override
    {
        std::ostringstream oss;
        oss << "BSDF_rough_dielectric [" << '\n'
            //<< "  alpha = " << m_alpha << '\n'
            << "  eta = " << m_eta << '\n'
            << "]" << std::endl;
        return oss.str();
    }

    MicrofacetDistribution m_distr;
    Float m_eta, m_invEta;
    Spectrum m_specularReflectance = Spectrum::Ones();
    Spectrum m_specularTransmittance = Spectrum::Ones();

    DECLEAR_BSDF_HELPER_FUNCTIONS()
    PSDR_DECLARE_CLASS(RoughDielectricBSDF)
    PSDR_IMPLEMENT_VIRTUAL_CLASS(RoughDielectricBSDF)
};
