/***************************************************************************
*   Copyright (C) 2006-2008 by Ian Reinhart Geiser                        *
*   geiseri@yahoo.com                                                     *
*                                                                         *
*   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 2 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, write to the                         *
*   Free Software Foundation, Inc.,                                       *
*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
***************************************************************************/
#include "pdfslidereporter.h"
#include "block.h"
#include "mindmap.h"

#include <QTextDocument>
#include <QPrinter>
#include <QPainter>
#include <QRect>
#include <QFile>
#include <QDate>
#include <QFontMetricsF>
#include <QSettings>
#include <QDesktopServices>
#include <QUrl>

#include  "qdebug.h"
extern int qt_defaultDpi();

PDFSlideReporter::PDFSlideReporter() : m_pdfPrinter(0), m_painter(0)
{

}

PDFSlideReporter::~PDFSlideReporter()
{}

void PDFSlideReporter::printImageBox( const QRectF & box, const QImage & img, QPainter * painter )
{
	QSizeF pageSize = img.size();
	const qreal textScaleX =  box.width() / pageSize.width();
	const qreal textScaleY =  box.height() / pageSize.height();

	painter->save();
	painter->translate( box.x(), box.y() );
	painter->scale( textScaleX, textScaleY);

	if( !img.isNull() )
		painter->drawImage(0,0,img);

	painter->restore();

}

void PDFSlideReporter::printTextBox( const QRectF & box, QTextDocument * text, QPainter * painter )
{
	const qreal dpiScaleX =  qt_defaultDpi() / qreal(painter->device()->logicalDpiX());
	const qreal dpiScaleY =  qt_defaultDpi() / qreal(painter->device()->logicalDpiY());
	QSizeF nativeBoxSize( box.size().width() * dpiScaleX, box.size().height() * dpiScaleY);
	QSizeF pageSize = text->size();
	pageSize.scale(nativeBoxSize, Qt::KeepAspectRatio);
	const qreal textScaleX =  pageSize.width() / text->size().width();
	const qreal textScaleY =  pageSize.height() / text->size().height();

	//	painter->drawRect( box );  // Debug templates...
	painter->save();
	painter->translate( box.x(), box.y() );
	painter->scale( 1.0/dpiScaleX,1.0/dpiScaleY);
	painter->scale( textScaleX, textScaleY);
	text->drawContents(painter);
	painter->restore();
}

void PDFSlideReporter::printTextBox( const QRectF & box, const QString &text, QPainter * painter )
{
	QTextDocument doc(text);
	printTextBox(box, &doc, painter);
}

QRectF PDFSlideReporter::generatePageRect( const QSizeF & pageSize, const QRectF & sourceRect )
{
	qreal x1,x2,y1,y2 = 0;
	sourceRect.getCoords(&x1,&y1,&x2,&y2);
	QRectF result;
	result.setCoords( (x1/100.0) * pageSize.width(),
	                  (y1/100.0) * pageSize.height(),
	                  (x2/100.0) * pageSize.width(),
	                  (y2/100.0) * pageSize.height());

	return result.normalized();
}


void PDFSlideReporter::generateReport( MindMap * map, const QString &fileName )
{
	if( QFile::exists(fileName))
		if( !QFile::remove(fileName) )
			return;

	QPrinter printer(QPrinter::HighResolution);
	printer.setColorMode(QPrinter::Color);
	printer.setFontEmbeddingEnabled(true);
	printer.setOutputFormat(QPrinter::PdfFormat);
	printer.setCreator("Flo 1.0");
	printer.setOrientation(QPrinter::Landscape);
	printer.setOutputFileName(fileName); // Setup
	printer.setFullPage(true);
	printer.setDocName(map->property("document.title").toString() );
	QPainter painter(&printer);

	QImage background;
	if( map->getProperty("slides.background").toString().isEmpty() )
		background.load( ":images/background_blue.png", "PNG" );
	else
		if( !background.load(map->getProperty("slides.background").toString()) )
		{
			background.load( ":images/background_blue.png", "PNG" );
		}

	m_pdfPrinter = &printer;
	m_painter = &painter;

	printImageBox( printer.pageRect(), background, m_painter );
	generateTitlePage( map->root() );
	foreach( Block *child, map->root()->children() )
	{
		m_pdfPrinter->newPage();
		printImageBox( printer.pageRect(), background, m_painter );
		generateContentPage(child, m_painter, m_pdfPrinter->pageRect().size() );
	}
	painter.end();
	m_pdfPrinter = 0;
	m_painter = 0;

	QDesktopServices::openUrl(fileName);
}
QRectF rectFromPoints( qreal x1, qreal y1, qreal x2, qreal y2)
{
	QRectF result;
	result.setTopLeft( QPointF( x1, y1));
	result.setBottomRight( QPointF( x2, y2));
	return result;
}

