/* poppler-link.cc: qt interface to poppler
 * Copyright (C) 2006, Albert Astals Cid
 * 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-private.h>

#include <QtCore/QStringList>

#include "Link.h"

namespace Poppler {

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

		LinkDestination::Kind kind; // destination type
		int pageNum; // page number
		double left, bottom; // position
		double right, top;
		double zoom; // zoom factor
		bool changeLeft, changeTop; // for destXYZ links, which position
		bool changeZoom; //   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;
		bool repeat;
		bool mix;
		SoundObject *sound;
};

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

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

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

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

	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 )
		{
			deleteDest = true;
			ld = data.doc->doc->findDest( data.namedDest );
		}
		
		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 (d->pageNum > 0 && d->pageNum <= data.doc->doc->getNumPages())
		{
			::Page *page = data.doc->doc->getCatalog()->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->top = tokens.at(4).toDouble();
		d->zoom = tokens.at(5).toDouble();
		d->changeLeft = static_cast<bool>(tokens.at(6).toInt());
		d->changeTop = static_cast<bool>(tokens.at(7).toInt());
		d->changeZoom = static_cast<bool>(tokens.at(8).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;
	}
	
	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;
	}

	// LinkMovie
	LinkMovie::LinkMovie( const QRectF &linkArea )
		: Link( *new LinkMoviePrivate( linkArea ) )
	{
	}
	
	LinkMovie::~LinkMovie()
	{
	}
	
	Link::LinkType LinkMovie::linkType() const
	{
		return Movie;
	}

}
