// 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_FDE_CFDE_TEXTOUT_H_
#define XFA_FDE_CFDE_TEXTOUT_H_

#include <deque>
#include <memory>
#include <vector>

#include "core/fxge/fx_dib.h"
#include "third_party/base/span.h"
#include "xfa/fde/cfde_data.h"
#include "xfa/fgas/layout/cfx_char.h"

class CFDE_RenderDevice;
class CFGAS_GEFont;
class CFX_RenderDevice;
class CFX_TxtBreak;
class TextCharPos;

class CFDE_TextOut {
 public:
  static bool DrawString(CFX_RenderDevice* device,
                         FX_ARGB color,
                         const RetainPtr<CFGAS_GEFont>& pFont,
                         pdfium::span<TextCharPos> pCharPos,
                         float fFontSize,
                         const CFX_Matrix& matrix);

  CFDE_TextOut();
  ~CFDE_TextOut();

  void SetFont(const RetainPtr<CFGAS_GEFont>& pFont);
  void SetFontSize(float fFontSize);
  void SetTextColor(FX_ARGB color) { m_TxtColor = color; }
  void SetStyles(const FDE_TextStyle& dwStyles);
  void SetAlignment(FDE_TextAlignment iAlignment);
  void SetLineSpace(float fLineSpace);
  void SetMatrix(const CFX_Matrix& matrix) { m_Matrix = matrix; }
  void SetLineBreakTolerance(float fTolerance);

  void CalcLogicSize(WideStringView str, CFX_SizeF* pSize);
  void CalcLogicSize(WideStringView str, CFX_RectF* pRect);
  void DrawLogicText(CFX_RenderDevice* device,
                     WideStringView str,
                     const CFX_RectF& rect);
  int32_t GetTotalLines() const { return m_iTotalLines; }

 private:
  struct Piece {
    Piece();
    Piece(const Piece& that);
    ~Piece();

    int32_t iStartChar;
    int32_t iChars;
    uint32_t dwCharStyles;
    CFX_RectF rtPiece;
  };

  class Line {
   public:
    Line();
    Line(const Line& that);
    ~Line();

    bool new_reload() const { return new_reload_; }
    void set_new_reload(bool reload) { new_reload_ = reload; }

    int32_t AddPiece(int32_t index, const Piece& piece);
    int32_t GetSize() const;
    Piece* GetPieceAtIndex(int32_t index);
    void RemoveLast(int32_t count);

   private:
    bool new_reload_ = false;
    std::deque<Piece> pieces_;
  };

  bool RetrieveLineWidth(CFX_BreakType dwBreakStatus,
                         float* pStartPos,
                         float* pWidth,
                         float* pHeight);
  void LoadText(const WideString& str, const CFX_RectF& rect);

  void Reload(const CFX_RectF& rect);
  void ReloadLinePiece(Line* pLine, const CFX_RectF& rect);
  bool RetrievePieces(CFX_BreakType dwBreakStatus,
                      bool bReload,
                      const CFX_RectF& rect,
                      int32_t* pStartChar,
                      int32_t* pPieceWidths);
  void AppendPiece(const Piece& piece, bool bNeedReload, bool bEnd);
  void DoAlignment(const CFX_RectF& rect);
  size_t GetDisplayPos(Piece* pPiece);

  std::unique_ptr<CFX_TxtBreak> const m_pTxtBreak;
  RetainPtr<CFGAS_GEFont> m_pFont;
  float m_fFontSize = 12.0f;
  float m_fLineSpace = 12.0f;
  float m_fLinePos = 0.0f;
  float m_fTolerance = 0.0f;
  FDE_TextAlignment m_iAlignment = FDE_TextAlignment::kTopLeft;
  FDE_TextStyle m_Styles;
  std::vector<int32_t> m_CharWidths;
  FX_ARGB m_TxtColor = 0xFF000000;
  uint32_t m_dwTxtBkStyles = 0;
  WideString m_wsText;
  CFX_Matrix m_Matrix;
  std::deque<Line> m_ttoLines;
  int32_t m_iCurLine = 0;
  int32_t m_iCurPiece = 0;
  int32_t m_iTotalLines = 0;
  std::vector<TextCharPos> m_CharPos;
};

#endif  // XFA_FDE_CFDE_TEXTOUT_H_
