%module rpt
%{
    // Includes the header in the wrapper code
    #include "../rpt/camera.hpp"
    #include "../rpt/interface.hpp"
%}

// Some modules need extra imports beside the main .hpp file
%include "std_array.i"
%include "std_string.i"
%include "std_vector.i"

// Instantiate templates used by example
// If the template is too nested (>2), parts of it need to be declared as well
namespace std {
    %template(FloatMatrix_3x3) array<array<float, 3>, 3>;
    %template(VectorFloat) vector<float>;
    %template(FloatMatrix_3x1) array<array<float, 1>, 3>;
    %template(FloatMatrix_3x4) array<array<float, 3>, 4>;
    %template(Matrix_Jx4) vector<array<float, 4>>;
    %template(Matrix_NxJx4) vector<vector<array<float, 4>>>;
    %template(Matrix_Jx3) vector<array<float, 3>>;
    %template(Matrix_VxNxJx3) vector<vector<vector<array<float, 3>>>>;
    %template(VectorCamera) vector<Camera>;
    %template(FloatMatrix_2x3) array<array<float, 3>, 2>;
    %template(VectorString) vector<std::string>;
}

// Convert vector to native (python) list
%naturalvar Camera::K;
%naturalvar Camera::DC;
%naturalvar Camera::R;
%naturalvar Camera::T;

// Improve printing of result objects
%extend Camera {
    std::string __str__() const {
         return $self->to_string();
    }
}

// Ignore: Warning 503: Can't wrap 'operator <<' unless renamed to a valid identifier.
%warnfilter(503) Camera;

// Ignore: Warning 511: Can't use keyword arguments with overloaded functions.
// The warning is cause by enabling keyword arguments, which doesn't work for vectors.
#pragma SWIG nowarn=511

// Parse the header file to generate wrappers
%include "../rpt/camera.hpp"
%include "../rpt/interface.hpp"

// Add additional Python code to the module
%pythoncode %{
def convert_cameras(cameras):
    """Convert cameras from Python to C++."""
    c_cameras = []
    for cam in cameras:
        camera = Camera()
        camera.name = cam["name"]
        camera.K = cam["K"]
        camera.DC = cam["DC"]
        camera.R = cam["R"]
        camera.T = cam["T"]
        camera.width = cam["width"]
        camera.height = cam["height"]
        camera.type = cam.get("type", "pinhole")
        c_cameras.append(camera)
    return c_cameras
%}
