/* poppler-page.cc: qt interface to poppler
 * Copyright (C) 2005, Net Integration Technologies, Inc.
 *
 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#define UNSTABLE_POPPLER_QT4
#include <poppler-qt4.h>
#include <QtCore/QFile>
#include <QtCore/QMap>
#include <QtGui/QImage>
#include <QtGui/QPixmap>
#include <GlobalParams.h>
#include <PDFDoc.h>
#include <Catalog.h>
#include <ErrorCodes.h>
#include <ArthurOutputDev.h>
#include <SplashOutputDev.h>
#include <TextOutputDev.h>
#include <splash/SplashBitmap.h>

#include "poppler-private.h"
#include "poppler-page-transition-private.h"
#include "poppler-annotation-helper.h"

namespace Poppler {

class PageData {
  public:
  const Document *parentDoc;
  int index;
  PageTransition *transition;
};

Page::Page(const Document *doc, int index) {
  m_page = new PageData();
  m_page->index = index;
  m_page->parentDoc = doc;
  m_page->transition = 0;
}

Page::~Page()
{
  delete m_page->transition;
  delete m_page;
}

QImage Page::splashRenderToImage(double xres, double yres, int x, int y, int w, int h, bool doLinks) const
{
  SplashOutputDev *output_dev = m_page->parentDoc->m_doc->getSplashOutputDev();
  
  m_page->parentDoc->m_doc->doc.displayPageSlice(output_dev, m_page->index + 1, xres, yres,
						 0, false, true, doLinks, x, y, w, h);
  
  SplashBitmap *bitmap = output_dev->getBitmap ();
  int bw = bitmap->getWidth();
  int bh = bitmap->getHeight();
  
  SplashColorPtr dataPtr = output_dev->getBitmap()->getDataPtr();
  
  if (QSysInfo::BigEndian == QSysInfo::ByteOrder)
  {
    uchar c;
    int count = bw * bh * 4;
    for (int k = 0; k < count; k += 4)
    {
      c = dataPtr[k];
      dataPtr[k] = dataPtr[k+3];
      dataPtr[k+3] = c;

      c = dataPtr[k+1];
      dataPtr[k+1] = dataPtr[k+2];
      dataPtr[k+2] = c;
    }
  }
  
  // construct a qimage SHARING the raw bitmap data in memory
  QImage img( dataPtr, bw, bh, QImage::Format_ARGB32 );
  img = img.copy();
  // unload underlying xpdf bitmap
  output_dev->startPage( 0, NULL );

  return img;
}

QPixmap *Page::splashRenderToPixmap(double xres, double yres, int x, int y, int w, int h, bool doLinks) const
{
  QImage img = splashRenderToImage(xres, yres, x, y, w, h, doLinks);

  // Turn the QImage into a QPixmap
  QPixmap* out = new QPixmap(QPixmap::fromImage(img));

  return out;
}

void Page::renderToPixmap(QPixmap *pixmap, double xres, double yres) const
{
  QPainter* painter = new QPainter(pixmap);
  painter->setRenderHint(QPainter::Antialiasing);
  ArthurOutputDev output_dev(painter);
  output_dev.startDoc(m_page->parentDoc->m_doc->doc.getXRef ());
  m_page->parentDoc->m_doc->doc.displayPageSlice(&output_dev,
						 m_page->index + 1,
						 xres,
						 yres,
						 0,
						 false,
						 true,
						 false,
						 -1,
						 -1,
						 -1,
						 -1);
  painter->end();
}

QString Page::text(const QRectF &r) const
{
  TextOutputDev *output_dev;
  GooString *s;
  PDFRectangle *rect;
  QString result;
  ::Page *p;
  
  output_dev = new TextOutputDev(0, gFalse, gFalse, gFalse);
  m_page->parentDoc->m_doc->doc.displayPageSlice(output_dev, m_page->index + 1, 72, 72,
      0, false, true, false, -1, -1, -1, -1);
  p = m_page->parentDoc->m_doc->doc.getCatalog()->getPage(m_page->index + 1);
  if (r.isNull())
  {
    rect = p->getCropBox();
    s = output_dev->getText(rect->x1, rect->y1, rect->x2, rect->y2);
  }
  else
  {
    double height, y1, y2;
    height = p->getCropHeight();
    y1 = height - r.top();
    y2 = height - r.bottom();
    s = output_dev->getText(r.left(), y1, r.right(), y2);
  }

  result = QString::fromUtf8(s->getCString());

  delete output_dev;
  delete s;
  return result;
}

bool Page::search(const QString &text, QRectF &rect, SearchDirection direction, SearchMode caseSensitive) const
{
  const QChar * str = text.unicode();
  int len = text.length();
  QVector<Unicode> u(len);
  for (int i = 0; i < len; ++i) u[i] = str[i].unicode();

  GBool sCase;
  if (caseSensitive == CaseSensitive) sCase = gTrue;
  else sCase = gFalse;

  bool found = false;
  double sLeft, sTop, sRight, sBottom;
  sLeft = rect.left();
  sTop = rect.top();
  sRight = rect.right();
  sBottom = rect.bottom();

  // fetch ourselves a textpage
  TextOutputDev td(NULL, gTrue, gFalse, gFalse);
  m_page->parentDoc->m_doc->doc.displayPage( &td, m_page->index + 1, 72, 72, 0, false, true, false );
  TextPage *textPage=td.takeText();

  if (direction == FromTop)
    found = textPage->findText( u.data(), len, 
            gTrue, gTrue, gFalse, gFalse, sCase, gFalse, &sLeft, &sTop, &sRight, &sBottom );
  else if ( direction == NextResult )
    found = textPage->findText( u.data(), len, 
            gFalse, gTrue, gTrue, gFalse, sCase, gFalse, &sLeft, &sTop, &sRight, &sBottom );
  else if ( direction == PreviousResult )
    found = textPage->findText( u.data(), len, 
            gTrue, gFalse, gFalse, gTrue, sCase, gFalse, &sLeft, &sTop, &sRight, &sBottom );

  delete textPage;

  rect.setLeft( sLeft );
  rect.setTop( sTop );
  rect.setRight( sRight );
  rect.setBottom( sBottom );

  return found;
}

QList<TextBox*> Page::textList() const
{
  TextOutputDev *output_dev;
  
  QList<TextBox*> output_list;
  
  output_dev = new TextOutputDev(0, gFalse, gFalse, gFalse);

  m_page->parentDoc->m_doc->doc.displayPageSlice(output_dev, m_page->index + 1, 72, 72,
      0, false, false, false, -1, -1, -1, -1);

  TextWordList *word_list = output_dev->makeWordList();
  
  if (!word_list) {
    delete output_dev;
    return output_list;
  }
  
  QMap<TextWord *, TextBox*> wordBoxMap;
  
  for (int i = 0; i < word_list->getLength(); i++) {
    TextWord *word = word_list->get(i);
    QString string = QString::fromUtf8(word->getText()->getCString());
    double xMin, yMin, xMax, yMax;
    word->getBBox(&xMin, &yMin, &xMax, &yMax);
    
    TextBox* text_box = new TextBox(string, QRectF(xMin, yMin, xMax-xMin, yMax-yMin));
    text_box->m_data->hasSpaceAfter = word->hasSpaceAfter() == gTrue;
    text_box->m_data->edge.reserve(word->getLength() + 1);
    for (int j = 0; j <= word->getLength(); ++j) text_box->m_data->edge.append(word->getEdge(j));
    
    wordBoxMap.insert(word, text_box);
    
    output_list.append(text_box);
  }
  
  for (int i = 0; i < word_list->getLength(); i++) {
    TextWord *word = word_list->get(i);
    TextBox* text_box = wordBoxMap[word];
    text_box->m_data->nextWord = wordBoxMap[word->nextWord()];
  }
  
  delete word_list;
  delete output_dev;
  
  return output_list;
}

PageTransition *Page::transition() const
{
  if (!m_page->transition) {
    Object o;
    PageTransitionParams params;
    params.dictObj = m_page->parentDoc->m_doc->doc.getCatalog()->getPage(m_page->index + 1)->getTrans(&o);
    if (params.dictObj->isDict()) m_page->transition = new PageTransition(params);
    o.free();
  }
  return m_page->transition;
}

QSizeF Page::pageSizeF() const
{
  ::Page *p;
  
  p = m_page->parentDoc->m_doc->doc.getCatalog()->getPage(m_page->index + 1);
  if ( ( Page::Landscape == orientation() ) || (Page::Seascape == orientation() ) ) {
      return QSizeF( p->getCropHeight(), p->getCropWidth() );
  } else {
    return QSizeF( p->getCropWidth(), p->getCropHeight() );
  }
}

QSize Page::pageSize() const
{
  return QSize( (int)pageSizeF().width(), (int)pageSizeF().height() );
}

Page::Orientation Page::orientation() const
{
  int rotation = m_page->parentDoc->m_doc->doc.getCatalog()->getPage(m_page->index + 1)->getRotate();
  switch (rotation) {
  case 90:
    return Page::Landscape;
    break;
  case 180:
    return Page::UpsideDown;
    break;
  case 270:
    return Page::Seascape;
    break;
  default:
    return Page::Portrait;
  }
}

void Page::defaultCTM(double *CTM, double dpiX, double dpiY, int rotate, bool upsideDown)
{
  ::Page *p;
  p = m_page->parentDoc->m_doc->doc.getCatalog()->getPage(m_page->index + 1);
  p->getDefaultCTM(CTM, dpiX, dpiY, rotate, upsideDown);
}

QList<Link*> Page::links() const
{
  QList<Link*> popplerLinks;

  Links *xpdfLinks = m_page->parentDoc->m_doc->doc.takeLinks();
  for (int i = 0; i < xpdfLinks->getNumLinks(); ++i)
  {
    ::Link *xpdfLink = xpdfLinks->getLink(i);
    
    double left, top, right, bottom;
    int leftAux, topAux, rightAux, bottomAux;
    xpdfLink->getRect( &left, &top, &right, &bottom );
    QRectF linkArea;
    
    m_page->parentDoc->m_doc->m_splashOutputDev->cvtUserToDev( left, top, &leftAux, &topAux );
    m_page->parentDoc->m_doc->m_splashOutputDev->cvtUserToDev( right, bottom, &rightAux, &bottomAux );
    linkArea.setLeft(leftAux);
    linkArea.setTop(topAux);
    linkArea.setRight(rightAux);
    linkArea.setBottom(bottomAux);

    if (!xpdfLink->isOk()) continue;

    Link *popplerLink = NULL;
    ::LinkAction *a = xpdfLink->getAction();
    if ( a )
    {
      switch ( a->getKind() )
      {
        case actionGoTo:
        {
          LinkGoTo * g = (LinkGoTo *) a;
          // create link: no ext file, namedDest, object pointer
          popplerLink = new LinkGoto( linkArea, QString::null, LinkDestination( LinkDestinationData(g->getDest(), g->getNamedDest(), m_page->parentDoc->m_doc ) ) );
        }
        break;

        case actionGoToR:
        {
          LinkGoToR * g = (LinkGoToR *) a;
          // copy link file
          const char * fileName = g->getFileName()->getCString();
          // ceate link: fileName, namedDest, object pointer
          popplerLink = new LinkGoto( linkArea, (QString)fileName, LinkDestination( LinkDestinationData(g->getDest(), g->getNamedDest(), m_page->parentDoc->m_doc ) ) );
        }
        break;

        case actionLaunch:
	{
          LinkLaunch * e = (LinkLaunch *)a;
          GooString * p = e->getParams();
          popplerLink = new LinkExecute( linkArea, e->getFileName()->getCString(), p ? p->getCString() : 0 );
	}
        break;

        case actionNamed:
	{
          const char * name = ((LinkNamed *)a)->getName()->getCString();
          if ( !strcmp( name, "NextPage" ) )
              popplerLink = new LinkAction( linkArea, LinkAction::PageNext );
          else if ( !strcmp( name, "PrevPage" ) )
              popplerLink = new LinkAction( linkArea, LinkAction::PagePrev );
          else if ( !strcmp( name, "FirstPage" ) )
              popplerLink = new LinkAction( linkArea, LinkAction::PageFirst );
          else if ( !strcmp( name, "LastPage" ) )
              popplerLink = new LinkAction( linkArea, LinkAction::PageLast );
          else if ( !strcmp( name, "GoBack" ) )
              popplerLink = new LinkAction( linkArea, LinkAction::HistoryBack );
          else if ( !strcmp( name, "GoForward" ) )
              popplerLink = new LinkAction( linkArea, LinkAction::HistoryForward );
          else if ( !strcmp( name, "Quit" ) )
              popplerLink = new LinkAction( linkArea, LinkAction::Quit );
          else if ( !strcmp( name, "GoToPage" ) )
              popplerLink = new LinkAction( linkArea, LinkAction::GoToPage );
          else if ( !strcmp( name, "Find" ) )
              popplerLink = new LinkAction( linkArea, LinkAction::Find );
          else if ( !strcmp( name, "FullScreen" ) )
              popplerLink = new LinkAction( linkArea, LinkAction::Presentation );
          else if ( !strcmp( name, "Close" ) )
          {
              // acroread closes the document always, doesnt care whether 
              // its presentation mode or not
              // popplerLink = new LinkAction( linkArea, LinkAction::EndPresentation );
              popplerLink = new LinkAction( linkArea, LinkAction::Close );
          }
          else
          {
                // TODO
          }
	}
        break;

        case actionURI:
	{
          popplerLink = new LinkBrowse( linkArea, ((LinkURI *)a)->getURI()->getCString() );
	}
        break;

        case actionMovie:
/*      TODO this (Movie link)
          m_type = Movie;
          LinkMovie * m = (LinkMovie *) a;
          // copy Movie parameters (2 IDs and a const char *)
          Ref * r = m->getAnnotRef();
          m_refNum = r->num;
          m_refGen = r->gen;
          copyString( m_uri, m->getTitle()->getCString() );
*/      break;

        case actionUnknown:
        break;
      }
    }
    
    if (popplerLink)
    {
      popplerLinks.append(popplerLink);
    }
  }

  delete xpdfLinks;
  
  return popplerLinks;
}

