// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "xfa/fde/cfde_txtedtpage.h"

#include <algorithm>

#include "core/fxcrt/cfx_wordbreak.h"
#include "third_party/base/ptr_util.h"
#include "third_party/base/stl_util.h"
#include "xfa/fde/cfde_txtedtbuf.h"
#include "xfa/fde/cfde_txtedtengine.h"
#include "xfa/fde/cfde_txtedtparag.h"
#include "xfa/fde/cfde_txtedttextset.h"
#include "xfa/fgas/layout/cfx_txtbreak.h"

namespace {

const double kTolerance = 0.1f;

}  // namespace

CFDE_TxtEdtPage::CFDE_TxtEdtPage(CFDE_TxtEdtEngine* pEngine, int32_t nPageIndex)
    : m_pEditEngine(pEngine),
      m_pBgnParag(nullptr),
      m_pEndParag(nullptr),
      m_nRefCount(0),
      m_nPageStart(-1),
      m_nCharCount(0),
      m_nPageIndex(nPageIndex),
      m_bLoaded(false) {
}

CFDE_TxtEdtPage::~CFDE_TxtEdtPage() {}

int32_t CFDE_TxtEdtPage::GetCharRect(int32_t nIndex,
                                     CFX_RectF& rect,
                                     bool bBBox) const {
  ASSERT(m_nRefCount > 0);
  ASSERT(nIndex >= 0 && nIndex < m_nCharCount);
  if (m_nRefCount < 1)
    return 0;

  for (const auto& piece : m_Pieces) {
    if (nIndex >= piece.nStart && nIndex < piece.nStart + piece.nCount) {
      std::vector<CFX_RectF> rectArr = m_pTextSet->GetCharRects(&piece, bBBox);
      rect = rectArr[nIndex - piece.nStart];
      return piece.nBidiLevel;
    }
  }
  ASSERT(0);
  return 0;
}

int32_t CFDE_TxtEdtPage::GetCharIndex(const CFX_PointF& fPoint, bool& bBefore) {
  CFX_PointF ptF = fPoint;
  NormalizePt2Rect(ptF, m_rtPageContents, kTolerance);
  int32_t nCount = pdfium::CollectionSize<int32_t>(m_Pieces);
  CFX_RectF rtLine;
  int32_t nBgn = 0;
  int32_t nEnd = 0;
  bool bInLine = false;
  int32_t i = 0;
  for (i = 0; i < nCount; i++) {
    const FDE_TEXTEDITPIECE* pPiece = &m_Pieces[i];
    if (!bInLine &&
        (pPiece->rtPiece.top <= ptF.y && pPiece->rtPiece.bottom() > ptF.y)) {
      nBgn = nEnd = i;
      rtLine = pPiece->rtPiece;
      bInLine = true;
    } else if (bInLine) {
      if (pPiece->rtPiece.bottom() <= ptF.y || pPiece->rtPiece.top > ptF.y) {
        nEnd = i - 1;
        break;
      } else {
        rtLine.Union(pPiece->rtPiece);
      }
    }
  }
  NormalizePt2Rect(ptF, rtLine, kTolerance);
  int32_t nCaret = 0;
  FDE_TEXTEDITPIECE* pPiece = nullptr;
  for (i = nBgn; i <= nEnd; i++) {
    pPiece = &m_Pieces[i];
    nCaret = m_nPageStart + pPiece->nStart;
    if (pPiece->rtPiece.Contains(ptF)) {
      std::vector<CFX_RectF> rectArr = m_pTextSet->GetCharRects(pPiece, false);
      int32_t nRtCount = pdfium::CollectionSize<int32_t>(rectArr);
      for (int32_t j = 0; j < nRtCount; j++) {
        if (rectArr[j].Contains(ptF)) {
          nCaret = m_nPageStart + pPiece->nStart + j;
          if (nCaret >= m_pEditEngine->GetTextLength()) {
            bBefore = true;
            return m_pEditEngine->GetTextLength();
          }
          wchar_t wChar = m_pEditEngine->GetTextBuf()->GetCharByIndex(nCaret);
          if (wChar == L'\n' || wChar == L'\r') {
            if (wChar == L'\n') {
              if (m_pEditEngine->GetTextBuf()->GetCharByIndex(nCaret - 1) ==
                  L'\r') {
                nCaret--;
              }
            }
            bBefore = true;
            return nCaret;
          }
          if (ptF.x > ((rectArr[j].left + rectArr[j].right()) / 2)) {
            bBefore = FX_IsOdd(pPiece->nBidiLevel);
          } else {
            bBefore = !FX_IsOdd(pPiece->nBidiLevel);
          }
          return nCaret;
        }
      }
    }
  }
  bBefore = true;
  return nCaret;
}

