#pragma once

#include "DeckLinkDisplayMode.h"
#include "DeckLinkSession.h"
#include "VideoIOEdges.h"
#include "VideoIOTypes.h"

#include <atomic>
#include <cstdint>
#include <functional>
#include <string>

namespace RenderCadenceCompositor
{
struct DeckLinkOutputConfig
{
	VideoFormat outputVideoMode;
	bool externalKeyingEnabled = false;
	bool outputAlphaRequired = false;
};

using DeckLinkOutputMetrics = VideoOutputEdgeMetrics;

class DeckLinkOutput : public IVideoOutputEdge
{
public:
	using CompletionCallback = IVideoOutputEdge::CompletionCallback;

	DeckLinkOutput() = default;
	DeckLinkOutput(const DeckLinkOutput&) = delete;
	DeckLinkOutput& operator=(const DeckLinkOutput&) = delete;
	~DeckLinkOutput();

	bool Initialize(const DeckLinkOutputConfig& config, CompletionCallback completionCallback, std::string& error);
	bool StartScheduledPlayback(std::string& error) override;
	bool ScheduleFrame(const VideoIOOutputFrame& frame) override;
	void Stop() override;
	void ReleaseResources() override;

	const VideoIOState& State() const override;
	DeckLinkOutputMetrics Metrics() const override;

private:
	void HandleCompletion(const VideoIOCompletion& completion);

	DeckLinkSession mSession;
	DeckLinkOutputConfig mConfig;
	CompletionCallback mCompletionCallback;
	std::atomic<uint64_t> mCompletions{ 0 };
	std::atomic<uint64_t> mDisplayedLate{ 0 };
	std::atomic<uint64_t> mDropped{ 0 };
	std::atomic<uint64_t> mFlushed{ 0 };
};
}
