/* poppler-page.cc: qt interface to poppler
 * Copyright (C) 2005, Net Integration Technologies, Inc.
 * Copyright (C) 2005, Tobias Koening
 *
 * 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.
 */

#include <poppler-qt.h>
#include <qfile.h>
#include <qimage.h>
#include <GlobalParams.h>
#include <PDFDoc.h>
#include <Catalog.h>
#include <ErrorCodes.h>
#include <SplashOutputDev.h>
#include <TextOutputDev.h>
#include <splash/SplashBitmap.h>
#include "poppler-private.h"
#include "poppler-page-transition-private.h"

namespace Poppler {

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

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

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

void Page::renderToPixmap(QPixmap **q, int x, int y, int w, int h, bool doLinks) const
{
  renderToPixmap(q, x, y, w, h, 72.0, 72.0, doLinks);
}

void Page::renderToPixmap(QPixmap **q, int x, int y, int w, int h, double xres, double yres, bool doLinks) const
{
  QImage img = renderToImage(xres, yres, doLinks);
  *q = new QPixmap( img );
}

QImage Page::renderToImage(double xres, double yres, bool doLinks) const
{
  SplashOutputDev *output_dev;
  SplashBitmap *bitmap;
  SplashColorPtr color_ptr;
  output_dev = data->doc->data->getOutputDev();

  data->doc->data->doc.displayPageSlice(output_dev, data->index + 1, xres, yres,
      0, false, false, doLinks, -1, -1, -1, -1);
  bitmap = output_dev->getBitmap ();
  color_ptr = bitmap->getDataPtr ();
  int bw = output_dev->getBitmap()->getWidth();
  int bh = output_dev->getBitmap()->getHeight();
  SplashColorPtr dataPtr = output_dev->getBitmap()->getDataPtr();
  
  if (QImage::BigEndian == QImage::systemByteOrder())
  {
    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, 32, 0, 0, QImage::IgnoreEndian );
  img = img.copy();
  // unload underlying xpdf bitmap
  output_dev->startPage( 0, NULL );

  return img;
}

QString Page::getText(const Rectangle &r) const
{
  TextOutputDev *output_dev;
  GooString *s;
  PDFRectangle *rect;
  QString result;
  ::Page *p;
  
  output_dev = new TextOutputDev(0, gFalse, gFalse, gFalse);
  data->doc->data->doc.displayPageSlice(output_dev, data->index + 1, 72, 72,
      0, false, false, false, -1, -1, -1, -1);
  p = data->doc->data->doc.getCatalog()->getPage(data->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.m_y2;
    y2 = height - r.m_y1;
    s = output_dev->getText(r.m_x1, y1, r.m_x2, y2);
  }

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

  delete output_dev;
  delete s;
  return result;
}

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

  data->doc->data->doc.displayPageSlice(output_dev, data->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;
  }
  
  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, Rectangle(xMin, yMin, xMax, yMax));
    
    output_list.append(text_box);
  }
  
  delete word_list;
  delete output_dev;
  
  return output_list;
}

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

QSize Page::pageSize() const
{
  ::Page *p;

  p = data->doc->data->doc.getCatalog()->getPage(data->index + 1);
  if ( ( Page::Landscape == orientation() ) || (Page::Seascape == orientation() ) ) {
    return QSize( (int)p->getCropHeight(), (int)p->getCropWidth() );
  } else {
    return QSize( (int)p->getCropWidth(), (int)p->getCropHeight() );
  }
}

Page::Orientation Page::orientation() const
{
  ::Page *p = data->doc->data->doc.getCatalog()->getPage(data->index + 1);

  int rotation = p->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;
  }
}

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

  Links *xpdfLinks = data->doc->data->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 );
    QRect linkArea;
    
    data->doc->data->m_outputDev->cvtUserToDev( left, top, &leftAux, &topAux );
    data->doc->data->m_outputDev->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(), data->doc->data ) ) );
        }
        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(), data->doc->data ) ) );
        }
        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;
}

}