void PDFSlideReporter::generateTitlePage( Block *block )
{
	QRectF title = readTemplateRect(block->mindmap(), "first.title", rectFromPoints(0, 25,100, 75));
	QRectF author = readTemplateRect(block->mindmap(), "first.author", rectFromPoints(75, 75,99, 80));
	QRectF date = readTemplateRect(block->mindmap(), "first.date", rectFromPoints(75, 80,99, 85));
	QRectF footer = readTemplateRect(block->mindmap(), "first.footer", rectFromPoints(1, 92,100, 100));

	printTextBox(
	              generatePageRect( m_pdfPrinter->pageRect().size(), footer),
	              block->mindmap()->getProperty("document.footer").toString(),
	              m_painter );
	printTextBox(
	              generatePageRect( m_pdfPrinter->pageRect().size(), date),
	              block->mindmap()->getProperty("document.date", QDate::currentDate()).toDate().toString(),
	              m_painter );
	printTextBox(
	              generatePageRect( m_pdfPrinter->pageRect().size(), author),
	              block->mindmap()->getProperty("document.author").toString(),
	              m_painter );
	printTextBox(
				generatePageRect( m_pdfPrinter->pageRect().size(), title),
	              block->title(),
	              m_painter);

}

void PDFSlideReporter::generateContentPage( Block *block, QPainter *painter, const QSizeF &size )
{
	QRectF title = readTemplateRect(block->mindmap(), "second.title", rectFromPoints(0, 0, 100, 15));
	QRectF bodyFull = readTemplateRect(block->mindmap(), "second.bodyFull", rectFromPoints(0, 20, 100, 91));
	QRectF bodyHalf = readTemplateRect(block->mindmap(), "second.bodyHalf", rectFromPoints(0, 20, 50, 91));
	QRectF imgHalf = readTemplateRect(block->mindmap(), "second.imageHalf", rectFromPoints(50, 20, 100, 91));
	QRectF pgnumber = readTemplateRect(block->mindmap(), "second.pgNumber", rectFromPoints(95, 92, 100, 100));
	QRectF footer = readTemplateRect(block->mindmap(), "second.footer", rectFromPoints(1, 92, 94, 100));

	printTextBox(
				generatePageRect( m_pdfPrinter->pageRect().size(), footer ),
				block->mindmap()->getProperty("document.footer").toString(),
				m_painter );

	printTextBox(
				generatePageRect( size, title),
				block->title(),
				painter );

	printTextBox(
				generatePageRect( size, pgnumber),
				QString::number(block->index() + 1),
				painter );

	QTextDocument doc;

	QString htmlList = "<html><body><ol>";
	foreach( Block *child, block->children() )
	{
		htmlList += "<li>" + child->title() + "</li>";
		if( child->children().size() != 0 )
			generateContentPageList( child, &htmlList );

	}
	htmlList += "</ol></body></html>";
	doc.setHtml( htmlList );

	if( block->emblem().isEmpty() )
		printTextBox(
			generatePageRect( size, bodyFull),
			&doc,
			painter );
	else if( doc.toPlainText().isEmpty() )
	{
		block->drawEmblemImage(
		                        generatePageRect( size, bodyFull),
		                        painter );

	}
	else
	{
		printTextBox(
			generatePageRect( size, bodyHalf),
			&doc,
			painter );
		block->drawEmblemImage(
		                        generatePageRect( size, imgHalf),
		                        painter );
	}
}

void PDFSlideReporter::generateContentPageList( Block *block, QString * writer )
{
	writer->append("<ul>");
	foreach( Block *child, block->children() )
	{
		writer->append( "<li>" + child->title() + "</li>");
		if( child->children().size() != 0 )
			generateContentPageList( child, writer );
	}
	writer->append("</ul>");

}

QRectF PDFSlideReporter::readTemplateRect( MindMap *map, const QString & field, const QRectF & defaultRect )
{
	QSettings templateFile(map->getProperty("slides.template").toString(), QSettings::IniFormat);
	templateFile.beginGroup("Slides");

	QRectF result;
	qreal top = templateFile.value(field + ".top", defaultRect.top() ).value<qreal>();
	qreal bottom = templateFile.value(field + ".bottom", defaultRect.bottom() ).value<qreal>();
	qreal left = templateFile.value(field + ".left", defaultRect.left() ).value<qreal>();
	qreal right = templateFile.value(field + ".right", defaultRect.right() ).value<qreal>();

	result.setCoords(left,top,right,bottom);
	return result;
}


