/* poppler-private.h: qt interface to poppler
 * Copyright (C) 2005, Net Integration Technologies, Inc.
 * Copyright (C) 2006 by Albert Astals Cid <aacid@kde.org>
 * Inspired on code by
 * Copyright (C) 2004 by Albert Astals Cid <tsdgeos@terra.es>
 * 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.
 */

#ifndef _POPPLER_PRIVATE_H_
#define _POPPLER_PRIVATE_H_

#include <config.h>
#include <GfxState.h>
#include <GlobalParams.h>
#include <Link.h>
#include <Outline.h>
#include <PDFDoc.h>
#include <FontInfo.h>
#include <OutputDev.h>
#if defined(HAVE_SPLASH)
#include <SplashOutputDev.h>
#endif
#include <QtCore/QVariant>

class FormWidget;

namespace Poppler {

    /* borrowed from kpdf */
    static QString unicodeToQString(Unicode* u, int len) {
        QString ret;
        ret.resize(len);
        QChar* qch = (QChar*) ret.unicode();
        for (;len;--len)
          *qch++ = (QChar) *u++;
        return ret;
    }

    static GooString *QStringToGooString(const QString &s) {
        int len = s.length();
        char *cstring = (char *)gmallocn(s.length(), sizeof(char));
        for (int i = 0; i < len; ++i)
          cstring[i] = s.at(i).unicode();
        GooString *ret = new GooString(cstring, len);
        gfree(cstring);
        return ret;
    }

    static GooString *QStringToUnicodeGooString(const QString &s) {
        int len = s.length() * 2 + 2;
        char *cstring = (char *)gmallocn(len, sizeof(char));
        cstring[0] = 0xfe;
        cstring[1] = 0xff;
        for (int i = 0; i < s.length(); ++i)
        {
          cstring[2+i*2] = s.at(i).row();
          cstring[3+i*2] = s.at(i).cell();
        }
        GooString *ret = new GooString(cstring, len);
        gfree(cstring);
        return ret;
    }

    static QString UnicodeParsedString(GooString *s1) {
        if ( !s1 || s1->getLength() == 0 )
            return QString();

        GBool isUnicode;
        int i;
        Unicode u;
        QString result;
        if ( ( s1->getChar(0) & 0xff ) == 0xfe && ( s1->getLength() > 1 && ( s1->getChar(1) & 0xff ) == 0xff ) )
        {
            isUnicode = gTrue;
            i = 2;
        }
        else
        {
            isUnicode = gFalse;
            i = 0;
        }
        while ( i < s1->getLength() )
        {
            if ( isUnicode )
            {
                u = ( ( s1->getChar(i) & 0xff ) << 8 ) | ( s1->getChar(i+1) & 0xff );
                i += 2;
            }
            else
            {
                u = s1->getChar(i) & 0xff;
                ++i;
            }
            result += unicodeToQString( &u, 1 );
        }
        return result;
    }


    class LinkDestinationData
    {
        public:
            LinkDestinationData( LinkDest *l, GooString *nd, Poppler::DocumentData *pdfdoc )
             : ld(l), namedDest(nd), doc(pdfdoc)
            {
            }

            LinkDest *ld;
            GooString *namedDest;
            Poppler::DocumentData *doc;
    };

    class DocumentData {
    public:
	DocumentData(GooString *filePath, GooString *ownerPassword, GooString *userPassword)
	    {
		doc = new PDFDoc(filePath, ownerPassword, userPassword);
		init(ownerPassword, userPassword);
	    }
	
	DocumentData(const QByteArray &data, GooString *ownerPassword, GooString *userPassword)
	    {
		Object obj;
		fileContents = data;
		obj.initNull();
		MemStream *str = new MemStream((char*)fileContents.data(), 0, fileContents.length(), &obj);
	        doc = new PDFDoc(str, ownerPassword, userPassword);
		init(ownerPassword, userPassword);
	    }
	
	void init(GooString *ownerPassword, GooString *userPassword)
	    {
		m_fontInfoScanner = 0;
		m_backend = Document::SplashBackend;
		m_outputDev = 0;
		paperColor = Qt::white;
		m_hints = 0;
		// It might be more appropriate to delete these in PDFDoc
		delete ownerPassword;
		delete userPassword;
		
		if ( count == 0 ) globalParams = new GlobalParams();
		count ++;
	    }
	
	~DocumentData()
	{
		qDeleteAll(m_embeddedFiles);
		delete doc;
		delete m_outputDev;
		delete m_fontInfoScanner;
		
		count --;
		if ( count == 0 ) delete globalParams;
	}
	
	OutputDev *getOutputDev()
	{
		if (!m_outputDev)
		{
			switch (m_backend)
			{
			case Document::ArthurBackend:
			// create a splash backend even in case of the Arthur Backend
			case Document::SplashBackend:
			{
#if defined(HAVE_SPLASH)
			SplashColor bgColor;
			bgColor[0] = paperColor.red();
			bgColor[1] = paperColor.green();
			bgColor[2] = paperColor.blue();
			GBool AA = m_hints & Document::TextAntialiasing ? gTrue : gFalse;
			SplashOutputDev * splashOutputDev = new SplashOutputDev(splashModeXBGR8, 4, gFalse, bgColor, gTrue, AA);
			splashOutputDev->setVectorAntialias(m_hints & Document::Antialiasing ? gTrue : gFalse);
			splashOutputDev->startDoc(doc->getXRef());
			m_outputDev = splashOutputDev;
#endif
			break;
			}
			}
		}
		return m_outputDev;
	}
	
