/* poppler-link.cc: qt interface to poppler
 * Copyright (C) 2006-2007, 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-qt4.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 )
	{
		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 )
		: Link( *new LinkRenditionPrivate( linkArea, rendition, ::LinkRendition::NoRendition, QString(), Ref() ) )
	{
	}
	
	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;
	}
}
