#pragma once
#include <render/scene.h>
#include "algorithm1.h"

NAMESPACE_BEGIN(algorithm1_vol)

// forward
// getPoint
bool getPoint(const Scene &scene, Intersection &v);
bool getPath(const Scene &scene, LightPath &path);

// eval vertex
Spectrum evalFirstVertexContrib(
    const Scene &scene, RndSampler *sampler, const Array2i &pixel_idx,
    const Intersection &curV, const Intersection &nextV);
Spectrum evalVertexContrib(
    const Scene &scene, RndSampler *sampler,
    const Intersection &preV, Intersection &curV, const Intersection &nextV);
Spectrum evalLastVertexContrib(const Scene &scene,
                               const Intersection &curV, const Intersection &neeV);

void evalVertex(const Scene &scene, LightPath &path, RndSampler *sampler);

// eval path
Spectrum evalPath(const Scene &scene, LightPath &path);

// eval
Spectrum eval(const Scene &scene, LightPath &path, RndSampler *sampler);

// ad

void d_getPoint(const Scene &scene, Scene &d_scene, const Intersection &v, Intersection &d_v);
void d_getPath(const Scene &scene, Scene &d_scene, LightPath &path, LightPath &d_path);

void d_evalFirstVertexContrib(const Scene &scene, Scene &d_scene,
                              RndSampler *sampler, const Array2i &pixel_idx,
                              const Intersection &curV, Intersection &d_curV,
                              const Intersection &nextV, Intersection &d_nextV,
                              Spectrum d_value);
void d_evalVertexContrib(const Scene &scene, Scene &d_scene,
                         RndSampler *sampler,
                         const Intersection &preV, Intersection &d_preV,
                         const Intersection &curV, Intersection &d_curV,
                         const Intersection &nextV, Intersection &d_nextV,
                         Spectrum d_value);
void d_evalLastVertexContrib(const Scene &scene, Scene &d_scene,
                             const Intersection &curV, Intersection &d_curV,
                             const Intersection &neeV, Intersection &d_neeV,
                             Spectrum d_value);

void d_evalVertex(const Scene &scene, Scene &d_scene,
                  const LightPath &path, LightPath &d_path,
                  RndSampler *sampler);

void d_evalPath(const Scene &scene, Scene &d_scene,
                const LightPath &path, LightPath &d_path,
                Spectrum d_value);

void d_eval(const Scene &scene, Scene &d_scene,
            LightPathAD &pathAD,
            Spectrum d_value, RndSampler *sampler);

NAMESPACE_END(algorithm1_vol)
