#pragma once

#include "../../../include/dv-processing/core/time.hpp"
#include "../../../include/dv-processing/data/trigger_base.hpp"

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

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

namespace py = pybind11;

/**
 * @brief Bind Trigger class to python
 * @param m pybind The module to bind to
 */
void bind_trigger_base(py::module &m) {
	using pybind11::operator""_a;
	{
		py::enum_<dv::TriggerType> triggerType(m, "TriggerType");
		for (auto enumValue = static_cast<int8_t>(dv::TriggerType::MIN);
			static_cast<dv::TriggerType>(enumValue) <= dv::TriggerType::MAX; enumValue++) {
			auto currentEnum = static_cast<dv::TriggerType>(enumValue);
			triggerType.value(dv::EnumNameTriggerType(currentEnum), currentEnum);
		}
	}

	py::class_<dv::Trigger>(m, "Trigger", "Trigger event received by the camera.")
		.def(py::init<>())
		.def(py::init<int64_t, dv::TriggerType>(), py::arg("timestamp"), py::arg("type"))
		.def_readwrite("timestamp", &dv::Trigger::timestamp, "Timestamp (µs).")
		.def_readwrite("type", &dv::Trigger::type, "Type of trigger that occurred.")
		.def(
			"time",
			[](const dv::Trigger &self) {
				return dv::toTimePoint(self.timestamp);
			},
			"Timestamp of the captured data, compatible with python time library");

	py::class_<dv::TriggerPacket> triggerPacketClass(m, "TriggerPacket");
	py::bind_vector<std::vector<dv::Trigger>>(triggerPacketClass, "TriggersVector");

	triggerPacketClass.def(py::init<>())
		.def(py::init<const std::vector<dv::Trigger> &>(), "triggers"_a, "Create a packet from a list of triggers")
		.def_readwrite("elements", &dv::TriggerPacket::elements)
		.def_static("GetFullyQualifiedName", &dv::TriggerPacket::GetFullyQualifiedName)
		.def_static("PacketIdentifier", &dv::TriggerPacketIdentifier);

	py::implicitly_convertible<std::vector<dv::Trigger>, dv::TriggerPacket>();
}
