/* poppler-document.cc: qt interface to poppler
 * Copyright (C) 2005, Net Integration Technologies, Inc.
 * Copyright (C) 2005, 2008, Brad Hards <bradh@frogmouth.net>
 * Copyright (C) 2005-2010, 2012, 2013, 2015, 2017, 2018, Albert Astals Cid <aacid@kde.org>
 * Copyright (C) 2006-2010, Pino Toscano <pino@kde.org>
 * Copyright (C) 2010, 2011 Hib Eris <hib@hiberis.nl>
 * Copyright (C) 2012 Koji Otani <sho@bbr.jp>
 * Copyright (C) 2012, 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
 * Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
 * Copyright (C) 2014 Adam Reichold <adamreichold@myopera.com>
 * Copyright (C) 2015 William Bader <williambader@hotmail.com>
 * Copyright (C) 2016 Jakub Alba <jakubalba@gmail.com>
 * Copyright (C) 2017 Adrian Johnson <ajohnson@redneon.com>
 * Copyright (C) 2017 Suzuki Toshiya <mpsuzuki@hiroshima-u.ac.jp>
 * Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by the LiMux project of the city of Munich
 *
 * 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 <config.h>
#include <ErrorCodes.h>
#include <GlobalParams.h>
#include <Outline.h>
#include <PDFDoc.h>
#include <Stream.h>
#include <Catalog.h>
#include <ViewerPreferences.h>
#include <DateInfo.h>
#include <GfxState.h>

#include <QtCore/QDebug>
#include <QtCore/QFile>
#include <QtCore/QByteArray>

#include "poppler-private.h"
#include "poppler-page-private.h"

#if defined(USE_CMS)
#include <lcms2.h>
#endif

namespace Poppler {

  int DocumentData::count = 0;

  Document *Document::load(const QString &filePath, const QByteArray &ownerPassword,
			   const QByteArray &userPassword)
    {
	DocumentData *doc = new DocumentData(filePath, 
					     new GooString(ownerPassword.data()),
					     new GooString(userPassword.data()));
	return DocumentData::checkDocument(doc);
    }

    Document *Document::loadFromData(const QByteArray &fileContents,
			      const QByteArray &ownerPassword,
			      const QByteArray &userPassword)
    {
	// create stream
	DocumentData *doc = new DocumentData(fileContents,
					     new GooString(ownerPassword.data()),
					     new GooString(userPassword.data()));
	return DocumentData::checkDocument(doc);
    }
    
    Document *DocumentData::checkDocument(DocumentData *doc)
    {
	Document *pdoc;
	if (doc->doc->isOk() || doc->doc->getErrorCode() == errEncrypted) {
		pdoc = new Document(doc);
		if (doc->doc->getErrorCode() == errEncrypted)
			pdoc->m_doc->locked = true;
		else
		{
			pdoc->m_doc->locked = false;
			pdoc->m_doc->fillMembers();
		}
		return pdoc;
	}
	else
	{
		delete doc;
	}
	return nullptr;
    }

    Document::Document(DocumentData *dataA)
    {
	m_doc = dataA;
    }

    Document::~Document()
    {
	delete m_doc;
    }

    Page *Document::page(int index) const
    {
	Page *page = new Page(m_doc, index);
	if (page->m_page->page == nullptr) {
	  delete page;
	  return nullptr;
	}

	return page;
    }

    bool Document::isLocked() const
    {
	return m_doc->locked;
    }

    bool Document::unlock(const QByteArray &ownerPassword,
			  const QByteArray &userPassword)
    {
	if (m_doc->locked) {
	    /* racier then it needs to be */
	    DocumentData *doc2;
	    if (!m_doc->fileContents.isEmpty())
	    {
		doc2 = new DocumentData(m_doc->fileContents,
					new GooString(ownerPassword.data()),
					new GooString(userPassword.data()));
	    }
	    else
	    {
		doc2 = new DocumentData(m_doc->m_filePath,
					new GooString(ownerPassword.data()),
					new GooString(userPassword.data()));
	    }
	    if (!doc2->doc->isOk()) {
		delete doc2;
	    } else {
		delete m_doc;
		m_doc = doc2;
		m_doc->locked = false;
		m_doc->fillMembers();
	    }
	}
	return m_doc->locked;
    }

    Document::PageMode Document::pageMode() const
    {
	switch (m_doc->doc->getCatalog()->getPageMode()) {
	case Catalog::pageModeNone:
	    return UseNone;
	case Catalog::pageModeOutlines:
	    return UseOutlines;
	case Catalog::pageModeThumbs:
	    return UseThumbs;
	case Catalog::pageModeFullScreen:
	    return FullScreen;
	case Catalog::pageModeOC:
	    return UseOC;
	case Catalog::pageModeAttach:
	    return UseAttach;
	default:
	    return UseNone;
	}
    }

    Document::PageLayout Document::pageLayout() const
    {
	switch (m_doc->doc->getCatalog()->getPageLayout()) {
	case Catalog::pageLayoutNone:
	    return NoLayout;
	case Catalog::pageLayoutSinglePage:
	    return SinglePage;
	case Catalog::pageLayoutOneColumn:
	    return OneColumn;
	case Catalog::pageLayoutTwoColumnLeft:
	    return TwoColumnLeft;
	case Catalog::pageLayoutTwoColumnRight:
	    return TwoColumnRight;
	case Catalog::pageLayoutTwoPageLeft:
	    return TwoPageLeft;
	case Catalog::pageLayoutTwoPageRight:
	    return TwoPageRight;
	default:
	    return NoLayout;
	}
    }

    Qt::LayoutDirection Document::textDirection() const
    {
        if (!m_doc->doc->getCatalog()->getViewerPreferences())
            return Qt::LayoutDirectionAuto;

        switch (m_doc->doc->getCatalog()->getViewerPreferences()->getDirection()) {
        case ViewerPreferences::directionL2R:
            return Qt::LeftToRight;
        case ViewerPreferences::directionR2L:
            return Qt::RightToLeft;
        default:
            return Qt::LayoutDirectionAuto;
        }
    }

    int Document::numPages() const
    {
	return m_doc->doc->getNumPages();
    }

    QList<FontInfo> Document::fonts() const
    {
	QList<FontInfo> ourList;
	FontIterator it( 0, m_doc );
	while ( it.hasNext() )
	{
		ourList += it.next();
	}
	return ourList;
    }

    QList<EmbeddedFile*> Document::embeddedFiles() const
    {
	return m_doc->m_embeddedFiles;
    }

    FontIterator* Document::newFontIterator( int startPage ) const
    {
	return new FontIterator( startPage, m_doc );
    }

    QByteArray Document::fontData(const FontInfo &fi) const
    {
	QByteArray result;
	if (fi.isEmbedded())
	{
		XRef *xref = m_doc->doc->getXRef()->copy();

		Object refObj(fi.m_data->embRef.num, fi.m_data->embRef.gen);
		Object strObj = refObj.fetch(xref);
		if (strObj.isStream())
		{
			int c;
			strObj.streamReset();
			while ((c = strObj.streamGetChar()) != EOF)
			{
				result.append((char)c);
			}
			strObj.streamClose();
		}
		delete xref;
	}
	return result;
    }

    QString Document::info( const QString & type ) const
    {
	if (m_doc->locked) {
	    return QString();
	}

	QScopedPointer<GooString> goo(m_doc->doc->getDocInfoStringEntry(type.toLatin1().constData()));
	return UnicodeParsedString(goo.data());
    }

    bool Document::setInfo( const QString & key, const QString & val )
    {
	if (m_doc->locked) {
	    return false;
	}

	GooString *goo = QStringToUnicodeGooString(val);
	m_doc->doc->setDocInfoStringEntry(key.toLatin1().constData(), goo);
	return true;
    }

    QString Document::title() const
    {
	if (m_doc->locked) {
	    return QString();
	}

	QScopedPointer<GooString> goo(m_doc->doc->getDocInfoTitle());
	return UnicodeParsedString(goo.data());
    }

    bool Document::setTitle( const QString & val )
    {
	if (m_doc->locked) {
	    return false;
	}

	m_doc->doc->setDocInfoTitle(QStringToUnicodeGooString(val));
	return true;
    }

    QString Document::author() const
    {
	if (m_doc->locked) {
	    return QString();
	}

	QScopedPointer<GooString> goo(m_doc->doc->getDocInfoAuthor());
	return UnicodeParsedString(goo.data());
    }

    bool Document::setAuthor( const QString & val )
    {
	if (m_doc->locked) {
	    return false;
	}

	m_doc->doc->setDocInfoAuthor(QStringToUnicodeGooString(val));
	return true;
    }

    QString Document::subject() const
    {
	if (m_doc->locked) {
	    return QString();
	}

	QScopedPointer<GooString> goo(m_doc->doc->getDocInfoSubject());
	return UnicodeParsedString(goo.data());
    }

    bool Document::setSubject( const QString & val )
    {
	if (m_doc->locked) {
	    return false;
	}

	m_doc->doc->setDocInfoSubject(QStringToUnicodeGooString(val));
	return true;
    }

    QString Document::keywords() const
    {
	if (m_doc->locked) {
	    return QString();
	}

	QScopedPointer<GooString> goo(m_doc->doc->getDocInfoKeywords());
	return UnicodeParsedString(goo.data());
    }

    bool Document::setKeywords( const QString & val )
    {
	if (m_doc->locked) {
	    return false;
	}

	m_doc->doc->setDocInfoKeywords(QStringToUnicodeGooString(val));
	return true;
    }

    QString Document::creator() const
    {
	if (m_doc->locked) {
	    return QString();
	}

	QScopedPointer<GooString> goo(m_doc->doc->getDocInfoCreator());
	return UnicodeParsedString(goo.data());
    }

    bool Document::setCreator( const QString & val )
    {
	if (m_doc->locked) {
	    return false;
	}

	m_doc->doc->setDocInfoCreator(QStringToUnicodeGooString(val));
	return true;
    }

    QString Document::producer() const
    {
	if (m_doc->locked) {
	    return QString();
	}

	QScopedPointer<GooString> goo(m_doc->doc->getDocInfoProducer());
	return UnicodeParsedString(goo.data());
    }

    bool Document::setProducer( const QString & val )
    {
	if (m_doc->locked) {
	    return false;
	}

	m_doc->doc->setDocInfoProducer(QStringToUnicodeGooString(val));
	return true;
    }

    bool Document::removeInfo()
    {
	if (m_doc->locked) {
	    return false;
	}

	m_doc->doc->removeDocInfo();
	return true;
    }

    QStringList Document::infoKeys() const
    {
	QStringList keys;

	if ( m_doc->locked )
	    return QStringList();

	QScopedPointer<XRef> xref(m_doc->doc->getXRef()->copy());
	if (!xref)
		return QStringList();
	Object info = xref->getDocInfo();
	if ( !info.isDict() )
	    return QStringList();

	Dict *infoDict = info.getDict();
	// somehow iterate over keys in infoDict
	keys.reserve(infoDict->getLength());
	for( int i=0; i < infoDict->getLength(); ++i ) {
	    keys.append( QString::fromLatin1(infoDict->getKey(i)) );
	}

	return keys;
    }

    QDateTime Document::date( const QString & type ) const
    {
	if (m_doc->locked) {
	    return QDateTime();
	}

	QScopedPointer<GooString> goo(m_doc->doc->getDocInfoStringEntry(type.toLatin1().constData()));
	QString str = UnicodeParsedString(goo.data());
	return Poppler::convertDate(str.toLatin1().constData());
    }

    bool Document::setDate( const QString & key, const QDateTime & val )
    {
	if (m_doc->locked) {
	    return false;
	}

	m_doc->doc->setDocInfoStringEntry(key.toLatin1().constData(), QDateTimeToUnicodeGooString(val));
	return true;
    }

    QDateTime Document::creationDate() const
    {
	if (m_doc->locked) {
	    return QDateTime();
	}

	QScopedPointer<GooString> goo(m_doc->doc->getDocInfoCreatDate());
	QString str = UnicodeParsedString(goo.data());
	return Poppler::convertDate(str.toLatin1().constData());
    }

    bool Document::setCreationDate( const QDateTime & val )
    {
	if (m_doc->locked) {
	    return false;
	}

	m_doc->doc->setDocInfoCreatDate(QDateTimeToUnicodeGooString(val));
	return true;
    }

    QDateTime Document::modificationDate() const
    {
	if (m_doc->locked) {
	    return QDateTime();
	}

	QScopedPointer<GooString> goo(m_doc->doc->getDocInfoModDate());
	QString str = UnicodeParsedString(goo.data());
	return Poppler::convertDate(str.toLatin1().constData());
    }

    bool Document::setModificationDate( const QDateTime & val )
    {
	if (m_doc->locked) {
	    return false;
	}

	m_doc->doc->setDocInfoModDate(QDateTimeToUnicodeGooString(val));
	return true;
    }

    bool Document::isEncrypted() const
    {
	return m_doc->doc->isEncrypted();
    }

    bool Document::isLinearized() const
    {
	return m_doc->doc->isLinearized();
    }

    bool Document::okToPrint() const
    {
	return m_doc->doc->okToPrint();
    }

    bool Document::okToPrintHighRes() const
    {
	return m_doc->doc->okToPrintHighRes();
    }

    bool Document::okToChange() const
    {
	return m_doc->doc->okToChange();
    }

    bool Document::okToCopy() const
    {
	return m_doc->doc->okToCopy();
    }

    bool Document::okToAddNotes() const
    {
	return m_doc->doc->okToAddNotes();
    }

    bool Document::okToFillForm() const
    {
	return m_doc->doc->okToFillForm();
    }

    bool Document::okToCreateFormFields() const
    {
	return ( okToFillForm() && okToChange() );
    }

    bool Document::okToExtractForAccessibility() const
    {
	return m_doc->doc->okToAccessibility();
    }

    bool Document::okToAssemble() const
    {
	return m_doc->doc->okToAssemble();
    }

    void Document::getPdfVersion(int *major, int *minor) const
    {
	if (major)
	    *major = m_doc->doc->getPDFMajorVersion();
	if (minor)
	    *minor = m_doc->doc->getPDFMinorVersion();
    }

    Page *Document::page(const QString &label) const
    {
	GooString label_g(label.toLatin1().data());
	int index;

	if (!m_doc->doc->getCatalog()->labelToIndex (&label_g, &index))
	    return nullptr;

	return page(index);
    }

    bool Document::hasEmbeddedFiles() const
    {
	return (!(0 == m_doc->doc->getCatalog()->numEmbeddedFiles()));
    }
    
    QDomDocument *Document::toc() const
    {
        Outline * outline = m_doc->doc->getOutline();
        if ( !outline )
            return nullptr;

        const GooList * items = outline->getItems();
        if ( !items || items->getLength() < 1 )
            return nullptr;

        QDomDocument *toc = new QDomDocument();
        if ( items->getLength() > 0 )
           m_doc->addTocChildren( toc, toc, items );

        return toc;
    }

    LinkDestination *Document::linkDestination( const QString &name )
    {
        GooString * namedDest = QStringToGooString( name );
        LinkDestinationData ldd(nullptr, namedDest, m_doc, false);
        LinkDestination *ld = new LinkDestination(ldd);
        delete namedDest;
        return ld;
    }
    
    void Document::setPaperColor(const QColor &color)
    {
        m_doc->setPaperColor(color);
    }
    
    void Document::setColorDisplayProfile(void* outputProfileA)
    {
#if defined(USE_CMS)
        GfxColorSpace::setDisplayProfile((cmsHPROFILE)outputProfileA);
#else
        Q_UNUSED(outputProfileA);
#endif
    }

    void Document::setColorDisplayProfileName(const QString &name)
    {
#if defined(USE_CMS)
        GooString *profileName = QStringToGooString( name );
        GfxColorSpace::setDisplayProfileName(profileName);
        delete profileName;
#else
        Q_UNUSED(name);
#endif
    }

    void* Document::colorRgbProfile() const
    {
#if defined(USE_CMS)
        return (void*)GfxColorSpace::getRGBProfile();
#else
        return NULL;
#endif
    }

    void* Document::colorDisplayProfile() const
    {
#if defined(USE_CMS)
       return (void*)GfxColorSpace::getDisplayProfile();
#else
       return NULL;
#endif
    }

    QColor Document::paperColor() const
    {
    	return m_doc->paperColor;
    }

    void Document::setRenderBackend( Document::RenderBackend backend )
    {
        // no need to delete the outputdev as for the moment we always create a splash one
        // as the arthur one does not allow "precaching" due to it's signature
        // delete m_doc->m_outputDev;
        // m_doc->m_outputDev = NULL;
        m_doc->m_backend = backend;
    }

    Document::RenderBackend Document::renderBackend() const
    {
        return m_doc->m_backend;
    }

    QSet<Document::RenderBackend> Document::availableRenderBackends()
    {
        QSet<Document::RenderBackend> ret;
#if defined(HAVE_SPLASH)
        ret << Document::SplashBackend;
#endif
        ret << Document::ArthurBackend;
        return ret;
    }

    void Document::setRenderHint( Document::RenderHint hint, bool on )
    {
        const bool touchesOverprinting = hint & Document::OverprintPreview;
        
        int hintForOperation = hint;
        if (touchesOverprinting && !isOverprintPreviewAvailable())
            hintForOperation = hintForOperation & ~(int)Document::OverprintPreview;

        if ( on )
            m_doc->m_hints |= hintForOperation;
        else
            m_doc->m_hints &= ~hintForOperation;

    }

    Document::RenderHints Document::renderHints() const
    {
        return Document::RenderHints( m_doc->m_hints );
    }

    PSConverter *Document::psConverter() const
    {
        return new PSConverter(m_doc);
    }

    PDFConverter *Document::pdfConverter() const
    {
        return new PDFConverter(m_doc);
    }

    QString Document::metadata() const
    {
        QString result;
        Catalog *catalog = m_doc->doc->getCatalog();
        if (catalog && catalog->isOk())
        {
            GooString *s = catalog->readMetadata();
            if (s) result = UnicodeParsedString(s);
            delete s;
        }
        return result;
    }

    bool Document::hasOptionalContent() const
    {
        return ( m_doc->doc->getOptContentConfig() && m_doc->doc->getOptContentConfig()->hasOCGs() );
    }

    OptContentModel *Document::optionalContentModel()
    {
        if (m_doc->m_optContentModel.isNull()) {
	    m_doc->m_optContentModel = new OptContentModel(m_doc->doc->getOptContentConfig(), nullptr);
	}
        return (OptContentModel *)m_doc->m_optContentModel;
    }

    QStringList Document::scripts() const
    {
        Catalog *catalog = m_doc->doc->getCatalog();
        const int numScripts = catalog->numJS();
        QStringList scripts;
        for (int i = 0; i < numScripts; ++i) {
            GooString *s = catalog->getJS(i);
            if (s) {
                scripts.append(UnicodeParsedString(s));
                delete s;
            }
        }
        return scripts;
    }

    bool Document::getPdfId(QByteArray *permanentId, QByteArray *updateId) const
    {
        GooString gooPermanentId;
        GooString gooUpdateId;

        if (!m_doc->doc->getID(permanentId ? &gooPermanentId : nullptr, updateId ? &gooUpdateId : nullptr))
            return false;

        if (permanentId)
            *permanentId = gooPermanentId.getCString();
        if (updateId)
            *updateId = gooUpdateId.getCString();

        return true;
    }

    Document::FormType Document::formType() const
    {
        switch ( m_doc->doc->getCatalog()->getFormType() )
        {
            case Catalog::NoForm:
                return Document::NoForm;
            case Catalog::AcroForm:
                return Document::AcroForm;
            case Catalog::XfaForm:
                return Document::XfaForm;
        }

        return Document::NoForm; // make gcc happy
    }

    QVector<int> Document::formCalculateOrder() const
    {
        QVector<int> result;

        Form *form = m_doc->doc->getCatalog()->getForm();
        const std::vector<Ref> &calculateOrder = form->getCalculateOrder();
        for (uint i = 0; i < calculateOrder.size(); ++i) {
            FormWidget *w = form->findWidgetByRef(calculateOrder[i]);
            if (w) {
                result << w->getID();
            }
        }

        return result;
    }

    QDateTime convertDate( const char *dateString )
    {
        int year, mon, day, hour, min, sec, tzHours, tzMins;
        char tz;

        if ( parseDateString( dateString, &year, &mon, &day, &hour, &min, &sec, &tz, &tzHours, &tzMins ) )
        {
            QDate d( year, mon, day );
            QTime t( hour, min, sec );
            if ( d.isValid() && t.isValid() ) {
                QDateTime dt( d, t, Qt::UTC );
                if ( tz ) {
                    // then we have some form of timezone
                    if ( 'Z' == tz  ) {
                        // We are already at UTC
                    } else if ( '+' == tz ) {
                        // local time is ahead of UTC
                        dt = dt.addSecs(-1*((tzHours*60)+tzMins)*60);
                    } else if ( '-' == tz ) {
                        // local time is behind UTC
                        dt = dt.addSecs(((tzHours*60)+tzMins)*60);
                    } else {
                        qWarning("unexpected tz val");
                    }
                }
		return dt;
            }
        }
        return QDateTime();
    }

    QDateTime convertDate( char *dateString )
    {
        return convertDate( (const char *) dateString );
    }


    bool isCmsAvailable()
    {
#if defined(USE_CMS)
        return true;
#else
        return false;
#endif
    }

    bool isOverprintPreviewAvailable() {
#ifdef SPLASH_CMYK
        return true;
#else
        return false;
#endif
   }

}

