/* poppler-link.cc: qt interface to poppler
 * Copyright (C) 2006-2007, 2013, 2016, 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"

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;
	}
}
