// 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

#ifndef XFA_FGAS_LAYOUT_FGAS_RTFBREAK_H_
#define XFA_FGAS_LAYOUT_FGAS_RTFBREAK_H_

#include <deque>
#include <vector>

#include "core/fxcrt/cfx_retain_ptr.h"
#include "core/fxcrt/fx_basic.h"
#include "core/fxcrt/fx_ucd.h"
#include "xfa/fgas/crt/fgas_utils.h"
#include "xfa/fgas/layout/fgas_textbreak.h"

class CFGAS_GEFont;

#define FX_RTFLAYOUTSTYLE_Pagination 0x01
#define FX_RTFLAYOUTSTYLE_ExpandTab 0x10

enum class CFX_RTFLineAlignment {
  Left = 0,
  Center,
  Right,
  Justified,
  Distributed
};

struct FX_RTFTEXTOBJ {
  FX_RTFTEXTOBJ();
  ~FX_RTFTEXTOBJ();

  CFX_WideString pStr;
  std::vector<int32_t> pWidths;
  CFX_RetainPtr<CFGAS_GEFont> pFont;
  const CFX_RectF* pRect;
  FX_WCHAR wLineBreakChar;
  FX_FLOAT fFontSize;
  int32_t iLength;
  int32_t iBidiLevel;
  int32_t iHorizontalScale;
  int32_t iVerticalScale;
};

class CFX_RTFPiece {
 public:
  CFX_RTFPiece();
  CFX_RTFPiece(const CFX_RTFPiece& other);
  ~CFX_RTFPiece();

  int32_t GetEndPos() const {
    return m_iWidth < 0 ? m_iStartPos : m_iStartPos + m_iWidth;
  }

  CFX_RTFChar& GetChar(int32_t index) {
    ASSERT(index > -1 && index < m_iChars && m_pChars);
    return (*m_pChars)[m_iStartChar + index];
  }

  CFX_WideString GetString() const {
    CFX_WideString ret;
    ret.Reserve(m_iChars);
    for (int32_t i = m_iStartChar; i < m_iStartChar + m_iChars; i++)
      ret += static_cast<FX_WCHAR>((*m_pChars)[i].m_wCharCode);
    return ret;
  }

  std::vector<int32_t> GetWidths() const {
    std::vector<int32_t> ret;
    ret.reserve(m_iChars);
    for (int32_t i = m_iStartChar; i < m_iStartChar + m_iChars; i++)
      ret.push_back((*m_pChars)[i].m_iCharWidth);
    return ret;
  }

  CFX_RTFBreakType m_dwStatus;
  int32_t m_iStartPos;
  int32_t m_iWidth;
  int32_t m_iStartChar;
  int32_t m_iChars;
  int32_t m_iBidiLevel;
  int32_t m_iBidiPos;
  int32_t m_iFontSize;
  int32_t m_iFontHeight;
  int32_t m_iHorizontalScale;
  int32_t m_iVerticalScale;
  uint32_t m_dwIdentity;
  std::vector<CFX_RTFChar>* m_pChars;  // not owned.
  CFX_RetainPtr<CFX_Retainable> m_pUserData;
};

class CFX_RTFLine {
 public:
  CFX_RTFLine();
  ~CFX_RTFLine();

  int32_t CountChars() const {
    return pdfium::CollectionSize<int32_t>(m_LineChars);
  }

  CFX_RTFChar& GetChar(int32_t index) {
    ASSERT(index >= 0 && index < pdfium::CollectionSize<int32_t>(m_LineChars));
    return m_LineChars[index];
  }

  int32_t GetLineEnd() const { return m_iStart + m_iWidth; }
  void Clear() {
    m_LineChars.clear();
    m_LinePieces.clear();
    m_iWidth = 0;
    m_iArabicChars = 0;
  }

  std::vector<CFX_RTFChar> m_LineChars;
  std::vector<CFX_RTFPiece> m_LinePieces;
  int32_t m_iStart;
  int32_t m_iWidth;
  int32_t m_iArabicChars;
};

class CFX_RTFBreak {
 public:
  explicit CFX_RTFBreak(uint32_t dwLayoutStyles);
  ~CFX_RTFBreak();