void CFDE_TxtEdtPage::CalcRangeRectArray(
    int32_t nStart,
    int32_t nCount,
    std::vector<CFX_RectF>* pRectFArr) const {
  int32_t nEnd = nStart + nCount - 1;
  bool bInRange = false;
  for (const auto& piece : m_Pieces) {
    if (!bInRange) {
      if (nStart >= piece.nStart && nStart < piece.nStart + piece.nCount) {
        int32_t nRangeEnd = piece.nCount - 1;
        bool bEnd = false;
        if (nEnd >= piece.nStart && nEnd < piece.nStart + piece.nCount) {
          nRangeEnd = nEnd - piece.nStart;
          bEnd = true;
        }
        std::vector<CFX_RectF> rcArr = m_pTextSet->GetCharRects(&piece, false);
        CFX_RectF rectPiece = rcArr[nStart - piece.nStart];
        rectPiece.Union(rcArr[nRangeEnd]);
        pRectFArr->push_back(rectPiece);
        if (bEnd)
          return;

        bInRange = true;
      }
    } else {
      if (nEnd >= piece.nStart && nEnd < piece.nStart + piece.nCount) {
        std::vector<CFX_RectF> rcArr = m_pTextSet->GetCharRects(&piece, false);
        CFX_RectF rectPiece = rcArr[0];
        rectPiece.Union(rcArr[nEnd - piece.nStart]);
        pRectFArr->push_back(rectPiece);
        return;
      }
      pRectFArr->push_back(piece.rtPiece);
    }
  }
}

int32_t CFDE_TxtEdtPage::SelectWord(const CFX_PointF& fPoint, int32_t& nCount) {
  if (m_nRefCount < 0) {
    return -1;
  }
  CFDE_TxtEdtBuf* pBuf = m_pEditEngine->GetTextBuf();
  bool bBefore;
  int32_t nIndex = GetCharIndex(fPoint, bBefore);
  if (nIndex == m_pEditEngine->GetTextLength()) {
    nIndex = m_pEditEngine->GetTextLength() - 1;
  }
  if (nIndex < 0) {
    return -1;
  }
  auto pIter = pdfium::MakeUnique<CFX_WordBreak>();
  pIter->Attach(new CFDE_TxtEdtBuf::Iterator(pBuf, 0));
  pIter->SetAt(nIndex);
  nCount = pIter->GetWordLength();
  return pIter->GetWordPos();
}

