#include <dv-processing/io/camera/discovery.hpp>

#include <opencv2/highgui.hpp>

int main() {
	using namespace std::chrono_literals;

	// Open any camera
	auto capture = dv::io::camera::open();

	// Make sure it supports event stream output, throw an error otherwise
	if (!capture->isEventStreamAvailable()) {
		throw dv::exceptions::RuntimeError("Input camera does not provide an event stream.");
	}

	// Initialize an accumulator with camera sensor resolution
	dv::SpeedInvariantTimeSurface surface(*capture->getEventResolution());

	// Initialize a preview window
	cv::namedWindow("Preview", cv::WINDOW_NORMAL);

	// Initialize a slicer
	dv::EventStreamSlicer slicer;

	// Register a callback every 33 milliseconds
	slicer.doEveryTimeInterval(33ms, [&surface](const dv::EventStore &events) {
		// Pass the events to update the time surface
		surface.accept(events);

		// Generate a preview frame
		dv::Frame frame = surface.generateFrame();

		// Show the accumulated image
		cv::imshow("Preview", frame.image);
		cv::waitKey(2);
	});

	// Run the event processing while the camera is connected
	while (capture->isRunning()) {
		// Receive events, check if anything was received
		if (const auto events = capture->getNextEventBatch()) {
			// If so, pass the events into the slicer to handle them
			slicer.accept(*events);
		}
	}

	return 0;
}
