// 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/fee/fde_txtedtbuf.h"

#include <algorithm>

#include "xfa/fee/ifde_txtedtbuf.h"
#include "xfa/fee/ifde_txtedtengine.h"

#define FDE_DEFCHUNKCOUNT 2
#define FDE_TXTEDT_FORMATBLOCK_BGN 0xFFF9
#define FDE_TXTEDT_FORMATBLOCK_END 0xFFFB
#define FDE_TXTEDT_ZEROWIDTHSPACE 0x200B

CFDE_TxtEdtBufIter::CFDE_TxtEdtBufIter(CFDE_TxtEdtBuf* pBuf, FX_WCHAR wcAlias)
    : m_pBuf(pBuf),
      m_nCurChunk(0),
      m_nCurIndex(0),
      m_nIndex(0),
      m_Alias(wcAlias) {
  FXSYS_assert(m_pBuf);
}
CFDE_TxtEdtBufIter::~CFDE_TxtEdtBufIter() {}
void CFDE_TxtEdtBufIter::Release() {
  delete this;
}
FX_BOOL CFDE_TxtEdtBufIter::Next(FX_BOOL bPrev) {
  if (bPrev) {
    if (m_nIndex == 0) {
      return FALSE;
    }
    FXSYS_assert(m_nCurChunk < m_pBuf->m_Chunks.GetSize());
    CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER lpChunk = NULL;
    if (m_nCurIndex > 0) {
      m_nCurIndex--;
    } else {
      while (m_nCurChunk > 0) {
        --m_nCurChunk;
        lpChunk =
            (CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER)m_pBuf->m_Chunks[m_nCurChunk];
        if (lpChunk->nUsed > 0) {
          m_nCurIndex = lpChunk->nUsed - 1;
          break;
        }
      }
    }
    FXSYS_assert(m_nCurChunk >= 0);
    m_nIndex--;
    return TRUE;
  } else {
    if (m_nIndex >= (m_pBuf->m_nTotal - 1)) {
      return FALSE;
    }
    FXSYS_assert(m_nCurChunk < m_pBuf->m_Chunks.GetSize());
    CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER lpChunk =
        (CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER)m_pBuf->m_Chunks[m_nCurChunk];
    if (lpChunk->nUsed != (m_nCurIndex + 1)) {
      m_nCurIndex++;
    } else {
      int32_t nEnd = m_pBuf->m_Chunks.GetSize() - 1;
      while (m_nCurChunk < nEnd) {
        m_nCurChunk++;
        CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER lpChunkTemp =
            (CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER)m_pBuf->m_Chunks[m_nCurChunk];
        if (lpChunkTemp->nUsed > 0) {
          m_nCurIndex = 0;
          break;
        }
      }
    }
    m_nIndex++;
    return TRUE;
  }
}
void CFDE_TxtEdtBufIter::SetAt(int32_t nIndex) {
  FXSYS_assert(nIndex >= 0 && nIndex < m_pBuf->m_nTotal);
  CFDE_TxtEdtBuf::FDE_CHUNKPLACE cp;
  m_pBuf->Index2CP(nIndex, cp);
  m_nIndex = nIndex;
  m_nCurChunk = cp.nChunkIndex;
  m_nCurIndex = cp.nCharIndex;
}
int32_t CFDE_TxtEdtBufIter::GetAt() const {
  return m_nIndex;
}
FX_WCHAR CFDE_TxtEdtBufIter::GetChar() {
  FXSYS_assert(m_nIndex >= 0 && m_nIndex < m_pBuf->m_nTotal);
  if (m_Alias == 0 || m_nIndex == (m_pBuf->m_nTotal - 1)) {
    return ((CFDE_TxtEdtBuf::FDE_LPCHUNKHEADER)m_pBuf->m_Chunks[m_nCurChunk])
        ->wChars[m_nCurIndex];
  }
  return m_Alias;
}
FX_BOOL CFDE_TxtEdtBufIter::IsEOF(FX_BOOL bTail) const {
  return bTail ? m_nIndex == (m_pBuf->GetTextLength() - 2) : m_nIndex == 0;
}
IFX_CharIter* CFDE_TxtEdtBufIter::Clone() {
  CFDE_TxtEdtBufIter* pIter = new CFDE_TxtEdtBufIter(m_pBuf);
  pIter->m_nCurChunk = m_nCurChunk;
  pIter->m_nCurIndex = m_nCurIndex;
  pIter->m_nIndex = m_nIndex;
  pIter->m_Alias = m_Alias;
  return pIter;
}
CFDE_TxtEdtBuf::CFDE_TxtEdtBuf(int32_t nDefChunkSize)
    : m_nChunkSize(nDefChunkSize),
      m_nTotal(0),
      m_bChanged(FALSE),
      m_pAllocator(NULL) {
  FXSYS_assert(m_nChunkSize);
  ResetChunkBuffer(FDE_DEFCHUNKCOUNT, m_nChunkSize);
}
void CFDE_TxtEdtBuf::Release() {
  delete this;
}
CFDE_TxtEdtBuf::~CFDE_TxtEdtBuf() {
  Clear(TRUE);
  m_pAllocator->Release();
  m_Chunks.RemoveAll();
}
FX_BOOL CFDE_TxtEdtBuf::SetChunkSize(int32_t nChunkSize) {
  FXSYS_assert(nChunkSize);
  ResetChunkBuffer(FDE_DEFCHUNKCOUNT, nChunkSize);
  return TRUE;
}
int32_t CFDE_TxtEdtBuf::GetChunkSize() const {
  return m_nChunkSize;
}
int32_t CFDE_TxtEdtBuf::GetTextLength() const {
  return m_nTotal;
}
void CFDE_TxtEdtBuf::SetText(const CFX_WideString& wsText) {
  FXSYS_assert(!wsText.IsEmpty());
  Clear(FALSE);
  int32_t nTextLength = wsText.GetLength();
  int32_t nNeedCount =
      ((nTextLength - 1) / m_nChunkSize + 1) - m_Chunks.GetSize();
  int32_t i = 0;
  for (i = 0; i < nNeedCount; i++) {
    FDE_LPCHUNKHEADER lpChunk = (FDE_LPCHUNKHEADER)m_pAllocator->Alloc(
        sizeof(FDE_CHUNKHEADER) + (m_nChunkSize - 1) * sizeof(FX_WCHAR));
    lpChunk->nUsed = 0;
    m_Chunks.Add(lpChunk);
  }
  int32_t nTotalCount = m_Chunks.GetSize();
  const FX_WCHAR* lpSrcBuf = wsText.c_str();
  int32_t nLeave = nTextLength;
  int32_t nCopyedLength = m_nChunkSize;
  for (i = 0; i < nTotalCount && nLeave > 0; i++) {
    if (nLeave < nCopyedLength) {
      nCopyedLength = nLeave;
    }
    FDE_LPCHUNKHEADER lpChunk = (FDE_LPCHUNKHEADER)m_Chunks[i];
    FXSYS_memcpy(lpChunk->wChars, lpSrcBuf, nCopyedLength * sizeof(FX_WCHAR));
    nLeave -= nCopyedLength;
    lpSrcBuf += nCopyedLength;
    lpChunk->nUsed = nCopyedLength;
  }
  m_nTotal = nTextLength;
  m_bChanged = TRUE;
}
void CFDE_TxtEdtBuf::GetText(CFX_WideString& wsText) const {
  GetRange(wsText, 0, m_nTotal);
}
FX_WCHAR CFDE_TxtEdtBuf::GetCharByIndex(int32_t nIndex) const {
  FXSYS_assert(nIndex >= 0 && nIndex < GetTextLength());
  FDE_LPCHUNKHEADER pChunkHeader = NULL;
  int32_t nTotal = 0;
  int32_t nCount = m_Chunks.GetSize();
  int32_t i = 0;
  for (i = 0; i < nCount; i++) {
    pChunkHeader = (FDE_LPCHUNKHEADER)m_Chunks[i];
    nTotal += pChunkHeader->nUsed;
    if (nTotal > nIndex) {
      break;
    }
  }
  FXSYS_assert(pChunkHeader);
  return pChunkHeader->wChars[pChunkHeader->nUsed - (nTotal - nIndex)];
}
void CFDE_TxtEdtBuf::GetRange(CFX_WideString& wsText,
                              int32_t nBegin,
                              int32_t nLength) const {
  FDE_CHUNKPLACE cp;
  Index2CP(nBegin, cp);
  int32_t nLeave = nLength;
  int32_t nCount = m_Chunks.GetSize();
  FX_WCHAR* lpDstBuf = wsText.GetBuffer(nLength);
  int32_t nChunkIndex = cp.nChunkIndex;
  FDE_LPCHUNKHEADER lpChunkHeader = (FDE_LPCHUNKHEADER)m_Chunks[nChunkIndex];
  int32_t nCopyLength = lpChunkHeader->nUsed - cp.nCharIndex;
  FX_WCHAR* lpSrcBuf = lpChunkHeader->wChars + cp.nCharIndex;
  while (nLeave > 0) {
    if (nLeave <= nCopyLength) {
      nCopyLength = nLeave;
    }
    FXSYS_memcpy(lpDstBuf, lpSrcBuf, nCopyLength * sizeof(FX_WCHAR));
    nChunkIndex++;
    if (nChunkIndex >= nCount) {
      break;
    }
    lpChunkHeader = (FDE_LPCHUNKHEADER)m_Chunks[nChunkIndex];
    lpSrcBuf = lpChunkHeader->wChars;
    nLeave -= nCopyLength;
    lpDstBuf += nCopyLength;
    nCopyLength = lpChunkHeader->nUsed;
  }
  wsText.ReleaseBuffer();
}
void CFDE_TxtEdtBuf::Insert(int32_t nPos,
                            const FX_WCHAR* lpText,
                            int32_t nLength) {
  FXSYS_assert(nPos >= 0 && nPos <= m_nTotal);
  FDE_CHUNKPLACE cp;
  Index2CP(nPos, cp);
  int32_t nLengthTemp = nLength;
  if (cp.nCharIndex != 0) {
    FDE_LPCHUNKHEADER lpNewChunk = (FDE_LPCHUNKHEADER)m_pAllocator->Alloc(
        sizeof(FDE_CHUNKHEADER) + (m_nChunkSize - 1) * sizeof(FX_WCHAR));
    FDE_LPCHUNKHEADER lpChunk = (FDE_LPCHUNKHEADER)m_Chunks[cp.nChunkIndex];
    int32_t nCopy = lpChunk->nUsed - cp.nCharIndex;
    FXSYS_memcpy(lpNewChunk->wChars, lpChunk->wChars + cp.nCharIndex,
                 nCopy * sizeof(FX_WCHAR));
    lpChunk->nUsed -= nCopy;
    cp.nChunkIndex++;
    m_Chunks.InsertAt(cp.nChunkIndex, lpNewChunk);
    lpNewChunk->nUsed = nCopy;
    cp.nCharIndex = 0;
  }
  if (cp.nChunkIndex != 0) {
    FDE_LPCHUNKHEADER lpChunk = (FDE_LPCHUNKHEADER)m_Chunks[cp.nChunkIndex - 1];
    if (lpChunk->nUsed != m_nChunkSize) {
      cp.nChunkIndex--;
      int32_t nFree = m_nChunkSize - lpChunk->nUsed;
      int32_t nCopy = std::min(nLengthTemp, nFree);
      FXSYS_memcpy(lpChunk->wChars + lpChunk->nUsed, lpText,
                   nCopy * sizeof(FX_WCHAR));
      lpText += nCopy;
      nLengthTemp -= nCopy;
      lpChunk->nUsed += nCopy;
      cp.nChunkIndex++;
    }
  }
  while (nLengthTemp > 0) {
    FDE_LPCHUNKHEADER lpChunk = (FDE_LPCHUNKHEADER)m_pAllocator->Alloc(
        sizeof(FDE_CHUNKHEADER) + (m_nChunkSize - 1) * sizeof(FX_WCHAR));
    FXSYS_assert(lpChunk);
    int32_t nCopy = std::min(nLengthTemp, m_nChunkSize);
    FXSYS_memcpy(lpChunk->wChars, lpText, nCopy * sizeof(FX_WCHAR));
    lpText += nCopy;
    nLengthTemp -= nCopy;
    lpChunk->nUsed = nCopy;
    m_Chunks.InsertAt(cp.nChunkIndex, lpChunk);
    cp.nChunkIndex++;
  }
  m_nTotal += nLength;
  m_bChanged = TRUE;
}
void CFDE_TxtEdtBuf::Delete(int32_t nIndex, int32_t nLength) {
  FXSYS_assert(nLength > 0 && nIndex >= 0 && nIndex + nLength <= m_nTotal);
  FDE_CHUNKPLACE cpEnd;
  Index2CP(nIndex + nLength - 1, cpEnd);
  m_nTotal -= nLength;
  FDE_LPCHUNKHEADER lpChunk = (FDE_LPCHUNKHEADER)m_Chunks[cpEnd.nChunkIndex];
  int32_t nFirstPart = cpEnd.nCharIndex + 1;
  int32_t nMovePart = lpChunk->nUsed - nFirstPart;
  if (nMovePart != 0) {
    int32_t nDelete = std::min(nFirstPart, nLength);
    FXSYS_memmove(lpChunk->wChars + nFirstPart - nDelete,
                  lpChunk->wChars + nFirstPart, nMovePart * sizeof(FX_WCHAR));
    lpChunk->nUsed -= nDelete;
    nLength -= nDelete;
    cpEnd.nChunkIndex--;
  }
  while (nLength > 0) {
    lpChunk = (FDE_LPCHUNKHEADER)m_Chunks[cpEnd.nChunkIndex];
    int32_t nDeleted = std::min(lpChunk->nUsed, nLength);
    lpChunk->nUsed -= nDeleted;
    if (lpChunk->nUsed == 0) {
      m_pAllocator->Free(lpChunk);
      m_Chunks.RemoveAt(cpEnd.nChunkIndex);
      lpChunk = NULL;
    }
    nLength -= nDeleted;
    cpEnd.nChunkIndex--;
  }
  m_bChanged = TRUE;
}
void CFDE_TxtEdtBuf::Clear(FX_BOOL bRelease) {
  int32_t i = 0;
  int32_t nCount = m_Chunks.GetSize();
  if (bRelease) {
    while (i < nCount) {
      m_pAllocator->Free(m_Chunks[i++]);
    }
    m_Chunks.RemoveAll();
  } else {
    while (i < nCount) {
      ((FDE_LPCHUNKHEADER)m_Chunks[i++])->nUsed = 0;
    }
  }
  m_nTotal = 0;
  m_bChanged = TRUE;
}
FX_BOOL CFDE_TxtEdtBuf::Optimize(IFX_Pause* pPause) {
  if (m_bChanged == FALSE) {
    return TRUE;
  }
  if (m_nTotal == 0) {
    return TRUE;
  }
  int32_t nCount = m_Chunks.GetSize();
  if (nCount == 0) {
    return TRUE;
  }
  int32_t i = 0;
  for (; i < nCount; i++) {
    FDE_LPCHUNKHEADER lpChunk = (FDE_LPCHUNKHEADER)m_Chunks[i];
    if (lpChunk->nUsed == 0) {
      m_pAllocator->Free(lpChunk);
      m_Chunks.RemoveAt(i);
      --i;
      --nCount;
    }
  }
  if (pPause != NULL && pPause->NeedToPauseNow()) {
    return FALSE;
  }
  FDE_LPCHUNKHEADER lpPreChunk = (FDE_LPCHUNKHEADER)m_Chunks[0];
  FDE_LPCHUNKHEADER lpCurChunk = NULL;
  for (i = 1; i < nCount; i++) {
    lpCurChunk = (FDE_LPCHUNKHEADER)m_Chunks[i];
    if (lpPreChunk->nUsed + lpCurChunk->nUsed <= m_nChunkSize) {
      FXSYS_memcpy(lpPreChunk->wChars + lpPreChunk->nUsed, lpCurChunk->wChars,
                   lpCurChunk->nUsed * sizeof(FX_WCHAR));
      lpPreChunk->nUsed += lpCurChunk->nUsed;
      m_pAllocator->Free(lpCurChunk);
      m_Chunks.RemoveAt(i);
      --i;
      --nCount;
    } else {
      lpPreChunk = lpCurChunk;
    }
    if (pPause != NULL && pPause->NeedToPauseNow()) {
      return FALSE;
    }
  }
  m_bChanged = FALSE;
  return TRUE;
}
void CFDE_TxtEdtBuf::ResetChunkBuffer(int32_t nDefChunkCount,
                                      int32_t nChunkSize) {
  FXSYS_assert(nChunkSize);
  FXSYS_assert(nDefChunkCount);
  if (m_pAllocator) {
    m_pAllocator->Release();
    m_pAllocator = NULL;
  }
  m_Chunks.RemoveAll();
  m_nChunkSize = nChunkSize;
  int32_t nChunkLength =
      sizeof(FDE_CHUNKHEADER) + (m_nChunkSize - 1) * sizeof(FX_WCHAR);
  m_pAllocator =
      FX_CreateAllocator(FX_ALLOCTYPE_Fixed, nDefChunkCount, nChunkLength);
  FXSYS_assert(m_pAllocator);
  FDE_LPCHUNKHEADER lpChunkHeader =
      (FDE_LPCHUNKHEADER)m_pAllocator->Alloc(nChunkLength);
  FXSYS_assert(lpChunkHeader);
  lpChunkHeader->nUsed = 0;
  m_Chunks.Add(lpChunkHeader);
  m_nTotal = 0;
}
int32_t CFDE_TxtEdtBuf::CP2Index(const FDE_CHUNKPLACE& cp) const {
  int32_t nTotal = cp.nCharIndex;
  int32_t i = 0;
  for (i = 0; i < cp.nChunkIndex; i++) {
    nTotal += ((FDE_LPCHUNKHEADER)m_Chunks[i])->nUsed;
  }
  return nTotal;
}
void CFDE_TxtEdtBuf::Index2CP(int32_t nIndex, FDE_CHUNKPLACE& cp) const {
  FXSYS_assert(nIndex <= GetTextLength());
  if (nIndex == m_nTotal) {
    cp.nChunkIndex = m_Chunks.GetSize() - 1;
    cp.nCharIndex = ((FDE_LPCHUNKHEADER)m_Chunks[cp.nChunkIndex])->nUsed;
    return;
  }
  int32_t i = 0;
  int32_t nTotal = 0;
  int32_t nCount = m_Chunks.GetSize();
  for (; i < nCount; i++) {
    nTotal += ((FDE_LPCHUNKHEADER)m_Chunks[i])->nUsed;
    if (nTotal > nIndex) {
      break;
    }
  }
  cp.nChunkIndex = i;
  cp.nCharIndex = ((FDE_LPCHUNKHEADER)m_Chunks[i])->nUsed - (nTotal - nIndex);
}
