//========================================================================
//
// HtmlOutputDev.h
//
// Copyright 1997 Derek B. Noonburg
//
// Changed 1999 by G.Ovtcharov
//========================================================================

//========================================================================
//
// Modified under the Poppler project - http://poppler.freedesktop.org
//
// All changes made under the Poppler project to this file are licensed
// under GPL version 2 or later
//
// Copyright (C) 2006, 2007, 2009, 2012, 2018, 2019 Albert Astals Cid <aacid@kde.org>
// Copyright (C) 2008, 2009 Warren Toomey <wkt@tuhs.org>
// Copyright (C) 2009, 2011 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2009 Kovid Goyal <kovid@kovidgoyal.net>
// Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
// Copyright (C) 2011 Joshua Richardson <jric@chegg.com>
// Copyright (C) 2011 Stephen Reichling <sreichling@chegg.com>
// Copyright (C) 2012 Igor Slepchin <igor.redhat@gmail.com>
// Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
// 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
// Copyright (C) 2019 Oliver Sander <oliver.sander@tu-dresden.de>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
//
//========================================================================

#ifndef HTMLOUTPUTDEV_H
#define HTMLOUTPUTDEV_H

#include <stdio.h>
#include "goo/gbasename.h"
#include "GfxFont.h"
#include "OutputDev.h"
#include "HtmlLinks.h"
#include "HtmlFonts.h"
#include "Link.h"
#include "Catalog.h"
#include "UnicodeMap.h"

#define xoutRound(x) ((int)(x + 0.5))

#define DOCTYPE "<!DOCTYPE html>"

class GfxState;
class GooString;
class HtmlImage;
class PDFDoc;
class OutlineItem;
//------------------------------------------------------------------------
// HtmlString
//------------------------------------------------------------------------

enum UnicodeTextDirection {
  textDirUnknown,
  textDirLeftRight,
  textDirRightLeft,
  textDirTopBottom
};

class HtmlString {
public:

  // Constructor.
  HtmlString(GfxState *state, double fontSize, HtmlFontAccu* fonts);

  // Destructor.
  ~HtmlString();

  HtmlString(const HtmlString &) = delete;
  HtmlString& operator=(const HtmlString &) = delete;

  // Add a character to the string.
  void addChar(GfxState *state, double x, double y,
	       double dx, double dy,
	       Unicode u); 
  HtmlLink* getLink() { return link; }
  const HtmlFont &getFont() const { return *fonts->Get(fontpos); }
  void endString(); // postprocessing

private:
// aender die text variable
  HtmlLink *link;
  double xMin, xMax;		// bounding box x coordinates
  double yMin, yMax;		// bounding box y coordinates
  int col;			// starting column
  Unicode *text;		// the text
  double *xRight;		// right-hand x coord of each char
  HtmlString *yxNext;		// next string in y-major order
  HtmlString *xyNext;		// next string in x-major order
  int fontpos;
  GooString* htext;
  int len;			// length of text and xRight
  int size;			// size of text and xRight arrays
  UnicodeTextDirection dir;	// direction (left to right/right to left)
  HtmlFontAccu *fonts;
  
  friend class HtmlPage;

};


//------------------------------------------------------------------------
// HtmlPage
//------------------------------------------------------------------------



class HtmlPage {
public:

  // Constructor.
  HtmlPage(bool rawOrder);

  // Destructor.
  ~HtmlPage();

  HtmlPage(const HtmlPage &) = delete;
  HtmlPage& operator=(const HtmlPage &) = delete;

  // Begin a new string.
  void beginString(GfxState *state, const GooString *s);

  // Add a character to the current string.
  void addChar(GfxState *state, double x, double y,
	       double dx, double dy, 
		double ox, double oy, 
		Unicode *u, int uLen); //unsigned char c);

  void updateFont(GfxState *state);

  // End the current string, sorting it into the list of strings.
  void endString();

  // Coalesce strings that look like parts of the same line.
  void coalesce();

  // Find a string.  If <top> is true, starts looking at top of page;
  // otherwise starts looking at <xMin>,<yMin>.  If <bottom> is true,
  // stops looking at bottom of page; otherwise stops looking at
  // <xMax>,<yMax>.  If found, sets the text bounding rectangle and
  // returns true; otherwise returns false.
  

  // new functions
  void AddLink(const HtmlLink& x){
    links->AddLink(x);
  }

  // add an image to the current page
  void addImage(GooString *fname, GfxState *state);

  // number of images on the current page
  int  getNumImages() { return imgList->size(); }

  void dump(FILE *f, int pageNum, const std::vector<std::string>& backgroundImages);

  // Clear the page.
  void clear();
  
  void conv();
private:
  HtmlFont* getFont(HtmlString *hStr) { return fonts->Get(hStr->fontpos); }

  double fontSize;		// current font size
  bool rawOrder;		// keep strings in content stream order

  HtmlString *curStr;		// currently active string

  HtmlString *yxStrings;	// strings in y-major order
  HtmlString *xyStrings;	// strings in x-major order
  HtmlString *yxCur1, *yxCur2;	// cursors for yxStrings list
  
  void setDocName(const char* fname);
  void dumpAsXML(FILE* f,int page);
  void dumpComplex(FILE* f, int page, const std::vector<std::string>& backgroundImages);
  int dumpComplexHeaders(FILE * const file, FILE *& pageFile, int page);

  // marks the position of the fonts that belong to current page (for noframes)
  int fontsPageMarker; 
  HtmlFontAccu *fonts;
  HtmlLinks *links; 
  std::vector<HtmlImage*> *imgList;
  