QList<Annotation*> Page::annotations() const
{
    Object annotArray;
    ::Page *pdfPage = m_page->parentDoc->m_doc->doc.getCatalog()->getPage(m_page->index + 1);
    pdfPage->getAnnots( &annotArray );
    if ( !annotArray.isArray() || annotArray.arrayGetLength() < 1 )
        return QList<Annotation*>();

    // ID to Annotation/PopupWindow maps
    QMap< int, Annotation * > annotationsMap;
    QMap< int, PopupWindow * > popupsMap;
    // lists of Windows and Revisions that needs resolution
    QLinkedList< ResolveRevision > resolveRevList;
    QLinkedList< ResolveWindow > resolvePopList;
    QLinkedList< PostProcessText > ppTextList;

    // build a normalized transform matrix for this page at 100% scale
    GfxState * gfxState = new GfxState( 72.0, 72.0, pdfPage->getMediaBox(), pdfPage->getRotate(), gTrue );
    double * gfxCTM = gfxState->getCTM();
    double MTX[6];
    for ( int i = 0; i < 6; i+=2 )
    {
        MTX[i] = gfxCTM[i] / pdfPage->getCropWidth();
        MTX[i+1] = gfxCTM[i+1] / pdfPage->getCropHeight();
    }
    delete gfxState;

    /** 1 - PARSE ALL ANNOTATIONS AND POPUPS FROM THE PAGE */
    Object annot;
    Object annotRef;    // no need to free this (impl. dependent!)
    uint numAnnotations = annotArray.arrayGetLength();
    for ( uint j = 0; j < numAnnotations; j++ )
    {
        // get the j-th annotation
        annotArray.arrayGet( j, &annot );
        if ( !annot.isDict() )
        {
            qDebug() << "PDFGenerator: annot not dictionary." << endl;
            annot.free();
            continue;
        }

        Annotation * annotation = 0;
        Dict * annotDict = annot.getDict();
        int annotID = annotArray.arrayGetNF( j, &annotRef )->getRefNum();
        bool parseMarkup = true,    // nearly all supported annots are markup
             addToPage = true;      // Popup annots are added to custom queue

        /** 1.1. GET Subtype */
        QString subType;
        XPDFReader::lookupName( annotDict, "Subtype", subType );
        if ( subType.isEmpty() )
        {
            qDebug() << "annot has no Subtype" << endl;
            annot.free();
            continue;
        }

        /** 1.2. CREATE Annotation / PopupWindow and PARSE specific params */
        if ( subType == "Text" || subType == "FreeText" )
        {
            // parse TextAnnotation params
            TextAnnotation * t = new TextAnnotation();
            annotation = t;

            if ( subType == "Text" )
            {
                // -> textType
                t->textType = TextAnnotation::Linked;
                // -> textIcon
                XPDFReader::lookupName( annotDict, "Name", t->textIcon );
                if ( !t->textIcon.isEmpty() )
                {
                    t->textIcon = t->textIcon.toLower();
                    t->textIcon.remove( ' ' );
                }
                // request for postprocessing window geometry
                PostProcessText request;
                request.textAnnotation = t;
                request.opened = false;
                XPDFReader::lookupBool( annotDict, "Open", request.opened );
                ppTextList.append( request );
            }
            else
            {
                // NOTE: please provide testcases for FreeText (don't have any) - Enrico
                // -> textType
                t->textType = TextAnnotation::InPlace;
                // -> textFont
                QString textFormat;
                XPDFReader::lookupString( annotDict, "DA", textFormat );
                // TODO, fill t->textFont using textFormat if not empty
                // -> inplaceAlign
                XPDFReader::lookupInt( annotDict, "Q", t->inplaceAlign );
                // -> inplaceText (simple)
                XPDFReader::lookupString( annotDict, "DS", t->inplaceText );
                // -> inplaceText (complex override)
                XPDFReader::lookupString( annotDict, "RC", t->inplaceText );
                // -> inplaceCallout
                double c[6];
                int n = XPDFReader::lookupNumArray( annotDict, "CL", c, 6 );
                if ( n >= 4 )
                {
                    XPDFReader::transform( MTX, c[0], c[1], t->inplaceCallout[0] );
                    XPDFReader::transform( MTX, c[2], c[3], t->inplaceCallout[1] );
                    if ( n == 6 )
                        XPDFReader::transform( MTX, c[4], c[5], t->inplaceCallout[2] );
                }
                // -> inplaceIntent
                QString intentName;
                XPDFReader::lookupString( annotDict, "IT", intentName );
                if ( intentName == "FreeTextCallout" )
                    t->inplaceIntent = TextAnnotation::Callout;
                else if ( intentName == "FreeTextTypeWriter" )
                    t->inplaceIntent = TextAnnotation::TypeWriter;
            }
        }
        else if ( subType == "Line" || subType == "Polygon" || subType == "PolyLine" )
        {
            // parse LineAnnotation params
            LineAnnotation * l = new LineAnnotation();
            annotation = l;

            // -> linePoints
            double c[100];
            int num = XPDFReader::lookupNumArray( annotDict, (subType == "Line") ? "L" : "Vertices", c, 100 );
            if ( num < 4 || (num % 2) != 0 )
            {
                qDebug() << "L/Vertices wrong fol Line/Poly." << endl;
                delete annotation;
                annot.free();
                continue;
            }
            for ( int i = 0; i < num; i += 2 )
            {
                QPointF p;
                XPDFReader::transform( MTX, c[i], c[i+1], p );
                l->linePoints.push_back( p );
            }
            // -> lineStartStyle, lineEndStyle
            Object leArray;
            annotDict->lookup( "LE", &leArray );
            if ( leArray.isArray() && leArray.arrayGetLength() == 2 )
            {
                // -> lineStartStyle
                Object styleObj;
                leArray.arrayGet( 0, &styleObj );
                if ( styleObj.isName() )
                {
                    const char * name = styleObj.getName();
                    if ( !strcmp( name, "Square" ) )
                        l->lineStartStyle = LineAnnotation::Square;
                    else if ( !strcmp( name, "Circle" ) )
                        l->lineStartStyle = LineAnnotation::Circle;
                    else if ( !strcmp( name, "Diamond" ) )
                        l->lineStartStyle = LineAnnotation::Diamond;
                    else if ( !strcmp( name, "OpenArrow" ) )
                        l->lineStartStyle = LineAnnotation::OpenArrow;
                    else if ( !strcmp( name, "ClosedArrow" ) )
                        l->lineStartStyle = LineAnnotation::ClosedArrow;
                    else if ( !strcmp( name, "None" ) )
                        l->lineStartStyle = LineAnnotation::None;
                    else if ( !strcmp( name, "Butt" ) )
                        l->lineStartStyle = LineAnnotation::Butt;
                    else if ( !strcmp( name, "ROpenArrow" ) )
                        l->lineStartStyle = LineAnnotation::ROpenArrow;
                    else if ( !strcmp( name, "RClosedArrow" ) )
                        l->lineStartStyle = LineAnnotation::RClosedArrow;
                    else if ( !strcmp( name, "Slash" ) )
                        l->lineStartStyle = LineAnnotation::Slash;
                }
                styleObj.free();
                // -> lineEndStyle
                leArray.arrayGet( 1, &styleObj );
                if ( styleObj.isName() )
                {
                    const char * name = styleObj.getName();
                    if ( !strcmp( name, "Square" ) )
                        l->lineEndStyle = LineAnnotation::Square;
                    else if ( !strcmp( name, "Circle" ) )
                        l->lineEndStyle = LineAnnotation::Circle;
                    else if ( !strcmp( name, "Diamond" ) )
                        l->lineEndStyle = LineAnnotation::Diamond;
                    else if ( !strcmp( name, "OpenArrow" ) )
                        l->lineEndStyle = LineAnnotation::OpenArrow;
                    else if ( !strcmp( name, "ClosedArrow" ) )
                        l->lineEndStyle = LineAnnotation::ClosedArrow;
                    else if ( !strcmp( name, "None" ) )
                        l->lineEndStyle = LineAnnotation::None;
                    else if ( !strcmp( name, "Butt" ) )
                        l->lineEndStyle = LineAnnotation::Butt;
                    else if ( !strcmp( name, "ROpenArrow" ) )
                        l->lineEndStyle = LineAnnotation::ROpenArrow;
                    else if ( !strcmp( name, "RClosedArrow" ) )
                        l->lineEndStyle = LineAnnotation::RClosedArrow;
                    else if ( !strcmp( name, "Slash" ) )
                        l->lineEndStyle = LineAnnotation::Slash;
                }
                styleObj.free();
            }
            leArray.free();
            // -> lineClosed
            l->lineClosed = subType == "Polygon";
            // -> lineInnerColor
            XPDFReader::lookupColor( annotDict, "IC", l->lineInnerColor );
            // -> lineLeadingFwdPt
            XPDFReader::lookupNum( annotDict, "LL", l->lineLeadingFwdPt );
            // -> lineLeadingBackPt
            XPDFReader::lookupNum( annotDict, "LLE", l->lineLeadingBackPt );
            // -> lineShowCaption
            XPDFReader::lookupBool( annotDict, "Cap", l->lineShowCaption );
            // -> lineIntent
            QString intentName;
            XPDFReader::lookupString( annotDict, "IT", intentName );
            if ( intentName == "LineArrow" )
                l->lineIntent = LineAnnotation::Arrow;
            else if ( intentName == "LineDimension" )
                l->lineIntent = LineAnnotation::Dimension;
            else if ( intentName == "PolygonCloud" )
                l->lineIntent = LineAnnotation::PolygonCloud;
        }
        else if ( subType == "Square" || subType == "Circle" )
        {
            // parse GeomAnnotation params
            GeomAnnotation * g = new GeomAnnotation();
            annotation = g;

            // -> geomType
            if ( subType == "Square" )
                g->geomType = GeomAnnotation::InscribedSquare;
            else
                g->geomType = GeomAnnotation::InscribedCircle;
            // -> geomInnerColor
            XPDFReader::lookupColor( annotDict, "IC", g->geomInnerColor );
            // TODO RD
        }
        else if ( subType == "Highlight" || subType == "Underline" ||
                  subType == "Squiggly" || subType == "StrikeOut" )
        {
            // parse HighlightAnnotation params
            HighlightAnnotation * h = new HighlightAnnotation();
            annotation = h;

            // -> highlightType
            if ( subType == "Highlight" )
                h->highlightType = HighlightAnnotation::Highlight;
            else if ( subType == "Underline" )
                h->highlightType = HighlightAnnotation::Underline;
            else if ( subType == "Squiggly" )
                h->highlightType = HighlightAnnotation::Squiggly;
            else if ( subType == "StrikeOut" )
                h->highlightType = HighlightAnnotation::StrikeOut;

            // -> highlightQuads
            double c[80];
            int num = XPDFReader::lookupNumArray( annotDict, "QuadPoints", c, 80 );
            if ( num < 8 || (num % 8) != 0 )
            {
                qDebug() << "Wrong QuadPoints for a Highlight annotation." << endl;
                delete annotation;
                annot.free();
                continue;
            }
            for ( int q = 0; q < num; q += 8 )
            {
                HighlightAnnotation::Quad quad;
                for ( int p = 0; p < 4; p++ )
                    XPDFReader::transform( MTX, c[ q + p*2 ], c[ q + p*2 + 1 ], quad.points[ p ] );
                // ### PDF1.6 specs says that point are in ccw order, but in fact
                // points 3 and 4 are swapped in every PDF around!
                QPointF tmpPoint = quad.points[ 2 ];
                quad.points[ 2 ] = quad.points[ 3 ];
                quad.points[ 3 ] = tmpPoint;
                // initialize other oroperties and append quad
                quad.capStart = true;       // unlinked quads are always capped
                quad.capEnd = true;         // unlinked quads are always capped
                quad.feather = 0.1;         // default feather
                h->highlightQuads.append( quad );
            }
        }
        else if ( subType == "Stamp" )
        {
            // parse StampAnnotation params
            StampAnnotation * s = new StampAnnotation();
            annotation = s;

            // -> stampIconName
            XPDFReader::lookupName( annotDict, "Name", s->stampIconName );
        }
        else if ( subType == "Ink" )
        {
            // parse InkAnnotation params
            InkAnnotation * k = new InkAnnotation();
            annotation = k;

            // -> inkPaths
            Object pathsArray;
            annotDict->lookup( "InkList", &pathsArray );
            if ( !pathsArray.isArray() || pathsArray.arrayGetLength() < 1 )
            {
                qDebug() << "InkList not present for ink annot" << endl;
                delete annotation;
                annot.free();
                continue;
            }
            int pathsNumber = pathsArray.arrayGetLength();
            for ( int m = 0; m < pathsNumber; m++ )
            {
                // transform each path in a list of normalized points ..
                QLinkedList<QPointF> localList;
                Object pointsArray;
                pathsArray.arrayGet( m, &pointsArray );
                if ( pointsArray.isArray() )
                {
                    int pointsNumber = pointsArray.arrayGetLength();
                    for ( int n = 0; n < pointsNumber; n+=2 )
                    {
                        // get the x,y numbers for current point
                        Object numObj;
                        double x = pointsArray.arrayGet( n, &numObj )->getNum();
                        numObj.free();
                        double y = pointsArray.arrayGet( n+1, &numObj )->getNum();
                        numObj.free();
                        // add normalized point to localList
                        QPointF np;
                        XPDFReader::transform( MTX, x, y, np );
                        localList.push_back( np );
                    }
                }
                pointsArray.free();
                // ..and add it to the annotation
                k->inkPaths.push_back( localList );
            }
            pathsArray.free();
        }
        else if ( subType == "Popup" )
        {
            // create PopupWindow and add it to the popupsMap
            PopupWindow * popup = new PopupWindow();
            popupsMap[ annotID ] = popup;
            parseMarkup = false;
            addToPage = false;

            // get window specific properties if any
            popup->shown = false;
            XPDFReader::lookupBool( annotDict, "Open", popup->shown );
            // no need to parse parent annotation id
            //XPDFReader::lookupIntRef( annotDict, "Parent", popup->... );

            // use the 'dummy annotation' for getting other parameters
            popup->dummyAnnotation = new Annotation();
            annotation = popup->dummyAnnotation;
        }
        else if ( subType == "Link" )
        {
            // ignore links (this may change in future)
            annot.free();
            continue;
        }
        else
        {
            // MISSING: Caret, FileAttachment, Sound, Movie, Widget,
            //          Screen, PrinterMark, TrapNet, Watermark, 3D
            qDebug() << "annotation '" << subType << "' not supported" << endl;
            annot.free();
            continue;
        }

        /** 1.3. PARSE common parameters */
        // -> boundary
        double r[4];
        if ( XPDFReader::lookupNumArray( annotDict, "Rect", r, 4 ) != 4 )
        {
            qDebug() << "Rect is missing for annotation." << endl;
            annot.free();
            continue;
        }
        // transform annotation rect to uniform coords
        QPointF topLeft, bottomRight;
        XPDFReader::transform( MTX, r[0], r[1], topLeft );
        XPDFReader::transform( MTX, r[2], r[3], bottomRight );
        annotation->boundary.setTopLeft(topLeft);
        annotation->boundary.setBottomRight(bottomRight);
        if ( annotation->boundary.left() > annotation->boundary.right() )
        {
            double aux = annotation->boundary.left();
            annotation->boundary.setLeft(annotation->boundary.right());
            annotation->boundary.setRight(aux);
        }
        if ( annotation->boundary.top() > annotation->boundary.bottom() )
        {
            double aux = annotation->boundary.top();
            annotation->boundary.setTop(annotation->boundary.bottom());
            annotation->boundary.setBottom(aux);
           //annotation->rUnscaledWidth = (r[2] > r[0]) ? r[2] - r[0] : r[0] - r[2];
           //annotation->rUnscaledHeight = (r[3] > r[1]) ? r[3] - r[1] : r[1] - r[3];
        }
        // -> contents
        XPDFReader::lookupString( annotDict, "Contents", annotation->contents );
        // -> uniqueName
        XPDFReader::lookupString( annotDict, "NM", annotation->uniqueName );
        // -> modifyDate (and -> creationDate)
        XPDFReader::lookupDate( annotDict, "M", annotation->modifyDate );
        if ( annotation->creationDate.isNull() && !annotation->modifyDate.isNull() )
            annotation->creationDate = annotation->modifyDate;
        // -> flags: set the external attribute since it's embedded on file
        annotation->flags |= Annotation::External;
        // -> flags
        int flags = 0;
        XPDFReader::lookupInt( annotDict, "F", flags );
        if ( flags & 0x2 )
            annotation->flags |= Annotation::Hidden;
        if ( flags & 0x8 )
            annotation->flags |= Annotation::FixedSize;
        if ( flags & 0x10 )
            annotation->flags |= Annotation::FixedRotation;
        if ( !(flags & 0x4) )
            annotation->flags |= Annotation::DenyPrint;
        if ( flags & 0x40 )
            annotation->flags |= (Annotation::DenyWrite | Annotation::DenyDelete);
        if ( flags & 0x80 )
            annotation->flags |= Annotation::DenyDelete;
        if ( flags & 0x100 )
            annotation->flags |= Annotation::ToggleHidingOnMouse;
        // -> style (Border(old spec), BS, BE)
        double border[3];
        int bn = XPDFReader::lookupNumArray( annotDict, "Border", border, 3 );
        if ( bn == 3 )
        {
            // -> style.xCorners
            annotation->style.xCorners = border[0];
            // -> style.yCorners
            annotation->style.yCorners = border[1];
            // -> style.width
            annotation->style.width = border[2];
        }
        Object bsObj;
        annotDict->lookup( "BS", &bsObj );
        if ( bsObj.isDict() )
        {
            // -> style.width
            XPDFReader::lookupNum( bsObj.getDict(), "W", annotation->style.width );
            // -> style.style
            QString styleName;
            XPDFReader::lookupName( bsObj.getDict(), "S", styleName );
            if ( styleName == "S" )
                annotation->style.style = Annotation::Solid;
            else if ( styleName == "D" )
                annotation->style.style = Annotation::Dashed;
            else if ( styleName == "B" )
                annotation->style.style = Annotation::Beveled;
            else if ( styleName == "I" )
                annotation->style.style = Annotation::Inset;
            else if ( styleName == "U" )
                annotation->style.style = Annotation::Underline;
            // -> style.marks and style.spaces
            Object dashArray;
            bsObj.getDict()->lookup( "D", &dashArray );
            if ( dashArray.isArray() )
            {
                int dashMarks = 3;
                int dashSpaces = 0;
                Object intObj;
                dashArray.arrayGet( 0, &intObj );
                if ( intObj.isInt() )
                    dashMarks = intObj.getInt();
                intObj.free();
                dashArray.arrayGet( 1, &intObj );
                if ( intObj.isInt() )
                    dashSpaces = intObj.getInt();
                intObj.free();
                annotation->style.marks = dashMarks;
                annotation->style.spaces = dashSpaces;
            }
            dashArray.free();
        }
        bsObj.free();
        Object beObj;
        annotDict->lookup( "BE", &beObj );
        if ( beObj.isDict() )
        {
            // -> style.effect
            QString effectName;
            XPDFReader::lookupName( beObj.getDict(), "S", effectName );
            if ( effectName == "C" )
                annotation->style.effect = Annotation::Cloudy;
            // -> style.effectIntensity
            int intensityInt = -1;
            XPDFReader::lookupInt( beObj.getDict(), "I", intensityInt );
            if ( intensityInt != -1 )
                annotation->style.effectIntensity = (double)intensityInt;
        }
        beObj.free();
        // -> style.color
        XPDFReader::lookupColor( annotDict, "C", annotation->style.color );

        /** 1.4. PARSE markup { common, Popup, Revision } parameters */
        if ( parseMarkup )
        {
            // -> creationDate
            XPDFReader::lookupDate( annotDict, "CreationDate", annotation->creationDate );
            // -> style.opacity
            XPDFReader::lookupNum( annotDict, "CA", annotation->style.opacity );
            // -> window.title and author
            XPDFReader::lookupString( annotDict, "T", annotation->window.title );
            annotation->author = annotation->window.title;
            // -> window.summary
            XPDFReader::lookupString( annotDict, "Subj", annotation->window.summary );
            // -> window.text
            XPDFReader::lookupString( annotDict, "RC", annotation->window.text );

            // if a popup is referenced, schedule for resolving it later
            int popupID = 0;
            XPDFReader::lookupIntRef( annotDict, "Popup", popupID );
            if ( popupID )
            {
                ResolveWindow request;
                request.popupWindowID = popupID;
                request.annotation = annotation;
                resolvePopList.append( request );
            }

            // if an older version is referenced, schedule for reparenting
            int parentID = 0;
            XPDFReader::lookupIntRef( annotDict, "IRT", parentID );
            if ( parentID )
            {
                ResolveRevision request;
                request.nextAnnotation = annotation;
                request.nextAnnotationID = annotID;
                request.prevAnnotationID = parentID;

                // -> request.nextScope
                request.nextScope = Annotation::Reply;
                Object revObj;
                annotDict->lookup( "RT", &revObj );
                if ( revObj.isName() )
                {
                    const char * name = revObj.getName();
                    if ( !strcmp( name, "R" ) )
                        request.nextScope = Annotation::Reply;
                    else if ( !strcmp( name, "Group" ) )
                        request.nextScope = Annotation::Group;
                }
                revObj.free();

                // -> revision.type (StateModel is deduced from type, not parsed)
                request.nextType = Annotation::None;
                annotDict->lookup( "State", &revObj );
                if ( revObj.isString() )
                {
                    const char * name = revObj.getString()->getCString();
                    if ( !strcmp( name, "Marked" ) )
                        request.nextType = Annotation::Marked;
                    else if ( !strcmp( name, "Unmarked" ) )
                        request.nextType = Annotation::Unmarked;
                    else if ( !strcmp( name, "Accepted" ) )
                        request.nextType = Annotation::Accepted;
                    else if ( !strcmp( name, "Rejected" ) )
                        request.nextType = Annotation::Rejected;
                    else if ( !strcmp( name, "Cancelled" ) )
                        request.nextType = Annotation::Cancelled;
                    else if ( !strcmp( name, "Completed" ) )
                        request.nextType = Annotation::Completed;
                    else if ( !strcmp( name, "None" ) )
                        request.nextType = Annotation::None;
                }
                revObj.free();

                // schedule for later reparenting
                resolveRevList.append( request );
            }
        }
        // free annot object
        annot.free();

        /** 1.5. ADD ANNOTATION to the annotationsMap  */
        if ( addToPage )
        {
            if ( annotationsMap.contains( annotID ) )
                qDebug() << "PDFGenerator: clash for annotations with ID:" << annotID << endl;
            annotationsMap[ annotID ] = annotation;
        }
    } // end Annotation/PopupWindow parsing loop

    /** 2 - RESOLVE POPUPS (popup.* -> annotation.window) */
    if ( !resolvePopList.isEmpty() && !popupsMap.isEmpty() )
    {
        QLinkedList< ResolveWindow >::iterator it = resolvePopList.begin(),
                                              end = resolvePopList.end();
        for ( ; it != end; ++it )
        {
            const ResolveWindow & request = *it;
            if ( !popupsMap.contains( request.popupWindowID ) )
                // warn aboud problems in popup resolving logic
                qDebug() << "PDFGenerator: can't resolve popup "
                          << request.popupWindowID << "." << endl;
            else
            {
                // set annotation's window properties taking ones from popup
                PopupWindow * pop = popupsMap[ request.popupWindowID ];
                Annotation * pa = pop->dummyAnnotation;
                Annotation::Window & w = request.annotation->window;

                // transfer properties to Annotation's window
                w.flags = pa->flags & (Annotation::Hidden |
                    Annotation::FixedSize | Annotation::FixedRotation);
                if ( !pop->shown )
                    w.flags |= Annotation::Hidden;
                w.topLeft.setX(pa->boundary.left());
                w.topLeft.setY(pa->boundary.top());
                w.width = (int)( pa->boundary.right() - pa->boundary.left() );
                w.height = (int)( pa->boundary.bottom() - pa->boundary.top() );
            }
        }

        // clear data
        QMap< int, PopupWindow * >::Iterator dIt = popupsMap.begin(), dEnd = popupsMap.end();
        for ( ; dIt != dEnd; ++dIt )
        {
            PopupWindow * p = dIt.value();
            delete p->dummyAnnotation;
            delete p;
        }
    }

    /** 3 - RESOLVE REVISIONS (parent.revisions.append( children )) */
    if ( !resolveRevList.isEmpty() )
    {
        // append children to parents
        int excludeIDs[ resolveRevList.count() ];   // can't even reach this size
        int excludeIndex = 0;                       // index in excludeIDs array
        QLinkedList< ResolveRevision >::iterator it = resolveRevList.begin(), end = resolveRevList.end();
        for ( ; it != end; ++it )
        {
            const ResolveRevision & request = *it;
            int parentID = request.prevAnnotationID;
            if ( !annotationsMap.contains( parentID ) )
                // warn about problems in reparenting logic
                qDebug() << "PDFGenerator: can't reparent annotation to "
                          << parentID << "." << endl;
            else
            {
                // compile and add a Revision structure to the parent annotation
                Annotation::Revision childRevision;
                childRevision.annotation = request.nextAnnotation;
                childRevision.scope = request.nextScope;
                childRevision.type = request.nextType;
                annotationsMap[ parentID ]->revisions.append( childRevision );
                // exclude child annotation from being rooted in page
                excludeIDs[ excludeIndex++ ] = request.nextAnnotationID;
            }
        }

        // prevent children from being attached to page as roots
        for ( int i = 0; i < excludeIndex; i++ )
            annotationsMap.remove( excludeIDs[ i ] );
    }

    /** 4 - POSTPROCESS TextAnnotations (when window geom is embedded) */
    if ( !ppTextList.isEmpty() )
    {
        QLinkedList< PostProcessText >::const_iterator it = ppTextList.begin(), end = ppTextList.end();
        for ( ; it != end; ++it )
        {
            const PostProcessText & request = *it;
            Annotation::Window & window = request.textAnnotation->window;
            // if not present, 'create' the window in-place over the annotation
            if ( window.flags == -1 )
            {
                window.flags = 0;
                QRectF & geom = request.textAnnotation->boundary;
                // initialize window geometry to annotation's one
                window.width = (int)( geom.right() - geom.left() );
                window.height = (int)( geom.bottom() - geom.top() );
                window.topLeft.setX( geom.left() > 0.0 ? geom.left() : 0.0 );
                window.topLeft.setY( geom.top() > 0.0 ? geom.top() : 0.0 );
            }
            // (pdf) if text is not 'opened', force window hiding. if the window
            // was parsed from popup, the flag should already be set
            if ( !request.opened && window.flags != -1 )
                window.flags |= Annotation::Hidden;
        }
    }

    /** 5 - finally RETURN ANNOTATIONS */
    return annotationsMap.values();
}


}
