/* -LICENSE-START-
** Copyright (c) 2022 Blackmagic Design
**
** Permission is hereby granted, free of charge, to any person or organization
** obtaining a copy of the software and accompanying documentation (the
** "Software") to use, reproduce, display, distribute, sub-license, execute,
** and transmit the Software, and to prepare derivative works of the Software,
** and to permit third-parties to whom the Software is furnished to do so, in
** accordance with:
**
** (1) if the Software is obtained from Blackmagic Design, the End User License
** Agreement for the Software Development Kit (“EULA”) available at
** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or
**
** (2) if the Software is obtained from any third party, such licensing terms
** as notified by that third party,
**
** and all subject to the following:
**
** (3) the copyright notices in the Software and this entire statement,
** including the above license grant, this restriction and the following
** disclaimer, must be included in all copies of the Software, in whole or in
** part, and all derivative works of the Software, unless such copies or
** derivative works are solely in the form of machine-executable object code
** generated by a source language processor.
**
** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
** DEALINGS IN THE SOFTWARE.
**
** A copy of the Software is available free of charge at
** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA.
**
** -LICENSE-END-
*/

#include <QBrush>
#include <QFont>
#include <QFontDatabase>
#include <QFontMetrics>
#include <QPainter>

#include "platform.h"
#include "DeckLinkPreviewOverlay.h"

DeckLinkPreviewOverlay::DeckLinkPreviewOverlay(QObject *parent) :
	QObject(parent),
	m_enableTimecode(false),
	m_enableDeviceLabel(false)
{
}

void DeckLinkPreviewOverlay::setFrame(com_ptr<IDeckLinkVideoFrame> frame)
{
	bool validTimecode = false;
	{
		std::lock_guard<std::mutex> lock(m_mutex);

		if (frame)
		{
			m_signalValid = (frame->GetFlags() & bmdFrameHasNoInputSource) == 0;

			if (m_signalValid)
			{
				// Get the timecode attached to this frame
				com_ptr<IDeckLinkTimecode>	timecode;
				HRESULT result = frame->GetTimecode(bmdTimecodeRP188Any, timecode.releaseAndGetAddressOf());
				if (result == S_OK)
				{
					dlstring_t timecodeStr;

					result = timecode->GetString(&timecodeStr);
					if (result == S_OK)
					{
						m_timecode = DlToQString(timecodeStr);
						DeleteString(timecodeStr);
						validTimecode = true;
					}
				}
			}
		}

		if (!validTimecode)
			m_timecode = "00:00:00:00";
	}

	emit updatePreview();
}

void DeckLinkPreviewOverlay::clear()
{
	{
		std::lock_guard<std::mutex> lock(m_mutex);
		m_signalValid = false;
	}
}

void DeckLinkPreviewOverlay::setDeviceLabel(const QString& label)
{
	{
		std::lock_guard<std::mutex> lock(m_mutex);
		m_deviceLabel = label;
	}

	if (m_enableDeviceLabel)
		emit updatePreview();
}

void DeckLinkPreviewOverlay::enableTimecode(bool enable)
{
	{
		std::lock_guard<std::mutex> lock(m_mutex);
		m_enableTimecode = enable;
	}
	emit updatePreview();
}

void DeckLinkPreviewOverlay::enableDeviceLabel(bool enable)
{
	{
		std::lock_guard<std::mutex> lock(m_mutex);
		m_enableDeviceLabel = enable;
	}
	emit updatePreview();
}

bool DeckLinkPreviewOverlay::signalValid()
{
	std::lock_guard<std::mutex> lock(m_mutex);
	return m_signalValid;
}

void DeckLinkPreviewOverlay::paint(QPaintDevice* paintDevice)
{
	QPainter painter;
	painter.begin(paintDevice);

	QFont font = QFontDatabase::systemFont(QFontDatabase::FixedFont);
	QBrush brush(QColor(0, 0, 0, 128));

	{
		std::lock_guard<std::mutex> lock(m_mutex);
		if (!m_signalValid)
		{
			font.setPixelSize(paintDevice->height() / 12);
			QFontMetrics metrics(font, paintDevice);

			QString text("No Signal");
			painter.setPen(QColor(Qt::red));
			painter.setFont(font);
			painter.drawText((paintDevice->width() - metrics.width(text)) / 2, (paintDevice->height() - metrics.height()) / 2 + metrics.ascent(), text);
		}

		if (m_enableDeviceLabel)
		{
			font.setPixelSize(paintDevice->height() / 16);
			QFontMetrics metrics(font, paintDevice);

			QRect box(0, 0, paintDevice->width(), metrics.height() + 4);
			painter.fillRect(box, brush);
			painter.setPen(QColor(Qt::white));
			painter.setFont(font);
			painter.drawText((paintDevice->width() - metrics.width(m_deviceLabel)) / 2, box.top() + 2 + metrics.ascent(), m_deviceLabel);
		}

		if (m_enableTimecode)
		{
			font.setPixelSize(paintDevice->height() / 16);
			QFontMetrics metrics(font, paintDevice);

			QRect box(0, paintDevice->height() - (metrics.height() + 4), paintDevice->width(), metrics.height() + 4);
			painter.fillRect(box, brush);
			painter.setPen(QColor(Qt::white));
			painter.setFont(font);
			painter.drawText((paintDevice->width() - metrics.width(m_timecode)) / 2, box.top() + 2 + metrics.ascent(), m_timecode);
		}
	}

	painter.end();
}
