/* poppler-link.cc: qt interface to poppler
 * Copyright (C) 2006-2007, 2013, 2016, 2017, Albert Astals Cid
 * Copyright (C) 2007-2008, Pino Toscano <pino@kde.org>
 * Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
 * Copyright (C) 2012, Tobias Koenig <tokoe@kdab.com>
 * Copyright (C) 2012, Guillermo A. Amaral B. <gamaral@kde.org>
 * Adapting code from
 *   Copyright (C) 2004 by Enrico Ros <eros.kde@email.it>
 *
 * 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-link-private.h>
#include <poppler-private.h>
#include <poppler-media.h>

#include <QtCore/QStringList>

#include "poppler-annotation-private.h"

#include "Link.h"
#include "Rendition.h"

static bool operator==( const Ref &r1, const Ref &r2 )
{
	return r1.num == r2.num && r1.gen == r2.gen;
}

namespace Poppler {

class LinkDestinationPrivate : public QSharedData
{
	public:
		LinkDestinationPrivate();

		LinkDestination::Kind kind; // destination type
		QString name;
		int pageNum; // page number
		double left, bottom; // position
		double right, top;
		double zoom; // zoom factor
		bool changeLeft : 1, changeTop : 1; // for destXYZ links, which position
		bool changeZoom : 1; //   components to change
};

	LinkDestinationPrivate::LinkDestinationPrivate()
	{
		// sane defaults
		kind = LinkDestination::destXYZ;
		pageNum = 0;
		left = 0;
		bottom = 0;
		right = 0;
		top = 0;
		zoom = 1;
		changeLeft = true;
		changeTop = true;
		changeZoom = false;
	}

class LinkGotoPrivate : public LinkPrivate
{
	public:
		LinkGotoPrivate( const QRectF &area, const LinkDestination &dest );

		QString extFileName;
		LinkDestination destination;
};

	LinkGotoPrivate::LinkGotoPrivate( const QRectF &area, const LinkDestination &dest )
		: LinkPrivate( area ), destination( dest )
	{
	}

class LinkExecutePrivate : public LinkPrivate
{
	public:
		LinkExecutePrivate( const QRectF &area );

		QString fileName;
		QString parameters;
};

	LinkExecutePrivate::LinkExecutePrivate( const QRectF &area )
		: LinkPrivate( area )
	{
	}

class LinkBrowsePrivate : public LinkPrivate
{
	public:
		LinkBrowsePrivate( const QRectF &area );

		QString url;
};

	LinkBrowsePrivate::LinkBrowsePrivate( const QRectF &area )
		: LinkPrivate( area )
	{
	}

class LinkActionPrivate : public LinkPrivate
{
	public:
		LinkActionPrivate( const QRectF &area );

		LinkAction::ActionType type;
};

	LinkActionPrivate::LinkActionPrivate( const QRectF &area )
		: LinkPrivate( area )
	{
	}

class LinkSoundPrivate : public LinkPrivate
{
	public:
		LinkSoundPrivate( const QRectF &area );
		~LinkSoundPrivate();

		double volume;
		bool sync : 1;
		bool repeat : 1;
		bool mix : 1;
		SoundObject *sound;
};

	LinkSoundPrivate::LinkSoundPrivate( const QRectF &area )
		: LinkPrivate( area ), sound( 0 )
	{
	}

	LinkSoundPrivate::~LinkSoundPrivate()
	{
		delete sound;
	}

class LinkRenditionPrivate : public LinkPrivate
{
	public:
		LinkRenditionPrivate( const QRectF &area, ::MediaRendition *rendition, ::LinkRendition::RenditionOperation operation, const QString &script, const Ref &annotationReference );
		~LinkRenditionPrivate();

		MediaRendition *rendition;
		LinkRendition::RenditionAction action;
		QString script;
		Ref annotationReference;
};

	LinkRenditionPrivate::LinkRenditionPrivate( const QRectF &area, ::MediaRendition *r, ::LinkRendition::RenditionOperation operation, const QString &javaScript, const Ref &ref )
		: LinkPrivate( area )
		, rendition( r ? new MediaRendition( r ) : 0 )
		, action( LinkRendition::PlayRendition )
		, script( javaScript )
		, annotationReference( ref )
	{
		switch ( operation )
		{
			case ::LinkRendition::NoRendition:
				action = LinkRendition::NoRendition;
				break;
			case ::LinkRendition::PlayRendition:
				action = LinkRendition::PlayRendition;
				break;
			case ::LinkRendition::StopRendition:
				action = LinkRendition::StopRendition;
				break;
			case ::LinkRendition::PauseRendition:
				action = LinkRendition::PauseRendition;
				break;
			case ::LinkRendition::ResumeRendition:
				action = LinkRendition::ResumeRendition;
				break;
		}
	}

	LinkRenditionPrivate::~LinkRenditionPrivate()
	{
		delete rendition;
	}

class LinkJavaScriptPrivate : public LinkPrivate
{
	public:
		LinkJavaScriptPrivate( const QRectF &area );

		QString js;
};

	LinkJavaScriptPrivate::LinkJavaScriptPrivate( const QRectF &area )
		: LinkPrivate( area )
	{
	}

class LinkMoviePrivate : public LinkPrivate
{
	public:
		LinkMoviePrivate( const QRectF &area, LinkMovie::Operation operation, const QString &title, const Ref &reference );

		LinkMovie::Operation operation;
		QString annotationTitle;
		Ref annotationReference;
};

	LinkMoviePrivate::LinkMoviePrivate( const QRectF &area, LinkMovie::Operation _operation, const QString &title, const Ref &reference  )
		: LinkPrivate( area ), operation( _operation ), annotationTitle( title ), annotationReference( reference )
	{
	}

	static void cvtUserToDev(::Page *page, double xu, double yu, int *xd, int *yd) {
		double ctm[6];
		
		page->getDefaultCTM(ctm, 72.0, 72.0, 0, false, true);
		*xd = (int)(ctm[0] * xu + ctm[2] * yu + ctm[4] + 0.5);
		*yd = (int)(ctm[1] * xu + ctm[3] * yu + ctm[5] + 0.5);
	}

	LinkDestination::LinkDestination(const LinkDestinationData &data)
		: d( new LinkDestinationPrivate )
	{
		bool deleteDest = false;
		LinkDest *ld = data.ld;
		
		if ( data.namedDest && !ld && !data.externalDest )
		{
			deleteDest = true;
			ld = data.doc->doc->findDest( data.namedDest );
		}
		// in case this destination was named one, and it was not resolved
		if ( data.namedDest && !ld )
		{
			d->name = QString::fromLatin1( data.namedDest->getCString() );
		}
		
		if (!ld) return;
		
		if (ld->getKind() == ::destXYZ) d->kind = destXYZ;
		else if (ld->getKind() == ::destFit) d->kind = destFit;
		else if (ld->getKind() == ::destFitH) d->kind = destFitH;
		else if (ld->getKind() == ::destFitV) d->kind = destFitV;
		else if (ld->getKind() == ::destFitR) d->kind = destFitR;
		else if (ld->getKind() == ::destFitB) d->kind = destFitB;
		else if (ld->getKind() == ::destFitBH) d->kind = destFitBH;
		else if (ld->getKind() == ::destFitBV) d->kind = destFitBV;

		if ( !ld->isPageRef() ) d->pageNum = ld->getPageNum();
		else
		{
			Ref ref = ld->getPageRef();
			d->pageNum = data.doc->doc->findPage( ref.num, ref.gen );
		}
		double left = ld->getLeft();
		double bottom = ld->getBottom();
		double right = ld->getRight();
		double top = ld->getTop();
		d->zoom = ld->getZoom();
		d->changeLeft = ld->getChangeLeft();
		d->changeTop = ld->getChangeTop();
		d->changeZoom = ld->getChangeZoom();
		
		int leftAux = 0, topAux = 0, rightAux = 0, bottomAux = 0;
		
		if (!data.externalDest) {
			::Page *page;
			if (d->pageNum > 0 &&
				d->pageNum <= data.doc->doc->getNumPages() &&
				(page = data.doc->doc->getPage( d->pageNum )))
			{
				cvtUserToDev( page, left, top, &leftAux, &topAux );
				cvtUserToDev( page, right, bottom, &rightAux, &bottomAux );

				d->left = leftAux / (double)page->getCropWidth();
				d->top = topAux / (double)page->getCropHeight();
				d->right = rightAux/ (double)page->getCropWidth();
				d->bottom = bottomAux / (double)page->getCropHeight();
			}
			else d->pageNum = 0;
		}
		
		if (deleteDest) delete ld;
	}
	
	LinkDestination::LinkDestination(const QString &description)
		: d( new LinkDestinationPrivate )
	{
		const QStringList tokens = description.split( ';' );
		if (tokens.size() >= 10) {
			d->kind = static_cast<Kind>(tokens.at(0).toInt());
			d->pageNum = tokens.at(1).toInt();
			d->left = tokens.at(2).toDouble();
			d->bottom = tokens.at(3).toDouble();
			d->right = tokens.at(4).toDouble();
			d->top = tokens.at(5).toDouble();
			d->zoom = tokens.at(6).toDouble();
			d->changeLeft = static_cast<bool>(tokens.at(7).toInt());
			d->changeTop = static_cast<bool>(tokens.at(8).toInt());
			d->changeZoom = static_cast<bool>(tokens.at(9).toInt());
		}
	}
	
	LinkDestination::LinkDestination(const LinkDestination &other)
		: d( other.d )
	{
	}
	
	LinkDestination::~LinkDestination()
	{
	}
	
	LinkDestination::Kind LinkDestination::kind() const
	{
		return d->kind;
	}
	
	int LinkDestination::pageNumber() const
	{
		return d->pageNum;
	}
	
	double LinkDestination::left() const
	{
		return d->left;
	}
	
	double LinkDestination::bottom() const
	{
		return d->bottom;
	}
	
	double LinkDestination::right() const
	{
		return d->right;
	}
	
	double LinkDestination::top() const
	{
		return d->top;
	}
	
	double LinkDestination::zoom() const
	{
		return d->zoom;
	}
	
	bool LinkDestination::isChangeLeft() const
	{
		return d->changeLeft;
	}
	
	bool LinkDestination::isChangeTop() const
	{
		return d->changeTop;
	}
	
	bool LinkDestination::isChangeZoom() const
	{
		return d->changeZoom;
	}
	
	QString LinkDestination::toString() const
	{
		QString s = QString::number( (qint8)d->kind );
		s += ";" + QString::number( d->pageNum );
		s += ";" + QString::number( d->left );
		s += ";" + QString::number( d->bottom );
		s += ";" + QString::number( d->right );
		s += ";" + QString::number( d->top );
		s += ";" + QString::number( d->zoom );
		s += ";" + QString::number( (qint8)d->changeLeft );
		s += ";" + QString::number( (qint8)d->changeTop );
		s += ";" + QString::number( (qint8)d->changeZoom );
		return s;
	}
	
	QString LinkDestination::destinationName() const
	{
		return d->name;
	}
	
	LinkDestination& LinkDestination::operator=(const LinkDestination &other)
	{
		if ( this == &other )
			return *this;
		
		d = other.d;
		return *this;
	}
	
	
	// Link
	Link::~Link()
	{
		delete d_ptr;
	}
	
	Link::Link(const QRectF &linkArea)
		: d_ptr( new LinkPrivate( linkArea ) )
	{
	}
	
	Link::Link( LinkPrivate &dd )
		: d_ptr( &dd )
	{
	}

	Link::LinkType Link::linkType() const
	{
		return None;
	}
	
	QRectF Link::linkArea() const
	{
		Q_D( const Link );
		return d->linkArea;
	}
	
	// LinkGoto
	LinkGoto::LinkGoto( const QRectF &linkArea, QString extFileName, const LinkDestination & destination )
		: Link( *new LinkGotoPrivate( linkArea, destination ) )
	{
		Q_D( LinkGoto );
		d->extFileName = extFileName;
	}
	
	LinkGoto::~LinkGoto()
	{
	}
	
	bool LinkGoto::isExternal() const
	{
		Q_D( const LinkGoto );
		return !d->extFileName.isEmpty();
	}
	
	QString LinkGoto::fileName() const
	{
		Q_D( const LinkGoto );
		return d->extFileName;
	}
	
	LinkDestination LinkGoto::destination() const
	{
		Q_D( const LinkGoto );
		return d->destination;
	}
	
	Link::LinkType LinkGoto::linkType() const
	{
		return Goto;
	}
	
	// LinkExecute
	LinkExecute::LinkExecute( const QRectF &linkArea, const QString & file, const QString & params )
		: Link( *new LinkExecutePrivate( linkArea ) )
	{
		Q_D( LinkExecute );
		d->fileName = file;
		d->parameters = params;
	}
	
	LinkExecute::~LinkExecute()
	{
	}
	
	QString LinkExecute::fileName() const
	{
		Q_D( const LinkExecute );
		return d->fileName;
	}
	QString LinkExecute::parameters() const
	{
		Q_D( const LinkExecute );
		return d->parameters;
	}

	Link::LinkType LinkExecute::linkType() const
	{
		return Execute;
	}

	// LinkBrowse
	LinkBrowse::LinkBrowse( const QRectF &linkArea, const QString &url )
		: Link( *new LinkBrowsePrivate( linkArea ) )
	{
		Q_D( LinkBrowse );
		d->url = url;
	}
	
	LinkBrowse::~LinkBrowse()
	{
	}
	
	QString LinkBrowse::url() const
	{
		Q_D( const LinkBrowse );
		return d->url;
	}
	
	Link::LinkType LinkBrowse::linkType() const
	{
		return Browse;
	}

	// LinkAction
	LinkAction::LinkAction( const QRectF &linkArea, ActionType actionType )
		: Link( *new LinkActionPrivate( linkArea ) )
	{
		Q_D( LinkAction );
		d->type = actionType;
	}
		
	LinkAction::~LinkAction()
	{
	}
	
	LinkAction::ActionType LinkAction::actionType() const
	{
		Q_D( const LinkAction );
		return d->type;
	}

	Link::LinkType LinkAction::linkType() const
	{
		return Action;
	}

	// LinkSound
	LinkSound::LinkSound( const QRectF &linkArea, double volume, bool sync, bool repeat, bool mix, SoundObject *sound )
		: Link( *new LinkSoundPrivate( linkArea ) )
	{
		Q_D( LinkSound );
		d->volume = volume;
		d->sync = sync;
		d->repeat = repeat;
		d->mix = mix;
		d->sound = sound;
	}
	
	LinkSound::~LinkSound()
	{
	}
	
	Link::LinkType LinkSound::linkType() const
	{
		return Sound;
	}

	double LinkSound::volume() const
	{
		Q_D( const LinkSound );
		return d->volume;
	}

	bool LinkSound::synchronous() const
	{
		Q_D( const LinkSound );
		return d->sync;
	}

	bool LinkSound::repeat() const
	{
		Q_D( const LinkSound );
		return d->repeat;
	}

	bool LinkSound::mix() const
	{
		Q_D( const LinkSound );
		return d->mix;
	}

	SoundObject *LinkSound::sound() const
	{
		Q_D( const LinkSound );
		return d->sound;
	}

	// LinkRendition
	LinkRendition::LinkRendition( const QRectF &linkArea, ::MediaRendition *rendition, int operation, const QString &script, const Ref &annotationReference )
		: Link( *new LinkRenditionPrivate( linkArea, rendition, static_cast<enum ::LinkRendition::RenditionOperation>(operation), script, annotationReference ) )
	{
	}

	LinkRendition::~LinkRendition()
	{
	}
	
	Link::LinkType LinkRendition::linkType() const
	{
		return Rendition;
	}
	
	MediaRendition * LinkRendition::rendition() const
	{
		Q_D( const LinkRendition );
		return d->rendition;
	}

	LinkRendition::RenditionAction LinkRendition::action() const
	{
		Q_D( const LinkRendition );
		return d->action;
	}

	QString LinkRendition::script() const
	{
		Q_D( const LinkRendition );
		return d->script;
	}

	bool LinkRendition::isReferencedAnnotation( const ScreenAnnotation *annotation ) const
	{
		Q_D( const LinkRendition );
		if ( d->annotationReference.num != -1 && d->annotationReference == annotation->d_ptr->pdfObjectReference() )
		{
			return true;
		}

		return false;
	}

	// LinkJavaScript
	LinkJavaScript::LinkJavaScript( const QRectF &linkArea, const QString &js )
		: Link( *new LinkJavaScriptPrivate( linkArea ) )
	{
		Q_D( LinkJavaScript );
		d->js = js;
	}
	
	LinkJavaScript::~LinkJavaScript()
	{
	}
	
	Link::LinkType LinkJavaScript::linkType() const
	{
		return JavaScript;
	}
	
	QString LinkJavaScript::script() const
	{
		Q_D( const LinkJavaScript );
		return d->js;
	}

	// LinkMovie
	LinkMovie::LinkMovie( const QRectF &linkArea, Operation operation, const QString &annotationTitle, const Ref &annotationReference )
		: Link( *new LinkMoviePrivate( linkArea, operation, annotationTitle, annotationReference ) )
	{
	}
	
	LinkMovie::~LinkMovie()
	{
	}
	
	Link::LinkType LinkMovie::linkType() const
	{
		return Movie;
	}
	
	LinkMovie::Operation LinkMovie::operation() const
	{
		Q_D( const LinkMovie );
		return d->operation;
	}

	bool LinkMovie::isReferencedAnnotation( const MovieAnnotation *annotation ) const
	{
		Q_D( const LinkMovie );
		if ( d->annotationReference.num != -1 && d->annotationReference == annotation->d_ptr->pdfObjectReference() )
		{
			return true;
		}
		else if ( !d->annotationTitle.isNull() )
		{
			return ( annotation->movieTitle() == d->annotationTitle );
		}

		return false;
	}

	LinkOCGState::LinkOCGState( LinkOCGStatePrivate *ocgp )
		: Link ( *ocgp )
	{
	}

	LinkOCGState::~LinkOCGState()
	{
	}

	Link::LinkType LinkOCGState::linkType() const
	{
		return OCGState;
	}
}
