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

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

    void setZero() override
    {
        m_distr.setZero();
        m_eta.setZero();
        m_k.setZero();
    }

    inline RoughConductorBSDF(float alpha, const Spectrum &intEta,
                              const Spectrum &K)
        : m_distr(alpha), m_eta(intEta), m_k(K) {}

    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 &rnd,
                    Vector &wo, Vector &woDual, Float &pdf, Float &pdfDual, Float &eta, Float &etaDual, Spectrum &ret, Spectrum &retDual,
                    EBSDFMode mode = EBSDFMode::ERadiance) const;

    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 true; }

    std::string toString() const override
    {
        std::ostringstream oss;
        oss << "BSDF_rough_conductor [" << '\n'
            << "  eta = "
            << std::endl
            << "  k = "
            << std::endl
            << "]" << std::endl;
        return oss.str();
    }

    MicrofacetDistribution m_distr;
    Spectrum m_eta, m_k;

    DECLEAR_BSDF_HELPER_FUNCTIONS()
    PSDR_DECLARE_CLASS(RoughConductorBSDF)
    PSDR_IMPLEMENT_VIRTUAL_CLASS(RoughConductorBSDF)
};