  GooString *DocName;
  int pageWidth;
  int pageHeight;
  int firstPage;                // used to begin the numeration of pages

  friend class HtmlOutputDev;
};

//------------------------------------------------------------------------
// HtmlMetaVar
//------------------------------------------------------------------------
class HtmlMetaVar {
public:
    HtmlMetaVar(const char *_name, const char *_content);
    ~HtmlMetaVar();    
    
    HtmlMetaVar(const HtmlMetaVar &) = delete;
    HtmlMetaVar& operator=(const HtmlMetaVar &) = delete;

    GooString* toString();

private:

    GooString *name;
    GooString *content;
};

//------------------------------------------------------------------------
// HtmlOutputDev
//------------------------------------------------------------------------

class HtmlOutputDev: public OutputDev {
public:

  // Open a text output file.  If <fileName> is nullptr, no file is written
  // (this is useful, e.g., for searching text).  If <useASCII7> is true,
  // text is converted to 7-bit ASCII; otherwise, text is converted to
  // 8-bit ISO Latin-1.  <useASCII7> should also be set for Japanese
  // (EUC-JP) text.  If <rawOrder> is true, the text is kept in content
  // stream order.
  HtmlOutputDev(Catalog *catalogA, const char *fileName, const char *title,
	  const char *author,
	  const char *keywords,
	  const char *subject,
	  const char *date,
	  bool rawOrder,
	  int firstPage = 1,
	  bool outline = 0);

  // Destructor.
  virtual ~HtmlOutputDev();

  // Check if file was successfully created.
  virtual bool isOk() { return ok; }

  //---- get info about output device

  // Does this device use upside-down coordinates?
  // (Upside-down means (0,0) is the top left corner of the page.)
  bool upsideDown() override { return true; }

  // Does this device use drawChar() or drawString()?
  bool useDrawChar() override { return true; }

  // Does this device use beginType3Char/endType3Char?  Otherwise,
  // text in Type 3 fonts will be drawn with drawChar/drawString.
  bool interpretType3Chars() override { return false; }

  // Does this device need non-text content?
  bool needNonText() override { return true; }

  //----- initialization and control

  bool checkPageSlice(Page *p, double hDPI, double vDPI,
                       int rotate, bool useMediaBox, bool crop,
                       int sliceX, int sliceY, int sliceW, int sliceH,
                       bool printing,
                       bool (* abortCheckCbk)(void *data) = nullptr,
                       void * abortCheckCbkData = nullptr,
                       bool (*annotDisplayDecideCbk)(Annot *annot, void *user_data) = nullptr,
                       void *annotDisplayDecideCbkData = nullptr) override
  {
   docPage = p;
   return true;
  }


  // Start a page.
  void startPage(int pageNum, GfxState *state, XRef *xref) override;

  // End a page.
  void endPage() override;

  // add a background image to the list of background images,
  // as this seems to be done outside other processing. takes ownership of img.
  void addBackgroundImage(const std::string& img);

  //----- update text state
  void updateFont(GfxState *state) override;

  //----- text drawing
  void beginString(GfxState *state, const GooString *s) override;
  void endString(GfxState *state) override;
  void drawChar(GfxState *state, double x, double y,
		double dx, double dy,
		double originX, double originY,
		CharCode code, int nBytes, Unicode *u, int uLen) override;
  
  void drawImageMask(GfxState *state, Object *ref,
		     Stream *str,
		     int width, int height, bool invert,
		     bool interpolate, bool inlineImg) override;
  void drawImage(GfxState *state, Object *ref, Stream *str,
		 int width, int height, GfxImageColorMap *colorMap,
		 bool interpolate, int *maskColors, bool inlineImg) override;

  //new feature    
  virtual int DevType() {return 1234;}

  int getPageWidth() { return maxPageWidth; }
  int getPageHeight() { return maxPageHeight; }

  bool dumpDocOutline(PDFDoc* doc);

private:
  // convert encoding into a HTML standard, or encoding->c_str if not
  // recognized. Will delete encoding for you and return a new one
  // that you have to delete
  static GooString* mapEncodingToHtml(GooString* encoding);
  void doProcessLink(AnnotLink *link);
  GooString* getLinkDest(AnnotLink *link);
  void dumpMetaVars(FILE *);
  void doFrame(int firstPage);
  bool newHtmlOutlineLevel(FILE *output, const std::vector<OutlineItem*> *outlines, int level = 1);
  void newXmlOutlineLevel(FILE *output, const std::vector<OutlineItem*> *outlines);
  int getOutlinePageNum(OutlineItem *item);
  void drawJpegImage(GfxState *state, Stream *str);
  void drawPngImage(GfxState *state, Stream *str, int width, int height,
                    GfxImageColorMap *colorMap, bool isMask = false);
  GooString *createImageFileName(const char *ext);

  FILE *fContentsFrame;
  FILE *page;                   // html file
  //FILE *tin;                    // image log file
  //bool write;
  bool needClose;		// need to close the file?
  HtmlPage *pages;		// text for the current page
  bool rawOrder;		// keep text in content stream order
  bool doOutline;		// output document outline
  bool ok;			// set up ok?
  bool dumpJPEG;
  int pageNum;
  int maxPageWidth;
  int maxPageHeight;
  GooString *Docname;
  GooString *docTitle;
  std::vector<HtmlMetaVar*> *glMetaVars;
  Catalog *catalog;
  Page *docPage;
  std::vector<std::string> backgroundImages;
  friend class HtmlPage;
};

#endif