	void addTocChildren( QDomDocument * docSyn, QDomNode * parent, GooList * items )
	{
		int numItems = items->getLength();
		for ( int i = 0; i < numItems; ++i )
		{
			// iterate over every object in 'items'
			OutlineItem * outlineItem = (OutlineItem *)items->get( i );
			
			// 1. create element using outlineItem's title as tagName
			QString name;
			Unicode * uniChar = outlineItem->getTitle();
			int titleLength = outlineItem->getTitleLength();
			name = unicodeToQString(uniChar, titleLength);
			if ( name.isEmpty() )
				continue;
			
			QDomElement item = docSyn->createElement( name );
			parent->appendChild( item );
			
			// 2. find the page the link refers to
			::LinkAction * a = outlineItem->getAction();
			if ( a && ( a->getKind() == actionGoTo || a->getKind() == actionGoToR ) )
			{
				// page number is contained/referenced in a LinkGoTo
				LinkGoTo * g = static_cast< LinkGoTo * >( a );
				LinkDest * destination = g->getDest();
				if ( !destination && g->getNamedDest() )
				{
					// no 'destination' but an internal 'named reference'. we could
					// get the destination for the page now, but it's VERY time consuming,
					// so better storing the reference and provide the viewport on demand
					GooString *s = g->getNamedDest();
					QChar *charArray = new QChar[s->getLength()];
					for (int i = 0; i < s->getLength(); ++i) charArray[i] = QChar(s->getCString()[i]);
					QString aux(charArray, s->getLength());
					item.setAttribute( "DestinationName", aux );
					delete[] charArray;
				}
				else if ( destination && destination->isOk() )
				{
					LinkDestinationData ldd(destination, NULL, this);
					item.setAttribute( "Destination", LinkDestination(ldd).toString() );
				}
				if ( a->getKind() == actionGoToR )
				{
					LinkGoToR * g2 = static_cast< LinkGoToR * >( a );
					item.setAttribute( "ExternalFileName", g2->getFileName()->getCString() );
				}
			}

			item.setAttribute( "Open", QVariant( (bool)outlineItem->isOpen() ).toString() );

			// 3. recursively descend over children
			outlineItem->open();
			GooList * children = outlineItem->getKids();
			if ( children )
				addTocChildren( docSyn, &item, children );
		}
	}
	
	void setPaperColor(const QColor &color)
	{
		if (color == paperColor)
			return;

		paperColor = color;
		if ( m_outputDev == NULL )
			return;

		switch ( m_backend )
		{
			case Document::SplashBackend:
			{
#if defined(HAVE_SPLASH)
				SplashOutputDev *splash_output = static_cast<SplashOutputDev *>( m_outputDev );
				SplashColor bgColor;
				bgColor[0] = paperColor.red();
				bgColor[1] = paperColor.green();
				bgColor[2] = paperColor.blue();
				splash_output->setPaperColor(bgColor);
#endif
				break;
			}
			default: ;
		}
	}
	
	void fillMembers()
	{
		m_fontInfoScanner = new FontInfoScanner(doc);
		int numEmb = doc->getCatalog()->numEmbeddedFiles();
		if (!(0 == numEmb)) {
			// we have some embedded documents, build the list
			for (int yalv = 0; yalv < numEmb; ++yalv) {
				EmbFile *ef = doc->getCatalog()->embeddedFile(yalv);
				m_embeddedFiles.append(new EmbeddedFile(ef));
				delete ef;
			}
		}
	}

	PDFDoc *doc;
	QByteArray fileContents;
	bool locked;
	FontInfoScanner *m_fontInfoScanner;
	Document::RenderBackend m_backend;
	OutputDev *m_outputDev;
	QList<EmbeddedFile*> m_embeddedFiles;
	QColor paperColor;
	int m_hints;
	static int count;
    };

    class FontInfoData
    {
	public:
		FontInfoData( const FontInfoData &fid )
		{
			fontName = fid.fontName;
			fontFile = fid.fontFile;
			isEmbedded = fid.isEmbedded;
			isSubset = fid.isSubset;
			type = fid.type;
		}
		
		FontInfoData( ::FontInfo* fi )
		{
			if (fi->getName()) fontName = fi->getName()->getCString();
			if (fi->getFile()) fontFile = fi->getFile()->getCString();
			isEmbedded = fi->getEmbedded();
			isSubset = fi->getSubset();
			type = (Poppler::FontInfo::Type)fi->getType();
		}

		QString fontName;
		QString fontFile;
		bool isEmbedded;
		bool isSubset;
		FontInfo::Type type;
    };

    class TextBoxData
    {
	public:
		QString text;
		QRectF bBox;
		TextBox *nextWord;
		QVector<double> edge;	// "near" edge x or y coord of each char
					//   (plus one extra entry for the last char)
		bool hasSpaceAfter;
    };

    class FormFieldData
    {
	public:
		FormFieldData(DocumentData *_doc, ::Page *p, ::FormWidget *w) :
		doc(_doc), page(p), fm(w), flags(0), annoflags(0)
		{
		}

		Qt::Alignment textAlignment(Object *obj) const
		{
			Object tmp;
			int align = 0;
			if (obj->dictLookup("Q", &tmp)->isInt())
			{
				align = tmp.getInt();
			}
			tmp.free();
			Qt::Alignment qtalign;
			switch ( align )
			{
				case 1:
					qtalign = Qt::AlignHCenter;
					break;
				case 2:
					qtalign = Qt::AlignRight;
					break;
				case 0:
				default:
					qtalign = Qt::AlignLeft;
			}
			return qtalign;
		}

		DocumentData *doc;
		::Page *page;
		::FormWidget *fm;
		QRectF box;
		int flags;
		int annoflags;
    };

}

#endif
