/*
 * Copyright (C) 2014-2024 CZ.NIC
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations including
 * the two.
 */

#include <QtGlobal>  /* Q_OS_IOS */

#if !defined(Q_OS_IOS)
#  include <QPrinter>
#endif /* Q_OS_IOS */
#include <QPdfWriter>
#include <QTextDocument>
#include <QFontDatabase>

#include "src/datovka_shared/utility/pdf_printer.h"

/*!
 * @brief Load text into text document.
 *
 * @param[in,out] doc Document whose content needs to be set.
 * @param[in]     text Text content.
 * @param[in]     format Text format.
 */
static
void setTextDocumentContent(QTextDocument &doc, const QString &text,
    enum Utility::TextFormat format)
{
	switch (format) {
	case Utility::PLAIN_TEXT:
		doc.setPlainText(text);
		break;
	case Utility::HTML_TEXT:
		doc.setHtml(text);
		break;
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
	case Utility::MARKDOWN_TEXT:
		doc.setMarkdown(text);
		break;
#endif /* >= Qt-5.14 */
	default:
		doc.setPlainText(text);
		break;
	}
}

#if !defined(Q_OS_IOS)
bool Utility::printText(QPrinter *printer, const QString &text,
    enum TextFormat format)
{
	if (Q_UNLIKELY(printer == Q_NULLPTR)) {
		return false;
	}

	QTextDocument doc;
	setTextDocumentContent(doc, text, format);
	/*
	 * QPrinter::pageRect() is obsolete, using
	 * pageLayout().paintRectPixels(resolution()) instead.
	 * The unit of the returned rectangle is QPrinter::DevicePixel.
	 */
	doc.setPageSize(QSizeF(
#if (QT_VERSION >= QT_VERSION_CHECK(5, 3, 0))
	    printer->pageLayout().paintRectPixels(printer->resolution()).size()
#else /* < Qt-5.3 */
	    printer->pageRect().size()
#endif /* >= Qt-5.3 */
	    ));
	doc.setDocumentMargin(50.0);
	doc.print(printer);

	return true;
}
#endif /* !Q_OS_IOS */

bool Utility::printPDF(const QString &fileName, const QString &text,
    enum TextFormat format)
{
	if (Q_UNLIKELY(text.isEmpty() || fileName.isEmpty())) {
		return false;
	}

#if defined(Q_OS_IOS)
	{
		Q_UNUSED(format);

		QPdfWriter pdfwriter(fileName);
		pdfwriter.setPageSize(QPageSize(QPageSize::A4));
		pdfwriter.setPageMargins(QMargins(30, 30, 30, 30));

		QTextDocument doc;
		setTextDocumentContent(doc, text, format);
		doc.setDefaultFont(QFont("Times", 12));

		doc.print(&pdfwriter);
	}
#else /* !Q_OS_IOS */
	{
		QPrinter printer; /* QPrinter::ScreenResolution */
		printer.setFullPage(true);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 3, 0))
		printer.setPageMargins(QMarginsF(0, 0, 0, 0));
#else /* < Qt-5.3 */
		printer.setPageMargins(0, 0, 0, 0, QPrinter::Millimeter);
#endif /* >= Qt-5.3 */
		printer.setOutputFileName(fileName);
		printer.setOutputFormat(QPrinter::PdfFormat);

		return printText(&printer, text, format);
	}
#endif /* Q_OS_IOS */

	return true;
}

bool Utility::printPDFWithFont(const QString &fileName, const QString &text,
    enum TextFormat format, const QString &fontFileName)
{
	if (Q_UNLIKELY(text.isEmpty() || fileName.isEmpty())) {
		return false;
	}

	int id = -1;
	QFont font;
	if (!fontFileName.isEmpty()) {
		id = QFontDatabase::addApplicationFont(fontFileName);
		if (id != -1) {
			QString family = QFontDatabase::applicationFontFamilies(id).at(0);
			font = QFont(family);
			font.setPointSize(10);
		}
	}

	QPdfWriter pdfwriter(fileName);
#if (QT_VERSION >= QT_VERSION_CHECK(5, 3, 0))
	pdfwriter.setPageSize(QPageSize(QPageSize::A4));
	pdfwriter.setPageMargins(QMargins(0, 0, 0, 0));
#else /* < Qt-5.3 */
	pdfwriter.setPageSize(QPagedPaintDevice::A4);
	{
		QPagedPaintDevice::Margins margins = {0.0, 0.0, 0.0, 0.0};
		pdfwriter.setMargins(margins);
	}
#endif /* >= Qt-5.3 */

	QTextDocument doc;
	setTextDocumentContent(doc, text, format);
	if (id != -1) {
		doc.setDefaultFont(font);
	}
	doc.print(&pdfwriter);

	return true;
}
