#pragma once

#include "../../../include/dv-processing/data/bounding_box_base.hpp"

#include <pybind11/pybind11.h>
#include <pybind11/stl_bind.h>

PYBIND11_MAKE_OPAQUE(std::vector<dv::BoundingBox>)

namespace py = pybind11;

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

	py::class_<dv::BoundingBox>(m, "BoundingBox")
		.def(py::init<int64_t, float, float, float, float, float, const std::string &>(), py::arg("timestamp"),
			py::arg("topLeftX"), py::arg("topLeftY"), py::arg("bottomRightX"), py::arg("bottomRightY"),
			py::arg("confidence"), py::arg("label"))
		.def_readwrite("timestamp", &dv::BoundingBox::timestamp, "Timestamp (µs).")
		.def_readwrite("topLeftX", &dv::BoundingBox::topLeftX, "Top left corner of bounding box x-coordinate.")
		.def_readwrite("topLeftY", &dv::BoundingBox::topLeftY, "Top left corner of bounding box y-coordinate.")
		.def_readwrite(
			"bottomRightX", &dv::BoundingBox::bottomRightX, "Bottom right corner of bounding box x-coordinate.")
		.def_readwrite(
			"bottomRightY", &dv::BoundingBox::bottomRightY, "Bottom right corner of bounding box y-coordinate.")
		.def_readwrite("confidence", &dv::BoundingBox::confidence, "Confidence of the given bounding box.")
		.def_readwrite("label", &dv::BoundingBox::label, "Label for the given bounding box.");

	py::class_<dv::BoundingBoxPacket> boundingBoxPacketClass(m, "BoundingBoxPacket");
	py::bind_vector<std::vector<dv::BoundingBox>>(boundingBoxPacketClass, "BoundingBoxVector");

	boundingBoxPacketClass.def(py::init<>())
		.def(py::init<const std::vector<dv::BoundingBox> &>(), "boundingBoxes"_a,
			"Create a packet from a list of bounding boxes")
		.def_readwrite("elements", &dv::BoundingBoxPacket::elements)
		.def_static("GetFullyQualifiedName", &dv::BoundingBoxPacket::GetFullyQualifiedName)
		.def_static("PacketIdentifier", &dv::BoundingBoxPacketIdentifier);
	py::implicitly_convertible<std::vector<dv::BoundingBox>, dv::BoundingBoxPacket>();
}
