#pragma once

#include "../../../include/dv-processing/features/feature_tracks.hpp"

#include <pybind11/pybind11.h>

namespace py = pybind11;

/**
 * @brief Bind features::FeatureTracks to python
 * @param m pybind The module to bind to
 */
void bind_feature_tracks(py::module &m) {
	py::class_<dv::features::FeatureTracks>(m, "FeatureTracks",
		"A class to store a time limited amount of feature tracks. Sorts and stores the data in separate queues for "
		"each track id. Provides `visualize` function to generate visualization images of the tracks.")
		.def(py::init<>())
		.def(
			"accept",
			[](dv::features::FeatureTracks &self, const dv::TimedKeyPoint &keypoint) {
				self.accept(keypoint);
			},
			py::arg("keypoint"), "Add a keypoint measurement into the feature track.")
		.def(
			"accept",
			[](dv::features::FeatureTracks &self, const dv::TimedKeyPointPacket &keypoints) {
				self.accept(keypoints);
			},
			py::arg("keypoints"), "Add a batch of keypoints measurement into the feature track.")
		.def(
			"accept",
			[](dv::features::FeatureTracks &self, const dv::features::TrackerBase::Result::ConstPtr &trackingResult) {
				self.accept(trackingResult);
			},
			py::arg("trackingResult"), "Add keypoint tracking result from a tracker.")
		.def("getHistoryDuration", &dv::features::FeatureTracks::getHistoryDuration, "Retrieve the history duration.")
		.def("setHistoryDuration", &dv::features::FeatureTracks::setHistoryDuration, py::arg("historyDuration"),
			"Set new history duration limit to buffer. If the new limit is shorter than the previously set, the tracks "
			"will be reduced to the new limit right away.")
		.def(
			"getTrack",
			[](const dv::features::FeatureTracks &self,
				const int trackId) -> std::optional<std::vector<dv::TimedKeyPoint>> {
				if (const auto track = self.getTrack(trackId); track.has_value()) {
					return std::vector<dv::TimedKeyPoint>(track.value()->begin(), track.value()->end());
				}
				else {
					return std::nullopt;
				}
			},
			py::arg("trackId"), "Retrieve a track of given track id.")
		.def("getTrackIds", &dv::features::FeatureTracks::getTrackIds,
			"Return all track ids that are available in the buffer.")
		.def("getLatestTrackKeypoints", &dv::features::FeatureTracks::getLatestTrackKeypoints,
			"Return last keypoint from all tracks in the history.")
		.def("visualize", &dv::features::FeatureTracks::visualize, py::arg("background"),
			"Draws tracks on the input image, by default uses neon color palette from the `dv::visualization::colors` "
			"namespace for each of the tracks.")
		.def("isEmpty", &dv::features::FeatureTracks::isEmpty,
			"Checks whether the feature track history buffer is empty.")
		.def("clear", &dv::features::FeatureTracks::clear,
			"Deletes any data stored in feature track buffer and resets visualization image.")
		.def("getHighestTime", &dv::features::FeatureTracks::getHighestTime,
			"Return latest time from all existing tracks.");
}
