// 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_TEXTBREAK_H_
#define XFA_FGAS_LAYOUT_FGAS_TEXTBREAK_H_

#include "core/include/fxcrt/fx_ucd.h"
#include "core/include/fxge/fx_ge.h"
#include "xfa/fgas/crt/fgas_utils.h"
#include "xfa/fgas/layout/fgas_unicode.h"

class IFX_Font;
class CFX_Char;
class IFX_TxtAccess;
class CFX_TxtChar;
class CFX_TxtPiece;
class IFX_TxtBreak;

#define FX_TXTBREAKPOLICY_None 0x00
#define FX_TXTBREAKPOLICY_Pagination 0x01
#define FX_TXTBREAKPOLICY_SpaceBreak 0x02
#define FX_TXTBREAKPOLICY_NumberBreak 0x04
#define FX_TXTBREAK_None 0x00
#define FX_TXTBREAK_PieceBreak 0x01
#define FX_TXTBREAK_LineBreak 0x02
#define FX_TXTBREAK_ParagraphBreak 0x03
#define FX_TXTBREAK_PageBreak 0x04
#define FX_TXTBREAK_ControlChar 0x10
#define FX_TXTBREAK_BreakChar 0x20
#define FX_TXTBREAK_UnknownChar 0x40
#define FX_TXTBREAK_RemoveChar 0x80
#define FX_TXTLAYOUTSTYLE_MutipleFormat 0x0001
#define FX_TXTLAYOUTSTYLE_VerticalLayout 0x0002
#define FX_TXTLAYOUTSTYLE_VerticalChars 0x0004
#define FX_TXTLAYOUTSTYLE_ReverseLine 0x0008
#define FX_TXTLAYOUTSTYLE_ArabicContext 0x0010
#define FX_TXTLAYOUTSTYLE_ArabicShapes 0x0020
#define FX_TXTLAYOUTSTYLE_RTLReadingOrder 0x0040
#define FX_TXTLAYOUTSTYLE_ExpandTab 0x0100
#define FX_TXTLAYOUTSTYLE_SingleLine 0x0200
#define FX_TXTLAYOUTSTYLE_CombText 0x0400
#define FX_TXTCHARSTYLE_Alignment 0x000F
#define FX_TXTCHARSTYLE_ArabicNumber 0x0010
#define FX_TXTCHARSTYLE_ArabicShadda 0x0020
#define FX_TXTCHARSTYLE_OddBidiLevel 0x0040
#define FX_TXTCHARSTYLE_RTLReadingOrder 0x0080
#define FX_TXTCHARSTYLE_ArabicContext 0x0300
#define FX_TXTCHARSTYLE_ArabicIndic 0x0400
#define FX_TXTCHARSTYLE_ArabicComma 0x0800
#define FX_TXTLINEALIGNMENT_Left 0
#define FX_TXTLINEALIGNMENT_Center 1
#define FX_TXTLINEALIGNMENT_Right 2
#define FX_TXTLINEALIGNMENT_Justified (1 << 2)
#define FX_TXTLINEALIGNMENT_Distributed (2 << 2)
#define FX_TXTLINEALIGNMENT_JustifiedLeft \
  (FX_TXTLINEALIGNMENT_Left | FX_TXTLINEALIGNMENT_Justified)
#define FX_TXTLINEALIGNMENT_JustifiedCenter \
  (FX_TXTLINEALIGNMENT_Center | FX_TXTLINEALIGNMENT_Justified)
#define FX_TXTLINEALIGNMENT_JustifiedRight \
  (FX_TXTLINEALIGNMENT_Right | FX_TXTLINEALIGNMENT_Justified)
#define FX_TXTLINEALIGNMENT_DistributedLeft \
  (FX_TXTLINEALIGNMENT_Left | FX_TXTLINEALIGNMENT_Distributed)
#define FX_TXTLINEALIGNMENT_DistributedCenter \
  (FX_TXTLINEALIGNMENT_Center | FX_TXTLINEALIGNMENT_Distributed)
#define FX_TXTLINEALIGNMENT_DistributedRight \
  (FX_TXTLINEALIGNMENT_Right | FX_TXTLINEALIGNMENT_Distributed)
#define FX_TXTLINEALIGNMENT_LowerMask 0x03
#define FX_TXTLINEALIGNMENT_HigherMask 0x0C
#define FX_TXTBREAK_MinimumTabWidth 160000

class IFX_TxtAccess {
 public:
  virtual ~IFX_TxtAccess() {}
  virtual FX_WCHAR GetChar(void* pIdentity, int32_t index) const = 0;
  virtual int32_t GetWidth(void* pIdentity, int32_t index) const = 0;
};

struct FX_TXTRUN {
  FX_TXTRUN() {
    pAccess = NULL;
    pIdentity = NULL;
    pStr = NULL;
    pWidths = NULL;
    iLength = 0;
    pFont = NULL;
    fFontSize = 12;
    dwStyles = 0;
    iHorizontalScale = 100;
    iVerticalScale = 100;
    iCharRotation = 0;
    dwCharStyles = 0;
    pRect = NULL;
    wLineBreakChar = L'\n';
    bSkipSpace = TRUE;
  }

  IFX_TxtAccess* pAccess;
  void* pIdentity;
  const FX_WCHAR* pStr;
  int32_t* pWidths;
  int32_t iLength;
  IFX_Font* pFont;
  FX_FLOAT fFontSize;
  FX_DWORD dwStyles;
  int32_t iHorizontalScale;
  int32_t iVerticalScale;
  int32_t iCharRotation;
  FX_DWORD dwCharStyles;
  const CFX_RectF* pRect;
  FX_WCHAR wLineBreakChar;
  FX_BOOL bSkipSpace;
};

