#pragma once

#include "../../../include/dv-processing/camera/calibration_set.hpp"

#include <pybind11/pybind11.h>

namespace py = pybind11;

/**
 * @brief Bind camera::CalibrationSet to python
 * @param m pybind The module to bind to
 */
void bind_calibration_set(py::module &m) {
	using pybind11::operator""_a;

	py::class_<dv::camera::CalibrationSet>(m, "CalibrationSet")
		.def(py::init<>())
		.def_static("LoadFromFile", &dv::camera::CalibrationSet::LoadFromFile, py::arg("path"),
			"Create a calibration file representation from a persistent file. Supports legacy '.xml' calibration "
			"files produced by DV as well as JSON files containing calibration of a new format. The file format is "
			"distinguished using the file path extension.")
		.def("getCameraList", &dv::camera::CalibrationSet::getCameraList,
			"Get a list of cameras available by their designation.")
		.def("getImuList", &dv::camera::CalibrationSet::getImuList,
			"Get a list camera designations which have imu calibrations available in this calibration set.")
		.def("getStereoList", &dv::camera::CalibrationSet::getStereoList,
			"Get a list of designations of stereo calibrations available here.")
		.def("getCameraCalibrations", &dv::camera::CalibrationSet::getCameraCalibrations,
			"Retrieve the full list of camera intrinsic calibrations.")
		.def("getImuCalibrations", &dv::camera::CalibrationSet::getImuCalibrations,
			"Retrieve the full list of IMU extrinsic calibrations.")
		.def("getStereoCalibrations", &dv::camera::CalibrationSet::getStereoCalibrations,
			"Retrieve the full list of stereo extrinsic calibrations.")
		.def("getCameraCalibration", &dv::camera::CalibrationSet::getCameraCalibration, py::arg("designation"),
			"Retrieve a camera calibration by designation (e.g. 'C0').")
		.def("getImuCalibration", &dv::camera::CalibrationSet::getImuCalibration, py::arg("designation"),
			"Get IMU calibration by IMU sensor designation (e.g. 'S0').")
		.def("getStereoCalibration", &dv::camera::CalibrationSet::getStereoCalibration, py::arg("designation"),
			"Get stereo calibration by stereo rig designation (e.g. 'C0C1').")
		.def("getCameraCalibrationByName", &dv::camera::CalibrationSet::getCameraCalibrationByName,
			py::arg("cameraName"),
			"Retrieve a camera calibration by camera name, which consist of model and serial number concatenation with "
			"an underscore separator (e.g. 'DVXplorer_DXA00000'). Camera name is usually available in recording "
			"files and when connected directly to a camera.")
		.def("getImuCalibrationByName", &dv::camera::CalibrationSet::getImuCalibrationByName, py::arg("cameraName"),
			"Retrieve an IMU calibration by camera name, which consist of model and serial number concatenation with "
			"an underscore separator (e.g. 'DVXplorer_DXA00000'). Camera name is usually available in recording "
			"files and when connected directly to a camera.")
		.def("getStereoCalibrationByLeftCameraName", &dv::camera::CalibrationSet::getStereoCalibrationByLeftCameraName,
			py::arg("cameraName"),
			"Retrieve a stereo calibration by matching camera name to left camera name in the stereo calibrations. "
			"Camera name consist of model and serial number concatenation with an underscore separator (e.g. "
			"'DVXplorer_DXA00000'). Camera name is usually available in recording files and when connected directly "
			"to a camera.")
		.def("getStereoCalibrationByRightCameraName",
			&dv::camera::CalibrationSet::getStereoCalibrationByRightCameraName, py::arg("cameraName"),
			"Retrieve a stereo calibration by matching camera name to right camera name in the stereo calibrations. "
			"Camera name consist of model and serial number concatenation with an underscore separator (e.g. "
			"'DVXplorer_DXA00000'). Camera name is usually available in recording files and when connected directly "
			"to a camera.")
		.def("addCameraCalibration", &dv::camera::CalibrationSet::addCameraCalibration, py::arg("calibration"),
			"Add an intrinsic calibration to the camera calibration set. Camera designation is going to be generated "
			"automatically.")
		.def("addImuCalibration", &dv::camera::CalibrationSet::addImuCalibration, py::arg("calibration"),
			"Add an IMU extrinsics calibration to the calibration set.")
		.def("addStereoCalibration", &dv::camera::CalibrationSet::addStereoCalibration, py::arg("calibration"),
			"Add a stereo calibration to the calibration set. Intrinsic calibrations of the sensors should already be "
			"added using `addCameraCalibration` prior to adding the stereo extrinsic calibration.")
		.def("updateImuCalibration", &dv::camera::CalibrationSet::updateImuCalibration, py::arg("calibration"),
			"Update an IMU calibration in the calibration set.")
		.def("updateCameraCalibration", &dv::camera::CalibrationSet::updateCameraCalibration, py::arg("calibration"),
			"Update a camera intrinsic calibration in the calibration set.")
		.def("updateStereoCameraCalibration", &dv::camera::CalibrationSet::updateStereoCameraCalibration,
			py::arg("calibration"), "Update a stereo calibration in the calibration set.")
		.def("writeToFile", &dv::camera::CalibrationSet::writeToFile, py::arg("outputFile"),
			"Write the contents of this calibration set into a file at given path. This function requires that "
			"supplied path contains '.json' extension.");
}
