#pragma once

#include <core/fwd.h>
#include <core/pmf.h>
#include <core/nanoflann.hpp>
#include <render/scene.h>


#define NUM_NEAREST_NEIGHBORS 10

struct PhotonMapOptions {
    PhotonMapOptions(size_t num_cam_path, size_t num_light_path, int max_bounces) : num_cam_path(num_cam_path), num_light_path(num_light_path), max_bounces(max_bounces) {}
    size_t num_cam_path;
    size_t num_light_path;
    int max_bounces;   
};

struct RadImpNode {
    Vector p;
    Spectrum val;
    int depth;
};


template <typename T>
struct PointCloud {
    struct Point
    {
        T  x,y,z;
    };

    std::vector<Point>  pts;

    inline size_t kdtree_get_point_count() const { return pts.size(); }

    inline T kdtree_get_pt(const size_t idx, const size_t dim) const
    {
        if (dim == 0) return pts[idx].x;
        else if (dim == 1) return pts[idx].y;
        else return pts[idx].z;
    }

    template <class BBOX>
    bool kdtree_get_bbox(BBOX& /* bb */) const { return false; }
};

template <typename T>
using KDtree = nanoflann::KDTreeSingleIndexAdaptor<nanoflann::L2_Simple_Adaptor<T, PointCloud<T> >, PointCloud<T>, 3>;

