/* poppler-ps-converter.cc: qt interface to poppler
 * Copyright (C) 2007, 2009, 2010, 2015, Albert Astals Cid <aacid@kde.org>
 * Copyright (C) 2008, Pino Toscano <pino@kde.org>
 * Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
 * Copyright (C) 2011 Glad Deschrijver <glad.deschrijver@gmail.com>
 * Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
 * Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
 * Copyright (C) 2014 Adrian Johnson <ajohnson@redneon.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, 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., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "poppler-qt5.h"

#include "poppler-private.h"
#include "poppler-converter-private.h"

#include "PSOutputDev.h"

static void outputToQIODevice(void *stream, const char *data, int len)
{
	static_cast<QIODevice*>(stream)->write(data, len);
}

namespace Poppler {

class PSConverterPrivate : public BaseConverterPrivate
{
	public:
		PSConverterPrivate();

		QList<int> pageList;
		QString title;
		double hDPI;
		double vDPI;
		int rotate;
		int paperWidth;
		int paperHeight;
		int marginRight;
		int marginBottom;
		int marginLeft;
		int marginTop;
		PSConverter::PSOptions opts;
		void (* pageConvertedCallback)(int page, void *payload);
		void *pageConvertedPayload;
};

PSConverterPrivate::PSConverterPrivate()
	: BaseConverterPrivate(),
	hDPI(72), vDPI(72), rotate(0), paperWidth(-1), paperHeight(-1),
	marginRight(0), marginBottom(0), marginLeft(0), marginTop(0),
	opts(PSConverter::Printing), pageConvertedCallback(0),
	pageConvertedPayload(0)
{
}


PSConverter::PSConverter(DocumentData *document)
	: BaseConverter(*new PSConverterPrivate())
{
	Q_D(PSConverter);
	d->document = document;
}

PSConverter::~PSConverter()
{
}

void PSConverter::setPageList(const QList<int> &pageList)
{
	Q_D(PSConverter);
	d->pageList = pageList;
}

void PSConverter::setTitle(const QString &title)
{
	Q_D(PSConverter);
	d->title = title;
}

void PSConverter::setHDPI(double hDPI)
{
	Q_D(PSConverter);
	d->hDPI = hDPI;
}

void PSConverter::setVDPI(double vDPI)
{
	Q_D(PSConverter);
	d->vDPI = vDPI;
}

void PSConverter::setRotate(int rotate)
{
	Q_D(PSConverter);
	d->rotate = rotate;
}

void PSConverter::setPaperWidth(int paperWidth)
{
	Q_D(PSConverter);
	d->paperWidth = paperWidth;
}

void PSConverter::setPaperHeight(int paperHeight)
{
	Q_D(PSConverter);
	d->paperHeight = paperHeight;
}

void PSConverter::setRightMargin(int marginRight)
{
	Q_D(PSConverter);
	d->marginRight = marginRight;
}

void PSConverter::setBottomMargin(int marginBottom)
{
	Q_D(PSConverter);
	d->marginBottom = marginBottom;
}

void PSConverter::setLeftMargin(int marginLeft)
{
	Q_D(PSConverter);
	d->marginLeft = marginLeft;
}

void PSConverter::setTopMargin(int marginTop)
{
	Q_D(PSConverter);
	d->marginTop = marginTop;
}

void PSConverter::setStrictMargins(bool strictMargins)
{
	Q_D(PSConverter);
	if (strictMargins)
		d->opts |= StrictMargins;
	else
		d->opts &= ~StrictMargins;
}

void PSConverter::setForceRasterize(bool forceRasterize)
{
	Q_D(PSConverter);
	if (forceRasterize)
		d->opts |= ForceRasterization;
	else
		d->opts &= ~ForceRasterization;
}

void PSConverter::setPSOptions(PSConverter::PSOptions options)
{
	Q_D(PSConverter);
	d->opts = options;
}

PSConverter::PSOptions PSConverter::psOptions() const
{
	Q_D(const PSConverter);
	return d->opts;
}

void PSConverter::setPageConvertedCallback(void (* callback)(int page, void *payload), void *payload)
{
	Q_D(PSConverter);
	d->pageConvertedCallback = callback;
	d->pageConvertedPayload = payload;
}

static GBool annotDisplayDecideCbk(Annot *annot, void *user_data)
{
	if (annot->getType() == Annot::typeWidget)
		return gTrue; // Never hide forms
	else
		return *(GBool*)user_data;
}

bool PSConverter::convert()
{
	Q_D(PSConverter);
	d->lastError = NoError;

	Q_ASSERT(!d->pageList.isEmpty());
	Q_ASSERT(d->paperWidth != -1);
	Q_ASSERT(d->paperHeight != -1);
	
	if (d->document->locked)
	{
		d->lastError = FileLockedError;
		return false;
	}
	
	QIODevice *dev = d->openDevice();
	if (!dev)
	{
		d->lastError = OpenOutputError;
		return false;
	}

	QByteArray pstitle8Bit = d->title.toLocal8Bit();
	char* pstitlechar;
	if (!d->title.isEmpty()) pstitlechar = pstitle8Bit.data();
	else pstitlechar = 0;
	
	std::vector<int> pages;
	foreach(int page, d->pageList)
	{
		pages.push_back(page);
	}

	PSOutputDev *psOut = new PSOutputDev(outputToQIODevice, dev,
	                                     pstitlechar,
	                                     d->document->doc,
	                                     pages,
	                                     (d->opts & PrintToEPS) ? psModeEPS : psModePS,
	                                     d->paperWidth,
	                                     d->paperHeight,
	                                     gFalse,
	                                     gFalse,
	                                     d->marginLeft,
	                                     d->marginBottom,
	                                     d->paperWidth - d->marginRight,
	                                     d->paperHeight - d->marginTop,
	                                     (d->opts & ForceRasterization));
	
	if (d->opts & StrictMargins)
	{
		double xScale = ((double)d->paperWidth - (double)d->marginLeft - (double)d->marginRight) / (double)d->paperWidth;
		double yScale = ((double)d->paperHeight - (double)d->marginBottom - (double)d->marginTop) / (double)d->paperHeight;
		psOut->setScale(xScale, yScale);
	}
	
	if (psOut->isOk())
	{
		GBool isPrinting = (d->opts & Printing) ? gTrue : gFalse;
		GBool showAnnotations = (d->opts & HideAnnotations) ? gFalse : gTrue;
		foreach(int page, d->pageList)
		{
			d->document->doc->displayPage(psOut,
			                              page,
			                              d->hDPI,
			                              d->vDPI,
			                              d->rotate,
			                              gFalse,
			                              gTrue,
			                              isPrinting,
			                              NULL,
			                              NULL,
			                              annotDisplayDecideCbk,
			                              &showAnnotations, gTrue);
			if (d->pageConvertedCallback)
				(*d->pageConvertedCallback)(page, d->pageConvertedPayload);
		}
		delete psOut;
		d->closeDevice();
		return true;
	}
	else
	{
		delete psOut;
		d->closeDevice();
		return false;
	}
}

}
