/* poppler-link.cc: qt interface to poppler
 * Copyright (C) 2006-2007, 2013, 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-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 LinkPrivate
{
	public:
		LinkPrivate( const QRectF &area );
		virtual ~LinkPrivate();

		QRectF linkArea;
};

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

	LinkPrivate::~LinkPrivate()
	{
	}

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;
		
		::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 )
	{
		QStringList tokens = description.split( ';' );
		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;
	}
}