int32_t CFDE_TxtEdtPage::LoadPage() {
  if (m_nRefCount > 0) {
    m_nRefCount++;
    return m_nRefCount;
  }

  CFDE_TxtEdtBuf* pBuf = m_pEditEngine->GetTextBuf();
  const FDE_TXTEDTPARAMS* pParams = m_pEditEngine->GetEditParams();
  wchar_t wcAlias = 0;
  if (pParams->dwMode & FDE_TEXTEDITMODE_Password)
    wcAlias = m_pEditEngine->GetAliasChar();

  m_pIter = pdfium::MakeUnique<CFDE_TxtEdtBuf::Iterator>(
      static_cast<CFDE_TxtEdtBuf*>(pBuf), wcAlias);
  CFX_TxtBreak* pBreak = m_pEditEngine->GetTextBreak();
  pBreak->EndBreak(CFX_BreakType::Paragraph);
  pBreak->ClearBreakPieces();
  int32_t nPageLineCount = m_pEditEngine->GetPageLineCount();
  int32_t nStartLine = nPageLineCount * m_nPageIndex;
  int32_t nEndLine = std::min((nStartLine + nPageLineCount - 1),
                              (m_pEditEngine->GetLineCount() - 1));
  int32_t nPageStart, nPageEnd, nTemp, nBgnParag, nStartLineInParag, nEndParag,
      nEndLineInParag;
  nBgnParag = m_pEditEngine->Line2Parag(0, 0, nStartLine, nStartLineInParag);
  m_pBgnParag =
      static_cast<CFDE_TxtEdtParag*>(m_pEditEngine->GetParag(nBgnParag));
  m_pBgnParag->LoadParag();
  m_pBgnParag->GetLineRange(nStartLine - nStartLineInParag, nPageStart, nTemp);
  nEndParag = m_pEditEngine->Line2Parag(nBgnParag, nStartLineInParag, nEndLine,
                                        nEndLineInParag);
  m_pEndParag =
      static_cast<CFDE_TxtEdtParag*>(m_pEditEngine->GetParag(nEndParag));
  m_pEndParag->LoadParag();
  m_pEndParag->GetLineRange(nEndLine - nEndLineInParag, nPageEnd, nTemp);
  nPageEnd += (nTemp - 1);

  float fLineStart = 0.0f;
  float fLineStep = pParams->fLineSpace;
  float fLinePos = fLineStart;
  if (!m_pTextSet)
    m_pTextSet = pdfium::MakeUnique<CFDE_TxtEdtTextSet>(this);

  m_Pieces.clear();
  CFX_BreakType dwBreakStatus = CFX_BreakType::None;
  int32_t nPieceStart = 0;

  m_CharWidths.resize(nPageEnd - nPageStart + 1, 0);
  pBreak->EndBreak(CFX_BreakType::Paragraph);
  pBreak->ClearBreakPieces();
  m_nPageStart = nPageStart;
  m_nCharCount = nPageEnd - nPageStart + 1;
  bool bReload = false;
  float fDefCharWidth = 0;
  std::unique_ptr<IFX_CharIter> pIter = m_pIter->Clone();
  pIter->SetAt(nPageStart);
  m_pIter->SetAt(nPageStart);
  bool bFirstPiece = true;
  do {
    if (bReload) {
      dwBreakStatus = pBreak->EndBreak(CFX_BreakType::Paragraph);
    } else {
      wchar_t wAppend = pIter->GetChar();
      dwBreakStatus = pBreak->AppendChar(wAppend);
    }
    if (pIter->GetAt() == nPageEnd && CFX_BreakTypeNoneOrPiece(dwBreakStatus))
      dwBreakStatus = pBreak->EndBreak(CFX_BreakType::Paragraph);

    if (!CFX_BreakTypeNoneOrPiece(dwBreakStatus)) {
      int32_t nPieceCount = pBreak->CountBreakPieces();
      for (int32_t j = 0; j < nPieceCount; j++) {
        const CFX_BreakPiece* pPiece = pBreak->GetBreakPieceUnstable(j);
        FDE_TEXTEDITPIECE TxtEdtPiece;
        memset(&TxtEdtPiece, 0, sizeof(FDE_TEXTEDITPIECE));
        TxtEdtPiece.nBidiLevel = pPiece->m_iBidiLevel;
        TxtEdtPiece.nCount = pPiece->GetLength();
        TxtEdtPiece.nStart = nPieceStart;
        TxtEdtPiece.dwCharStyles = pPiece->m_dwCharStyles;
        if (FX_IsOdd(pPiece->m_iBidiLevel))
          TxtEdtPiece.dwCharStyles |= FX_TXTCHARSTYLE_OddBidiLevel;

        float fParaBreakWidth = 0.0f;
        if (!CFX_BreakTypeNoneOrPiece(pPiece->m_dwStatus)) {
          if (TxtEdtPiece.nCount >= 2) {
            wchar_t wChar = pBuf->GetCharByIndex(
                m_nPageStart + TxtEdtPiece.nStart + TxtEdtPiece.nCount - 1);
            wchar_t wCharPre = pBuf->GetCharByIndex(
                m_nPageStart + TxtEdtPiece.nStart + TxtEdtPiece.nCount - 2);
            if (wChar == L'\n') {
              fParaBreakWidth += fDefCharWidth;
            }
            if (wCharPre == L'\n') {
              fParaBreakWidth += fDefCharWidth;
            }
          } else if (TxtEdtPiece.nCount >= 1) {
            wchar_t wChar = pBuf->GetCharByIndex(
                m_nPageStart + TxtEdtPiece.nStart + TxtEdtPiece.nCount - 1);
            if (wChar == L'\n') {
              fParaBreakWidth += fDefCharWidth;
            }
          }
        }

        TxtEdtPiece.rtPiece.left = (float)pPiece->m_iStartPos / 20000.0f;
        TxtEdtPiece.rtPiece.top = fLinePos;
        TxtEdtPiece.rtPiece.width =
            (float)pPiece->m_iWidth / 20000.0f + fParaBreakWidth;
        TxtEdtPiece.rtPiece.height = pParams->fLineSpace;

        if (bFirstPiece) {
          m_rtPageContents = TxtEdtPiece.rtPiece;
          bFirstPiece = false;
        } else {
          m_rtPageContents.Union(TxtEdtPiece.rtPiece);
        }
        nPieceStart += TxtEdtPiece.nCount;
        m_Pieces.push_back(TxtEdtPiece);
        for (int32_t k = 0; k < TxtEdtPiece.nCount; k++) {
          m_CharWidths[TxtEdtPiece.nStart + k] =
              pPiece->GetChar(k)->m_iCharWidth;
        }
      }
      fLinePos += fLineStep;
      pBreak->ClearBreakPieces();
    }
    if (pIter->GetAt() == nPageEnd && dwBreakStatus == CFX_BreakType::Line) {
      bReload = true;
      pIter->Next(true);
    }
  } while (pIter->Next(false) && (pIter->GetAt() <= nPageEnd));
  if (m_rtPageContents.left != 0) {
    float fDelta = 0.0f;
    if (m_rtPageContents.width < pParams->fPlateWidth) {
      if (pParams->dwAlignment & FDE_TEXTEDITALIGN_Right) {
        fDelta = pParams->fPlateWidth - m_rtPageContents.width;
      } else if (pParams->dwAlignment & FDE_TEXTEDITALIGN_Center) {
        if ((pParams->dwLayoutStyles & FDE_TEXTEDITLAYOUT_CombText) &&
            m_nCharCount > 1) {
          int32_t nCount = m_nCharCount - 1;
          int32_t n = (m_pEditEngine->GetLimit() - nCount) / 2;
          fDelta = (m_rtPageContents.width / nCount) * n;
        } else {
          fDelta = (pParams->fPlateWidth - m_rtPageContents.width) / 2;
        }
      }
    }
    float fOffset = m_rtPageContents.left - fDelta;
    for (auto& piece : m_Pieces)
      piece.rtPiece.Offset(-fOffset, 0.0f);

    m_rtPageContents.Offset(-fOffset, 0.0f);
  }
  if (m_pEditEngine->GetEditParams()->dwLayoutStyles &
      FDE_TEXTEDITLAYOUT_LastLineHeight) {
    m_rtPageContents.height -= pParams->fLineSpace - pParams->fFontSize;
    m_Pieces.back().rtPiece.height = pParams->fFontSize;
  }
  m_nRefCount = 1;
  m_bLoaded = true;
  return 0;
}

