// 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_FXFA_APP_XFA_TEXTLAYOUT_H_
#define XFA_FXFA_APP_XFA_TEXTLAYOUT_H_

#include <map>
#include <memory>
#include <vector>

#include "xfa/fde/css/fde_css.h"
#include "xfa/fde/fde_gedevice.h"
#include "xfa/fgas/layout/fgas_rtfbreak.h"
#include "xfa/fxfa/parser/xfa_object.h"
#include "xfa/fxfa/xfa_ffdoc.h"

#define XFA_LOADERCNTXTFLG_FILTERSPACE 0x001

class CFDE_CSSStyleSelector;
class CXFA_Para;
class CXFA_Font;
class CXFA_TextProvider;
class CXFA_TextTabstopsContext;

class CXFA_CSSTagProvider {
 public:
  using AttributeMap = std::map<CFX_WideString, CFX_WideString>;

  CXFA_CSSTagProvider();
  ~CXFA_CSSTagProvider();

  CFX_WideString GetTagName() { return m_wsTagName; }

  AttributeMap::iterator begin() { return m_Attributes.begin(); }
  AttributeMap::iterator end() { return m_Attributes.end(); }

  bool empty() const { return m_Attributes.empty(); }

  void SetTagNameObj(const CFX_WideString& wsName) { m_wsTagName = wsName; }
  void SetAttribute(const CFX_WideString& wsAttr,
                    const CFX_WideString& wsValue) {
    m_Attributes.insert({wsAttr, wsValue});
  }

  bool m_bTagAvailable;
  bool m_bContent;

 protected:
  CFX_WideString m_wsTagName;
  AttributeMap m_Attributes;
};

class CXFA_TextParseContext : public CFX_Target {
 public:
  CXFA_TextParseContext();
  ~CXFA_TextParseContext() override;

  void SetDisplay(FDE_CSSDISPLAY eDisplay) { m_eDisplay = eDisplay; }
  FDE_CSSDISPLAY GetDisplay() const { return m_eDisplay; }
  void SetDecls(const CFDE_CSSDeclaration** ppDeclArray, int32_t iDeclCount);
  const CFDE_CSSDeclaration** GetDecls() {
    return const_cast<const CFDE_CSSDeclaration**>(m_ppMatchedDecls);
  }
  uint32_t CountDecls() const { return m_dwMatchedDecls; }

  IFDE_CSSComputedStyle* m_pParentStyle;

 protected:
  CFDE_CSSDeclaration** m_ppMatchedDecls;
  uint32_t m_dwMatchedDecls;
  FDE_CSSDISPLAY m_eDisplay;
};

class CXFA_TextParser {
 public:
  CXFA_TextParser();
  virtual ~CXFA_TextParser();

  void Reset();
  void DoParse(CFDE_XMLNode* pXMLContainer, CXFA_TextProvider* pTextProvider);
  IFDE_CSSComputedStyle* CreateRootStyle(CXFA_TextProvider* pTextProvider);
  IFDE_CSSComputedStyle* ComputeStyle(CFDE_XMLNode* pXMLNode,
                                      IFDE_CSSComputedStyle* pParentStyle);
  bool IsParsed() const { return !!m_pAllocator; }

  int32_t GetVAlign(CXFA_TextProvider* pTextProvider) const;
  FX_FLOAT GetTabInterval(IFDE_CSSComputedStyle* pStyle) const;
  int32_t CountTabs(IFDE_CSSComputedStyle* pStyle) const;
  bool IsSpaceRun(IFDE_CSSComputedStyle* pStyle) const;
  bool GetTabstops(IFDE_CSSComputedStyle* pStyle,
                   CXFA_TextTabstopsContext* pTabstopContext);
  CFGAS_GEFont* GetFont(CXFA_TextProvider* pTextProvider,
                        IFDE_CSSComputedStyle* pStyle) const;
  FX_FLOAT GetFontSize(CXFA_TextProvider* pTextProvider,
                       IFDE_CSSComputedStyle* pStyle) const;
  int32_t GetHorScale(CXFA_TextProvider* pTextProvider,
                      IFDE_CSSComputedStyle* pStyle,
                      CFDE_XMLNode* pXMLNode) const;
  int32_t GetVerScale(CXFA_TextProvider* pTextProvider,
                      IFDE_CSSComputedStyle* pStyle) const;
  void GetUnderline(CXFA_TextProvider* pTextProvider,
                    IFDE_CSSComputedStyle* pStyle,
                    int32_t& iUnderline,
                    int32_t& iPeriod) const;
  void GetLinethrough(CXFA_TextProvider* pTextProvider,
                      IFDE_CSSComputedStyle* pStyle,
                      int32_t& iLinethrough) const;
  FX_ARGB GetColor(CXFA_TextProvider* pTextProvider,
                   IFDE_CSSComputedStyle* pStyle) const;
  FX_FLOAT GetBaseline(CXFA_TextProvider* pTextProvider,
                       IFDE_CSSComputedStyle* pStyle) const;
  FX_FLOAT GetLineHeight(CXFA_TextProvider* pTextProvider,
                         IFDE_CSSComputedStyle* pStyle,
                         bool bFirst,
                         FX_FLOAT fVerScale) const;
  bool GetEmbbedObj(CXFA_TextProvider* pTextProvider,
                    CFDE_XMLNode* pXMLNode,
                    CFX_WideString& wsValue);
  CXFA_TextParseContext* GetParseContextFromMap(CFDE_XMLNode* pXMLNode);