class CFX_TxtPiece : public CFX_Target {
 public:
  CFX_TxtPiece()
      : m_dwStatus(FX_TXTBREAK_PieceBreak),
        m_iStartPos(0),
        m_iWidth(-1),
        m_iStartChar(0),
        m_iChars(0),
        m_iBidiLevel(0),
        m_iBidiPos(0),
        m_iHorizontalScale(100),
        m_iVerticalScale(100),
        m_dwCharStyles(0),
        m_pChars(NULL),
        m_pUserData(NULL) {}
  int32_t GetEndPos() const {
    return m_iWidth < 0 ? m_iStartPos : m_iStartPos + m_iWidth;
  }
  int32_t GetLength() const { return m_iChars; }
  int32_t GetEndChar() const { return m_iStartChar + m_iChars; }
  CFX_TxtChar* GetCharPtr(int32_t index) const {
    FXSYS_assert(index > -1 && index < m_iChars && m_pChars != NULL);
    return m_pChars->GetDataPtr(m_iStartChar + index);
  }
  void GetString(FX_WCHAR* pText) const {
    FXSYS_assert(pText != NULL);
    int32_t iEndChar = m_iStartChar + m_iChars;
    CFX_Char* pChar;
    for (int32_t i = m_iStartChar; i < iEndChar; i++) {
      pChar = m_pChars->GetDataPtr(i);
      *pText++ = (FX_WCHAR)pChar->m_wCharCode;
    }
  }

  void GetString(CFX_WideString& wsText) const {
    FX_WCHAR* pText = wsText.GetBuffer(m_iChars);
    GetString(pText);
    wsText.ReleaseBuffer(m_iChars);
  }
  void GetWidths(int32_t* pWidths) const {
    FXSYS_assert(pWidths != NULL);
    int32_t iEndChar = m_iStartChar + m_iChars;
    CFX_Char* pChar;
    for (int32_t i = m_iStartChar; i < iEndChar; i++) {
      pChar = m_pChars->GetDataPtr(i);
      *pWidths++ = pChar->m_iCharWidth;
    }
  }
  FX_DWORD 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_iHorizontalScale;
  int32_t m_iVerticalScale;
  FX_DWORD m_dwCharStyles;
  CFX_TxtCharArray* m_pChars;
  void* m_pUserData;
};
typedef CFX_BaseArrayTemplate<CFX_TxtPiece> CFX_TxtPieceArray;

class IFX_TxtBreak {
 public:
  static IFX_TxtBreak* Create(FX_DWORD dwPolicies);
  virtual ~IFX_TxtBreak() {}
  virtual void Release() = 0;
  virtual void SetLineWidth(FX_FLOAT fLineWidth) = 0;
  virtual void SetLinePos(FX_FLOAT fLinePos) = 0;
  virtual FX_DWORD GetLayoutStyles() const = 0;
  virtual void SetLayoutStyles(FX_DWORD dwLayoutStyles) = 0;
  virtual void SetFont(IFX_Font* pFont) = 0;
  virtual void SetFontSize(FX_FLOAT fFontSize) = 0;
  virtual void SetTabWidth(FX_FLOAT fTabWidth, FX_BOOL bEquidistant) = 0;
  virtual void SetDefaultChar(FX_WCHAR wch) = 0;
  virtual void SetParagraphBreakChar(FX_WCHAR wch) = 0;
  virtual void SetLineBreakTolerance(FX_FLOAT fTolerance) = 0;
  virtual void SetHorizontalScale(int32_t iScale) = 0;
  virtual void SetVerticalScale(int32_t iScale) = 0;
  virtual void SetCharRotation(int32_t iCharRotation) = 0;
  virtual void SetCharSpace(FX_FLOAT fCharSpace) = 0;
  virtual void SetAlignment(int32_t iAlignment) = 0;
  virtual FX_DWORD GetContextCharStyles() const = 0;
  virtual void SetContextCharStyles(FX_DWORD dwCharStyles) = 0;
  virtual void SetCombWidth(FX_FLOAT fCombWidth) = 0;
  virtual void SetUserData(void* pUserData) = 0;
  virtual FX_DWORD AppendChar(FX_WCHAR wch) = 0;
  virtual FX_DWORD EndBreak(FX_DWORD dwStatus = FX_TXTBREAK_PieceBreak) = 0;
  virtual int32_t CountBreakChars() const = 0;
  virtual int32_t CountBreakPieces() const = 0;
  virtual const CFX_TxtPiece* GetBreakPiece(int32_t index) const = 0;
  virtual void ClearBreakPieces() = 0;
  virtual void Reset() = 0;
  virtual int32_t GetDisplayPos(
      const FX_TXTRUN* pTxtRun,
      FXTEXT_CHARPOS* pCharPos,
      FX_BOOL bCharCode = FALSE,
      CFX_WideString* pWSForms = NULL,
      FX_AdjustCharDisplayPos pAdjustPos = NULL) const = 0;
  virtual int32_t GetCharRects(const FX_TXTRUN* pTxtRun,
                               CFX_RectFArray& rtArray,
                               FX_BOOL bCharBBox = FALSE) const = 0;
};

#endif  // XFA_FGAS_LAYOUT_FGAS_TEXTBREAK_H_