void CFDE_TxtEdtPage::UnloadPage() {
  ASSERT(m_nRefCount > 0);
  m_nRefCount--;
  if (m_nRefCount != 0)
    return;

  m_Pieces.clear();
  m_pTextSet.reset();
  m_CharWidths.clear();
  if (m_pBgnParag) {
    m_pBgnParag->UnloadParag();
    m_pBgnParag = nullptr;
  }
  if (m_pEndParag) {
    m_pEndParag->UnloadParag();
    m_pEndParag = nullptr;
  }
  m_pIter.reset();
}

const FDE_TEXTEDITPIECE& CFDE_TxtEdtPage::GetTextPiece(size_t pos) const {
  ASSERT(pos < m_Pieces.size());
  return m_Pieces[pos];
}

wchar_t CFDE_TxtEdtPage::GetChar(const FDE_TEXTEDITPIECE* pIdentity,
                                 int32_t index) const {
  int32_t nIndex = m_nPageStart + pIdentity->nStart + index;
  if (nIndex != m_pIter->GetAt())
    m_pIter->SetAt(nIndex);

  wchar_t wChar = m_pIter->GetChar();
  m_pIter->Next();
  return wChar;
}

int32_t CFDE_TxtEdtPage::GetWidth(const FDE_TEXTEDITPIECE* pIdentity,
                                  int32_t index) const {
  int32_t nWidth = m_CharWidths[pIdentity->nStart + index];
  return nWidth;
}

void CFDE_TxtEdtPage::NormalizePt2Rect(CFX_PointF& ptF,
                                       const CFX_RectF& rtF,
                                       float fTolerance) const {
  if (rtF.Contains(ptF))
    return;
  if (ptF.x < rtF.left)
    ptF.x = rtF.left;
  else if (ptF.x >= rtF.right())
    ptF.x = rtF.right() - fTolerance;

  if (ptF.y < rtF.top)
    ptF.y = rtF.top;
  else if (ptF.y >= rtF.bottom())
    ptF.y = rtF.bottom() - fTolerance;
}
