#pragma once

#include <psdr/core/frame.h>
#include "sensor.h"

namespace psdr
{

PSDR_CLASS_DECL_BEGIN(PerspectiveCamera, final, Sensor)
public:
    PerspectiveCamera(float fov_x, float near, float far) : m_fov_x(fov_x), m_near_clip(near), m_far_clip(far), 
        m_crop_offset_x(0), m_crop_offset_y(0), m_crop_size_x(1), m_crop_size_y(1) {}

    void configure() override;

    RayC sample_primary_ray(const Vector2fC &samples) const override;
    RayD sample_primary_ray(const Vector2fD &samples) const override;

    SensorDirectSampleC sample_direct(const Vector3fC &p) const override;

    PrimaryEdgeSample sample_primary_edge(const FloatC &sample1) const override;

    std::string to_string() const override;

    void set_crop_window(float crop_offset_x, float crop_offset_y, float crop_size_x, float crop_size_y) {
        m_crop_offset_x = crop_offset_x;
        m_crop_offset_y = crop_offset_y;
        m_crop_size_x = crop_size_x;
        m_crop_size_y = crop_size_y;
    }
    
    float       m_fov_x,
                m_near_clip,
                m_far_clip,
                m_crop_offset_x,
                m_crop_offset_y,
                m_crop_size_x,
                m_crop_size_y;

    Matrix4fD   m_sample_to_camera, m_camera_to_sample,
                m_world_to_sample, m_sample_to_world;

    Vector3fD   m_camera_pos, m_camera_dir;
    FloatD      m_inv_area;
PSDR_CLASS_DECL_END(PerspectiveCamera)

} // namespace psdr
