//========================================================================
//
// MarkedContentOutputDev.cc
//
// This file is licensed under the GPLv2 or later
//
// Copyright 2013 Igalia S.L.
// Copyright 2018, 2019 Albert Astals Cid <aacid@kde.org>
//
//========================================================================

#include "MarkedContentOutputDev.h"
#include "GlobalParams.h"
#include "UnicodeMap.h"
#include "GfxState.h"
#include "GfxFont.h"
#include "Annot.h"
#include <vector>


MarkedContentOutputDev::MarkedContentOutputDev(int mcidA):
  currentFont(nullptr),
  currentText(nullptr),
  mcid(mcidA),
  pageWidth(0.0),
  pageHeight(0.0),
  unicodeMap(nullptr)
{
  currentColor.r = currentColor.g = currentColor.b = 0;
}


MarkedContentOutputDev::~MarkedContentOutputDev()
{
  if (unicodeMap)
    unicodeMap->decRefCnt();
  if (currentFont)
    currentFont->decRefCnt();
  delete currentText;
}


void MarkedContentOutputDev::endSpan()
{
  if (currentText && currentText->getLength()) {
    // The TextSpan takes ownership of currentText and
    // increases the reference count for currentFont.
    textSpans.push_back(TextSpan(currentText,
                                 currentFont,
                                 currentColor));
  }
  currentText = nullptr;
}


void MarkedContentOutputDev::startPage(int pageNum, GfxState *state, XRef *xref)
{
  if (state) {
    pageWidth  = state->getPageWidth();
    pageHeight = state->getPageHeight();
  } else {
    pageWidth = pageHeight = 0.0;
  }
}


void MarkedContentOutputDev::endPage()
{
  pageWidth = pageHeight = 0.0;
}


void MarkedContentOutputDev::beginMarkedContent(const char *name, Dict *properties)
{
  int id = -1;
  if (properties)
    properties->lookupInt("MCID", nullptr, &id);

  if (id == -1)
    return;

  // The stack keep track of MCIDs of nested marked content.
  if (inMarkedContent() || id == mcid)
    mcidStack.push_back(id);
}


void MarkedContentOutputDev::endMarkedContent(GfxState *state)
{
  if (inMarkedContent()) {
      mcidStack.pop_back();
      // The outer marked content sequence MCID was popped, ensure
      // that the last piece of text collected ends up in a TextSpan.
      if (!inMarkedContent())
        endSpan();
  }
}


bool MarkedContentOutputDev::needFontChange(const GfxFont* font) const
{
  if (currentFont == font)
    return false;

  if (!currentFont)
    return font != nullptr && font->isOk();

  if (font == nullptr)
    return true;

  // Two non-null valid fonts are the same if they point to the same Ref
  if (*currentFont->getID() == *font->getID())
    return false;

  return true;
}


void MarkedContentOutputDev::drawChar(GfxState *state,
                                      double xx, double yy,
                                      double dx, double dy,
                                      double ox, double oy,
                                      CharCode c, int nBytes,
                                      Unicode *u, int uLen)
{
  if (!inMarkedContent() || !uLen)
    return;


  // Color changes are tracked here so the color can be chosen depending on
  // the render mode (for mode 1 stroke color is used), so there is no need
  // to implement both updateFillColor() and updateStrokeColor().
  bool colorChange = false;
  GfxRGB color;
  if ((state->getRender() & 3) == 1)
    state->getStrokeRGB(&color);
  else
    state->getFillRGB(&color);

  colorChange = (color.r != currentColor.r ||
                 color.g != currentColor.g ||
                 color.b != currentColor.b);

  // Check also for font changes.
  bool fontChange = needFontChange(state->getFont());

  // Save a span with the current changes.
  if (colorChange || fontChange) {
    endSpan();
  }

  // Perform the color/font changes.
  if (colorChange)
    currentColor = color;

  if (fontChange) {
    if (currentFont != nullptr) {
      currentFont->decRefCnt();
      currentFont = nullptr;
    }
    if (state->getFont() != nullptr) {
      currentFont = state->getFont();
      currentFont->incRefCnt();
    }
  }


  double sp, dx2, dy2, w1, h1, x1, y1;

  // Subtract char and word spacing from the (dx,dy) values
  sp = state->getCharSpace();
  if (c == (CharCode) 0x20)
    sp += state->getWordSpace();
  state->textTransformDelta(sp * state->getHorizScaling(), 0, &dx2, &dy2);
  dx -= dx2;
  dy -= dy2;
  state->transformDelta(dx, dy, &w1, &h1);
  state->transform(xx, yy, &x1, &y1);

  // Throw away characters that are not inside the page boundaries.
  if (x1 + w1 < 0 || x1 > pageWidth || y1 + h1 < 0 || y1 > pageHeight)
    return;

  // Make a sanity check on character size. Note: (x != x) <-> isnan(x)
  if (x1 != x1 || y1 != y1 || w1 != w1 || h1 != h1)
    return;

  for (int i = 0; i < uLen; i++) {
    // Soft hyphen markers are skipped, as they are invisible unless
    // rendering is done to an actual device and the hyphenation hint
    // used. MarkedContentOutputDev extracts the *visible* text content.
    if (u[i] != 0x00AD) {
      // Add the UTF-8 sequence to the current text span.
      if (!unicodeMap)
        unicodeMap = globalParams->getTextEncoding();

      char buf[8];
      int n = unicodeMap->mapUnicode(u[i], buf, sizeof(buf));
      if (n > 0) {
        if (currentText == nullptr)
          currentText = new GooString();
        currentText->append(buf, n);
      }
    }
  }
}


const TextSpanArray& MarkedContentOutputDev::getTextSpans() const
{
  return textSpans;
}