  void SetLineBoundary(FX_FLOAT fLineStart, FX_FLOAT fLineEnd);
  void SetLineStartPos(FX_FLOAT fLinePos);
  void SetFont(const CFX_RetainPtr<CFGAS_GEFont>& pFont);
  void SetFontSize(FX_FLOAT fFontSize);
  void SetTabWidth(FX_FLOAT fTabWidth);
  void SetLineBreakTolerance(FX_FLOAT fTolerance);
  void SetHorizontalScale(int32_t iScale);
  void SetVerticalScale(int32_t iScale);
  void SetCharSpace(FX_FLOAT fCharSpace);
  void SetAlignment(CFX_RTFLineAlignment align) { m_iAlignment = align; }
  void SetUserData(const CFX_RetainPtr<CFX_Retainable>& pUserData);

  void AddPositionedTab(FX_FLOAT fTabPos);

  CFX_RTFBreakType EndBreak(CFX_RTFBreakType dwStatus);
  int32_t CountBreakPieces() const;
  const CFX_RTFPiece* GetBreakPieceUnstable(int32_t index) const;
  void ClearBreakPieces();

  void Reset();

  int32_t GetDisplayPos(const FX_RTFTEXTOBJ* pText,
                        FXTEXT_CHARPOS* pCharPos,
                        bool bCharCode) const;

  CFX_RTFBreakType AppendChar(FX_WCHAR wch);

  CFX_RTFLine* GetCurrentLineForTesting() const { return m_pCurLine; }

 private:
  void AppendChar_Combination(CFX_RTFChar* pCurChar);
  void AppendChar_Tab(CFX_RTFChar* pCurChar);
  CFX_RTFBreakType AppendChar_Control(CFX_RTFChar* pCurChar);
  CFX_RTFBreakType AppendChar_Arabic(CFX_RTFChar* pCurChar);
  CFX_RTFBreakType AppendChar_Others(CFX_RTFChar* pCurChar);
  void FontChanged();
  void SetBreakStatus();
  CFX_RTFChar* GetLastChar(int32_t index) const;
  bool HasRTFLine() const { return m_iReady >= 0; }
  FX_CHARTYPE GetUnifiedCharType(FX_CHARTYPE chartype) const;
  int32_t GetLastPositionedTab() const;
  bool GetPositionedTab(int32_t* iTabPos) const;

  int32_t GetBreakPos(std::vector<CFX_RTFChar>& tca,
                      int32_t& iEndPos,
                      bool bAllChars,
                      bool bOnlyBrk);
  void SplitTextLine(CFX_RTFLine* pCurLine,
                     CFX_RTFLine* pNextLine,
                     bool bAllChars);
  bool EndBreak_SplitLine(CFX_RTFLine* pNextLine,
                          bool bAllChars,
                          CFX_RTFBreakType dwStatus);
  void EndBreak_BidiLine(std::deque<FX_TPO>* tpos, CFX_RTFBreakType dwStatus);
  void EndBreak_Alignment(const std::deque<FX_TPO>& tpos,
                          bool bAllChars,
                          CFX_RTFBreakType dwStatus);

  int32_t m_iBoundaryStart;
  int32_t m_iBoundaryEnd;
  uint32_t m_dwLayoutStyles;
  bool m_bPagination;
  CFX_RetainPtr<CFGAS_GEFont> m_pFont;
  int32_t m_iFontHeight;
  int32_t m_iFontSize;
  int32_t m_iTabWidth;
  std::vector<int32_t> m_PositionedTabs;
  FX_WCHAR m_wDefChar;
  int32_t m_iDefChar;
  FX_WCHAR m_wLineBreakChar;
  int32_t m_iHorizontalScale;
  int32_t m_iVerticalScale;
  int32_t m_iCharSpace;
  CFX_RTFLineAlignment m_iAlignment;
  CFX_RetainPtr<CFX_Retainable> m_pUserData;
  FX_CHARTYPE m_eCharType;
  uint32_t m_dwIdentity;
  CFX_RTFLine m_RTFLine[2];
  CFX_RTFLine* m_pCurLine;
  int32_t m_iTolerance;
  int8_t m_iReady;
};

#endif  // XFA_FGAS_LAYOUT_FGAS_RTFBREAK_H_