 protected:
  bool TagValidate(const CFX_WideString& str) const;

 private:
  void InitCSSData(CXFA_TextProvider* pTextProvider);
  void ParseRichText(CFDE_XMLNode* pXMLNode,
                     IFDE_CSSComputedStyle* pParentStyle);
  void ParseTagInfo(CFDE_XMLNode* pXMLNode, CXFA_CSSTagProvider& tagProvider);
  IFDE_CSSStyleSheet* LoadDefaultSheetStyle();
  IFDE_CSSComputedStyle* CreateStyle(IFDE_CSSComputedStyle* pParentStyle);
  std::unique_ptr<IFX_MemoryAllocator> m_pAllocator;
  std::unique_ptr<CFDE_CSSStyleSelector> m_pSelector;
  IFDE_CSSStyleSheet* m_pUASheet;
  CFX_MapPtrTemplate<CFDE_XMLNode*, CXFA_TextParseContext*>
      m_mapXMLNodeToParseContext;
};

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

  bool m_bSaveLineHeight;
  FX_FLOAT m_fWidth;
  FX_FLOAT m_fHeight;
  FX_FLOAT m_fLastPos;
  FX_FLOAT m_fStartLineOffset;
  int32_t m_iChar;
  int32_t m_iLines;
  int32_t m_iTotalLines;
  CFDE_XMLNode* m_pXMLNode;
  CXFA_Node* m_pNode;
  IFDE_CSSComputedStyle* m_pParentStyle;
  CFX_ArrayTemplate<FX_FLOAT> m_lineHeights;
  uint32_t m_dwFlags;
  std::vector<FX_FLOAT> m_BlocksHeight;
};

class CXFA_LinkUserData : public IFX_Retainable, public CFX_Target {
 public:
  CXFA_LinkUserData(IFX_MemoryAllocator* pAllocator, FX_WCHAR* pszText);
  ~CXFA_LinkUserData() override;

  // IFX_Retainable:
  uint32_t Retain() override;
  uint32_t Release() override;

  const FX_WCHAR* GetLinkURL();

 protected:
  IFX_MemoryAllocator* m_pAllocator;
  uint32_t m_dwRefCount;
  CFX_WideString m_wsURLContent;
};

class CXFA_TextUserData : public IFX_Retainable, public CFX_Target {
 public:
  CXFA_TextUserData(IFX_MemoryAllocator* pAllocator,
                    IFDE_CSSComputedStyle* pStyle);
  CXFA_TextUserData(IFX_MemoryAllocator* pAllocator,
                    IFDE_CSSComputedStyle* pStyle,
                    CXFA_LinkUserData* pLinkData);
  ~CXFA_TextUserData() override;

  // IFX_Retainable:
  uint32_t Retain() override;
  uint32_t Release() override;

  IFDE_CSSComputedStyle* m_pStyle;
  CXFA_LinkUserData* m_pLinkData;

 protected:
  IFX_MemoryAllocator* m_pAllocator;
  uint32_t m_dwRefCount;
};

class XFA_TextPiece : public CFX_Target {
 public:
  XFA_TextPiece();
  ~XFA_TextPiece() override;

  FX_WCHAR* pszText;
  int32_t iChars;
  int32_t* pWidths;
  int32_t iHorScale;
  int32_t iVerScale;
  int32_t iBidiLevel;
  int32_t iUnderline;
  int32_t iPeriod;
  int32_t iLineThrough;
  CFGAS_GEFont* pFont;
  FX_ARGB dwColor;
  FX_FLOAT fFontSize;
  CFX_RectF rtPiece;
  CXFA_LinkUserData* pLinkData;
};
typedef CFX_ArrayTemplate<XFA_TextPiece*> CXFA_PieceArray;

class CXFA_PieceLine : public CFX_Target {
 public:
  CXFA_PieceLine();
  ~CXFA_PieceLine() override;

  CXFA_PieceArray m_textPieces;
  CFX_Int32Array m_charCounts;
};
typedef CFX_ArrayTemplate<CXFA_PieceLine*> CXFA_PieceLineArray;

struct XFA_TABSTOPS {
  uint32_t dwAlign;
  FX_FLOAT fTabstops;
};

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

  void Append(uint32_t dwAlign, FX_FLOAT fTabstops);
  void RemoveAll();
  void Reset();

  CFX_ArrayTemplate<XFA_TABSTOPS> m_tabstops;
  int32_t m_iTabCount;
  int32_t m_iTabIndex;
  bool m_bTabstops;
  FX_FLOAT m_fTabWidth;
  FX_FLOAT m_fLeft;
};

