// Copyright 2017 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_CXFA_TEXTLAYOUT_H_
#define XFA_FXFA_CXFA_TEXTLAYOUT_H_

#include <memory>
#include <vector>

#include "core/fxcrt/css/cfx_css.h"
#include "core/fxcrt/fx_coordinates.h"
#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/retain_ptr.h"
#include "core/fxcrt/unowned_ptr.h"
#include "core/fxge/dib/fx_dib.h"
#include "fxjs/gc/heap.h"
#include "v8/include/cppgc/garbage-collected.h"
#include "v8/include/cppgc/member.h"
#include "v8/include/cppgc/visitor.h"
#include "xfa/fgas/layout/cfgas_char.h"
#include "xfa/fgas/layout/cfgas_textpiece.h"
#include "xfa/fxfa/fxfa_basic.h"

class CFGAS_LinkUserData;
class CFGAS_RTFBreak;
class CFX_CSSComputedStyle;
class CFX_RenderDevice;
class CFX_XMLNode;
class CXFA_FFDoc;
class CXFA_Node;
class CXFA_TextParser;
class CXFA_TextProvider;
class CXFA_TextTabstopsContext;
class TextCharPos;

class CXFA_TextLayout final : public cppgc::GarbageCollected<CXFA_TextLayout> {
 public:
  CONSTRUCT_VIA_MAKE_GARBAGE_COLLECTED;
  ~CXFA_TextLayout();

  void Trace(cppgc::Visitor* visitor) const;

  float GetLayoutHeight();
  float StartLayout(float fWidth);
  float DoLayout(float fTextHeight);
  float DoSplitLayout(size_t szBlockIndex,
                      float fCalcHeight,
                      float fTextHeight);
  float Layout(const CFX_SizeF& size);

  CFX_SizeF CalcSize(const CFX_SizeF& minSize, const CFX_SizeF& maxSize);
  void ItemBlocks(const CFX_RectF& rtText, size_t szBlockIndex);
  bool DrawString(CFX_RenderDevice* pFxDevice,
                  const CFX_Matrix& mtDoc2Device,
                  const CFX_RectF& rtClip,
                  size_t szBlockIndex);
  bool IsLoaded() const { return !m_pieceLines.empty(); }
  void Unload();
  bool HasBlock() const { return m_bHasBlock; }
  void ClearBlocks() { m_Blocks.clear(); }
  void ResetHasBlock() { m_bHasBlock = false; }
  const wchar_t* GetLinkURLAtPoint(const CFX_PointF& point);

 private:
  class TextPiece : public CFGAS_TextPiece {
   public:
    TextPiece();
    ~TextPiece();

    int32_t iUnderline = 0;
    int32_t iLineThrough = 0;
    XFA_AttributeValue iPeriod = XFA_AttributeValue::All;
    FX_ARGB dwColor = 0;
    RetainPtr<CFGAS_LinkUserData> pLinkData;
  };

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

    std::vector<std::unique_ptr<TextPiece>> m_textPieces;
    std::vector<size_t> m_charCounts;
  };

  struct BlockData {
    size_t szIndex;
    size_t szLength;
  };

  struct BlockHeight {
    size_t szBlockIndex;
    float fHeight;
  };

  struct LoaderContext {
    LoaderContext();
    ~LoaderContext();

    void Trace(cppgc::Visitor* visitor) const;

    bool bSaveLineHeight = false;
    bool bFilterSpace = false;
    float fWidth = 0;
    float fHeight = 0;
    float fLastPos = 0;
    float fStartLineOffset = 0;
    int32_t iChar = 0;
    // TODO(thestig): Make this size_t?
    int32_t iTotalLines = -1;
    UnownedPtr<const CFX_XMLNode> pXMLNode;
    RetainPtr<CFX_CSSComputedStyle> pParentStyle;
    cppgc::Member<CXFA_Node> pNode;
    std::vector<float> lineHeights;
    std::vector<BlockHeight> blockHeights;
  };

  CXFA_TextLayout(CXFA_FFDoc* doc, CXFA_TextProvider* pTextProvider);

  void GetTextDataNode();
  CFX_XMLNode* GetXMLContainerNode();
  std::unique_ptr<CFGAS_RTFBreak> CreateBreak(bool bDefault);
  void InitBreak(float fLineWidth);
  void InitBreak(CFX_CSSComputedStyle* pStyle,
                 CFX_CSSDisplay eDisplay,
                 float fLineWidth,
                 const CFX_XMLNode* pXMLNode,
                 CFX_CSSComputedStyle* pParentStyle);
  void Loader(float textWidth, float* pLinePos, bool bSavePieces);
  void LoadText(CXFA_Node* pNode,
                float textWidth,
                float* pLinePos,
                bool bSavePieces);
  bool LoadRichText(const CFX_XMLNode* pXMLNode,
                    float textWidth,
                    float* pLinePos,
                    const RetainPtr<CFX_CSSComputedStyle>& pParentStyle,
                    bool bSavePieces,
                    RetainPtr<CFGAS_LinkUserData> pLinkData,
                    bool bEndBreak,
                    bool bIsOl,
                    int32_t iLiCount);
  bool AppendChar(const WideString& wsText,
                  float* pLinePos,
                  float fSpaceAbove,
                  bool bSavePieces);
  void AppendTextLine(CFGAS_Char::BreakType dwStatus,
                      float* pLinePos,
                      bool bSavePieces,
                      bool bEndBreak);
  void EndBreak(CFGAS_Char::BreakType dwStatus, float* pLinePos, bool bDefault);
  bool IsEnd(bool bSavePieces);
  void UpdateAlign(float fHeight, float fBottom);
  void RenderString(CFX_RenderDevice* pDevice,
                    PieceLine* pPieceLine,
                    size_t szPiece,
                    std::vector<TextCharPos>* pCharPos,
                    const CFX_Matrix& mtDoc2Device);
  void RenderPath(CFX_RenderDevice* pDevice,
                  const PieceLine* pPieceLine,
                  size_t szPiece,
                  std::vector<TextCharPos>* pCharPos,
                  const CFX_Matrix& mtDoc2Device);
  size_t GetDisplayPos(const TextPiece* pPiece,
                       std::vector<TextCharPos>* pCharPos);
  void DoTabstops(CFX_CSSComputedStyle* pStyle, PieceLine* pPieceLine);
  bool LayoutInternal(size_t szBlockIndex);
  size_t CountBlocks() const;
  size_t GetNextIndexFromLastBlockData() const;
  void UpdateLoaderHeight(float fTextHeight);

  bool m_bHasBlock = false;
  bool m_bRichText = false;
  int32_t m_iLines = 0;
  float m_fMaxWidth = 0;
  std::vector<BlockData> m_Blocks;
  cppgc::Member<CXFA_FFDoc> const m_pDoc;
  cppgc::Member<CXFA_TextProvider> const m_pTextProvider;
  cppgc::Member<CXFA_Node> m_pTextDataNode;
  cppgc::Member<CXFA_TextParser> m_pTextParser;
  std::unique_ptr<CFGAS_RTFBreak> m_pBreak;
  std::unique_ptr<LoaderContext> m_pLoader;
  std::vector<std::unique_ptr<PieceLine>> m_pieceLines;
  std::unique_ptr<CXFA_TextTabstopsContext> m_pTabstopContext;
};

#endif  // XFA_FXFA_CXFA_TEXTLAYOUT_H_
