#pragma once
#ifndef BINNED_PARTICLE_TRACER_AD_PATHSPACE_H__
#define BINNED_PARTICLE_TRACER_AD_PATHSPACE_H__

#include "binnedPathADps.h"

struct Binned_ParticleTracerAD_PathSpace : Binned_PathTracerAD_PathSpace {
    using RecordEntry = std::tuple<SpectrumAD, FloatAD, int>; // <path_contribution, path_length, idx_pixel>

    void renderInterior(const Scene &scene, const RenderOptions &options, ptr<float> rendered_image) const override;

    void traceParticleAD(const Scene &scene, RndSampler *sampler, int max_bounces, int thread_id, Float grad_threshold) const;
    void handleEmissionAD(const IntersectionAD &its, const Scene &scene, RndSampler *sampler, const SpectrumAD &weight, 
        int max_bounces, std::vector<RecordEntry> &records) const;
    void handleSurfaceInteractionAD(const IntersectionAD &its, const Scene &scene, const Medium *ptr_med, RndSampler *sampler,
        const SpectrumAD &weight, int max_bounces, FloatAD path_length, std::vector<RecordEntry> &records) const;

    mutable std::vector<std::vector<SpectrumAD>> image_per_thread;

    // Unused
    Spectrum pixelColor(const Scene &scene, const RenderOptions &options, RndSampler *sampler, Float x, Float y) const override { assert(false); }
    SpectrumAD pixelColorAD(const Scene &scene, const RenderOptions &options, RndSampler *sampler, Float x, Float y) const override { assert(false); };

    std::string getName() const { return "binned_ptracerAD_ps"; }
};

#endif //BINNED_PARTICLE_TRACER_AD_PATHSPACE_H__