class CXFA_TextLayout {
 public:
  explicit CXFA_TextLayout(CXFA_TextProvider* pTextProvider);
  ~CXFA_TextLayout();

  int32_t GetText(CFX_WideString& wsText);
  FX_FLOAT GetLayoutHeight();
  FX_FLOAT StartLayout(FX_FLOAT fWidth = -1);
  bool DoLayout(int32_t iBlockIndex,
                FX_FLOAT& fCalcHeight,
                FX_FLOAT fContentAreaHeight = -1,
                FX_FLOAT fTextHeight = -1);

  bool CalcSize(const CFX_SizeF& minSize,
                const CFX_SizeF& maxSize,
                CFX_SizeF& defaultSize);
  bool Layout(const CFX_SizeF& size, FX_FLOAT* fHeight = nullptr);
  void ItemBlocks(const CFX_RectF& rtText, int32_t iBlockIndex);
  bool DrawString(CFX_RenderDevice* pFxDevice,
                  const CFX_Matrix& tmDoc2Device,
                  const CFX_RectF& rtClip,
                  int32_t iBlock = 0);
  bool IsLoaded() const { return m_pieceLines.GetSize() > 0; }
  void Unload();
  const CXFA_PieceLineArray* GetPieceLines();

  bool m_bHasBlock;
  CFX_Int32Array m_Blocks;

 private:
  void GetTextDataNode();
  CFDE_XMLNode* GetXMLContainerNode();
  CFX_RTFBreak* CreateBreak(bool bDefault);
  void InitBreak(FX_FLOAT fLineWidth);
  void InitBreak(IFDE_CSSComputedStyle* pStyle,
                 FDE_CSSDISPLAY eDisplay,
                 FX_FLOAT fLineWidth,
                 CFDE_XMLNode* pXMLNode,
                 IFDE_CSSComputedStyle* pParentStyle = nullptr);
  bool Loader(const CFX_SizeF& szText,
              FX_FLOAT& fLinePos,
              bool bSavePieces = true);
  void LoadText(CXFA_Node* pNode,
                const CFX_SizeF& szText,
                FX_FLOAT& fLinePos,
                bool bSavePieces);
  bool LoadRichText(CFDE_XMLNode* pXMLNode,
                    const CFX_SizeF& szText,
                    FX_FLOAT& fLinePos,
                    IFDE_CSSComputedStyle* pParentStyle,
                    bool bSavePieces,
                    CXFA_LinkUserData* pLinkData = nullptr,
                    bool bEndBreak = true,
                    bool bIsOl = false,
                    int32_t iLiCount = 0);
  bool AppendChar(const CFX_WideString& wsText,
                  FX_FLOAT& fLinePos,
                  FX_FLOAT fSpaceAbove,
                  bool bSavePieces);
  void AppendTextLine(uint32_t dwStatus,
                      FX_FLOAT& fLinePos,
                      bool bSavePieces,
                      bool bEndBreak = false);
  void EndBreak(uint32_t dwStatus, FX_FLOAT& fLinePos, bool bDefault);
  bool IsEnd(bool bSavePieces);
  void ProcessText(CFX_WideString& wsText);
  void UpdateAlign(FX_FLOAT fHeight, FX_FLOAT fBottom);
  void RenderString(CFDE_RenderDevice* pDevice,
                    CFDE_Brush* pBrush,
                    CXFA_PieceLine* pPieceLine,
                    int32_t iPiece,
                    FXTEXT_CHARPOS* pCharPos,
                    const CFX_Matrix& tmDoc2Device);
  void RenderPath(CFDE_RenderDevice* pDevice,
                  CFDE_Pen* pPen,
                  CXFA_PieceLine* pPieceLine,
                  int32_t iPiece,
                  FXTEXT_CHARPOS* pCharPos,
                  const CFX_Matrix& tmDoc2Device);
  int32_t GetDisplayPos(const XFA_TextPiece* pPiece,
                        FXTEXT_CHARPOS* pCharPos,
                        bool bCharCode = false);
  bool ToRun(const XFA_TextPiece* pPiece, FX_RTFTEXTOBJ& tr);
  void DoTabstops(IFDE_CSSComputedStyle* pStyle, CXFA_PieceLine* pPieceLine);
  bool Layout(int32_t iBlock);
  int32_t CountBlocks() const;

  CXFA_TextProvider* m_pTextProvider;
  CXFA_Node* m_pTextDataNode;
  bool m_bRichText;
  std::unique_ptr<IFX_MemoryAllocator> m_pAllocator;
  std::unique_ptr<CFX_RTFBreak> m_pBreak;
  std::unique_ptr<CXFA_LoaderContext> m_pLoader;
  int32_t m_iLines;
  FX_FLOAT m_fMaxWidth;
  CXFA_TextParser m_textParser;
  CXFA_PieceLineArray m_pieceLines;
  std::unique_ptr<CXFA_TextTabstopsContext> m_pTabstopContext;
  bool m_bBlockContinue;
};

#endif  // XFA_FXFA_APP_XFA_TEXTLAYOUT_H_
