// 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 FPDFSDK_PWL_CPWL_EDIT_IMPL_H_
#define FPDFSDK_PWL_CPWL_EDIT_IMPL_H_

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

#include "core/fpdfdoc/cpdf_variabletext.h"
#include "core/fpdfdoc/cpvt_wordrange.h"
#include "core/fxcrt/unowned_ptr.h"
#include "core/fxge/fx_dib.h"

#define FX_EDIT_ISLATINWORD(u)                  \
  (u == 0x2D || (u <= 0x005A && u >= 0x0041) || \
   (u <= 0x007A && u >= 0x0061) || (u <= 0x02AF && u >= 0x00C0))

class CFFL_FormFiller;
class CPWL_EditImpl;
class CPWL_EditImpl_Iterator;
class CPWL_EditImpl_Provider;
class CFX_RenderDevice;
class CPWL_Edit;
class CPWL_EditCtrl;
class IPWL_SystemHandler;
class IFX_Edit_UndoItem;

struct CPWL_EditImpl_LineRect {
  CPWL_EditImpl_LineRect(const CPVT_WordRange& wrLine,
                         const CFX_FloatRect& rcLine)
      : m_wrLine(wrLine), m_rcLine(rcLine) {}

  CPVT_WordRange m_wrLine;
  CFX_FloatRect m_rcLine;
};

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

  void BeginRefresh();
  void Push(const CPVT_WordRange& linerange, const CFX_FloatRect& rect);
  void NoAnalyse();
  std::vector<CFX_FloatRect>* GetRefreshRects();
  void EndRefresh();

 private:
  void Add(const CFX_FloatRect& new_rect);

  std::vector<CPWL_EditImpl_LineRect> m_NewLineRects;
  std::vector<CPWL_EditImpl_LineRect> m_OldLineRects;
  std::vector<CFX_FloatRect> m_RefreshRects;
};

class CPWL_EditImpl_Select {
 public:
  CPWL_EditImpl_Select();
  explicit CPWL_EditImpl_Select(const CPVT_WordRange& range);

  void Reset();
  void Set(const CPVT_WordPlace& begin, const CPVT_WordPlace& end);
  void SetEndPos(const CPVT_WordPlace& end);

  CPVT_WordRange ConvertToWordRange() const;
  bool IsEmpty() const;

  CPVT_WordPlace BeginPos;
  CPVT_WordPlace EndPos;
};

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

  void AddItem(std::unique_ptr<IFX_Edit_UndoItem> pItem);
  void Undo();
  void Redo();
  bool CanUndo() const;
  bool CanRedo() const;

 private:
  void RemoveHeads();
  void RemoveTails();

  std::deque<std::unique_ptr<IFX_Edit_UndoItem>> m_UndoItemStack;
  size_t m_nCurUndoPos;
  bool m_bWorking;
};

class IFX_Edit_UndoItem {
 public:
  virtual ~IFX_Edit_UndoItem() = default;

  // Undo/Redo the current undo item and returns the number of additional items
  // to be processed in |m_UndoItemStack| to fully undo/redo the action. (An
  // example is CFXEU_ReplaceSelection::Undo(), if CFXEU_ReplaceSelection marks
  // the end of a replace action, CFXEU_ReplaceSelection::Undo() returns 3
  // because 3 more undo items need to be processed to revert the replace
  // action: insert text, clear selection and the CFXEU_ReplaceSelection which
  // marks the beginning of replace action.) Implementations should return 0 by
  // default.
  virtual int Undo() = 0;
  virtual int Redo() = 0;
};

class CFXEU_InsertWord final : public IFX_Edit_UndoItem {
 public:
  CFXEU_InsertWord(CPWL_EditImpl* pEdit,
                   const CPVT_WordPlace& wpOldPlace,
                   const CPVT_WordPlace& wpNewPlace,
                   uint16_t word,
                   int32_t charset);
  ~CFXEU_InsertWord() override;

  // IFX_Edit_UndoItem:
  int Redo() override;
  int Undo() override;

 private:
  UnownedPtr<CPWL_EditImpl> m_pEdit;

  CPVT_WordPlace m_wpOld;
  CPVT_WordPlace m_wpNew;
  uint16_t m_Word;
  int32_t m_nCharset;
};

class CFXEU_InsertReturn final : public IFX_Edit_UndoItem {
 public:
  CFXEU_InsertReturn(CPWL_EditImpl* pEdit,
                     const CPVT_WordPlace& wpOldPlace,
                     const CPVT_WordPlace& wpNewPlace);
  ~CFXEU_InsertReturn() override;

  // IFX_Edit_UndoItem:
  int Redo() override;
  int Undo() override;

 private:
  UnownedPtr<CPWL_EditImpl> m_pEdit;

  CPVT_WordPlace m_wpOld;
  CPVT_WordPlace m_wpNew;
};

class CFXEU_ReplaceSelection final : public IFX_Edit_UndoItem {
 public:
  CFXEU_ReplaceSelection(CPWL_EditImpl* pEdit, bool bIsEnd);
  ~CFXEU_ReplaceSelection() override;

  // IFX_Edit_UndoItem:
  int Redo() override;
  int Undo() override;

 private:
  bool IsEnd() const { return m_bEnd; }

  UnownedPtr<CPWL_EditImpl> m_pEdit;
  const bool m_bEnd;  // indicate whether this is the end of replace action
};

class CFXEU_Backspace final : public IFX_Edit_UndoItem {
 public:
  CFXEU_Backspace(CPWL_EditImpl* pEdit,
                  const CPVT_WordPlace& wpOldPlace,
                  const CPVT_WordPlace& wpNewPlace,
                  uint16_t word,
                  int32_t charset);
  ~CFXEU_Backspace() override;

  // IFX_Edit_UndoItem:
  int Redo() override;
  int Undo() override;

 private:
  UnownedPtr<CPWL_EditImpl> m_pEdit;

  CPVT_WordPlace m_wpOld;
  CPVT_WordPlace m_wpNew;
  uint16_t m_Word;
  int32_t m_nCharset;
};

class CFXEU_Delete final : public IFX_Edit_UndoItem {
 public:
  CFXEU_Delete(CPWL_EditImpl* pEdit,
               const CPVT_WordPlace& wpOldPlace,
               const CPVT_WordPlace& wpNewPlace,
               uint16_t word,
               int32_t charset,
               bool bSecEnd);
  ~CFXEU_Delete() override;

  // IFX_Edit_UndoItem:
  int Redo() override;
  int Undo() override;

 private:
  UnownedPtr<CPWL_EditImpl> m_pEdit;

  CPVT_WordPlace m_wpOld;
  CPVT_WordPlace m_wpNew;
  uint16_t m_Word;
  int32_t m_nCharset;
  bool m_bSecEnd;
};

class CFXEU_Clear final : public IFX_Edit_UndoItem {
 public:
  CFXEU_Clear(CPWL_EditImpl* pEdit,
              const CPVT_WordRange& wrSel,
              const WideString& swText);
  ~CFXEU_Clear() override;

  // IFX_Edit_UndoItem:
  int Redo() override;
  int Undo() override;

 private:
  UnownedPtr<CPWL_EditImpl> m_pEdit;

  CPVT_WordRange m_wrSel;
  WideString m_swText;
};

class CFXEU_InsertText final : public IFX_Edit_UndoItem {
 public:
  CFXEU_InsertText(CPWL_EditImpl* pEdit,
                   const CPVT_WordPlace& wpOldPlace,
                   const CPVT_WordPlace& wpNewPlace,
                   const WideString& swText,
                   int32_t charset);
  ~CFXEU_InsertText() override;

  // IFX_Edit_UndoItem:
  int Redo() override;
  int Undo() override;

 private:
  UnownedPtr<CPWL_EditImpl> m_pEdit;

  CPVT_WordPlace m_wpOld;
  CPVT_WordPlace m_wpNew;
  WideString m_swText;
  int32_t m_nCharset;
};

class CPWL_EditImpl {
 public:
  static void DrawEdit(CFX_RenderDevice* pDevice,
                       const CFX_Matrix& mtUser2Device,
                       CPWL_EditImpl* pEdit,
                       FX_COLORREF crTextFill,
                       const CFX_FloatRect& rcClip,
                       const CFX_PointF& ptOffset,
                       const CPVT_WordRange* pRange,
                       IPWL_SystemHandler* pSystemHandler,
                       CFFL_FormFiller* pFFLData);

  CPWL_EditImpl();
  ~CPWL_EditImpl();

  void SetFontMap(IPVT_FontMap* pFontMap);
  void SetNotify(CPWL_EditCtrl* pNotify);
  void SetOperationNotify(CPWL_Edit* pOperationNotify);

  // Returns an iterator for the contents. Should not be released.
  CPWL_EditImpl_Iterator* GetIterator();
  IPVT_FontMap* GetFontMap();
  void Initialize();

  // Set the bounding box of the text area.
  void SetPlateRect(const CFX_FloatRect& rect);
  void SetScrollPos(const CFX_PointF& point);

  // Set the horizontal text alignment. (nFormat [0:left, 1:middle, 2:right])
  void SetAlignmentH(int32_t nFormat, bool bPaint);
  // Set the vertical text alignment. (nFormat [0:left, 1:middle, 2:right])
  void SetAlignmentV(int32_t nFormat, bool bPaint);

  // Set the substitution character for hidden text.
  void SetPasswordChar(uint16_t wSubWord, bool bPaint);

  // Set the maximum number of words in the text.
  void SetLimitChar(int32_t nLimitChar);
  void SetCharArray(int32_t nCharArray);
  void SetCharSpace(float fCharSpace);
  void SetMultiLine(bool bMultiLine, bool bPaint);
  void SetAutoReturn(bool bAuto, bool bPaint);
  void SetAutoFontSize(bool bAuto, bool bPaint);
  void SetAutoScroll(bool bAuto, bool bPaint);
  void SetFontSize(float fFontSize);
  void SetTextOverflow(bool bAllowed, bool bPaint);
  void OnMouseDown(const CFX_PointF& point, bool bShift, bool bCtrl);
  void OnMouseMove(const CFX_PointF& point, bool bShift, bool bCtrl);
  void OnVK_UP(bool bShift, bool bCtrl);
  void OnVK_DOWN(bool bShift, bool bCtrl);
  void OnVK_LEFT(bool bShift, bool bCtrl);
  void OnVK_RIGHT(bool bShift, bool bCtrl);
  void OnVK_HOME(bool bShift, bool bCtrl);
  void OnVK_END(bool bShift, bool bCtrl);
  void SetText(const WideString& sText);
  bool InsertWord(uint16_t word, int32_t charset);
  bool InsertReturn();
  bool Backspace();
  bool Delete();
  bool ClearSelection();
  bool InsertText(const WideString& sText, int32_t charset);
  void ReplaceSelection(const WideString& text);
  bool Redo();
  bool Undo();
  CPVT_WordPlace WordIndexToWordPlace(int32_t index) const;
  CPVT_WordPlace SearchWordPlace(const CFX_PointF& point) const;
  int32_t GetCaret() const;
  CPVT_WordPlace GetCaretWordPlace() const;
  WideString GetSelectedText() const;
  WideString GetText() const;
  float GetFontSize() const;
  uint16_t GetPasswordChar() const;
  CFX_PointF GetScrollPos() const;
  int32_t GetCharArray() const;
  CFX_FloatRect GetContentRect() const;
  WideString GetRangeText(const CPVT_WordRange& range) const;
  float GetCharSpace() const;
  void SetSelection(int32_t nStartChar, int32_t nEndChar);
  std::pair<int32_t, int32_t> GetSelection() const;
  void SelectAll();
  void SelectNone();
  bool IsSelected() const;
  void Paint();
  void EnableRefresh(bool bRefresh);
  void RefreshWordRange(const CPVT_WordRange& wr);
  CPVT_WordRange GetWholeWordRange() const;
  CPVT_WordRange GetSelectWordRange() const;
  void EnableUndo(bool bUndo);
  bool IsTextFull() const;
  bool IsTextOverflow() const;
  bool CanUndo() const;
  bool CanRedo() const;
  CPVT_WordRange GetVisibleWordRange() const;

  bool Clear();

  CPVT_WordPlace DoInsertText(const CPVT_WordPlace& place,
                              const WideString& sText,
                              int32_t charset);
  int32_t GetCharSetFromUnicode(uint16_t word, int32_t nOldCharset);

  int32_t GetTotalLines() const;

  ByteString GetPDFWordString(int32_t nFontIndex,
                              uint16_t Word,
                              uint16_t SubWord);

  void SetSelection(const CPVT_WordPlace& begin, const CPVT_WordPlace& end);

  bool Delete(bool bAddUndo, bool bPaint);
  bool Clear(bool bAddUndo, bool bPaint);
  bool InsertText(const WideString& sText,
                  int32_t charset,
                  bool bAddUndo,
                  bool bPaint);
  bool InsertWord(uint16_t word, int32_t charset, bool bAddUndo, bool bPaint);
  bool InsertReturn(bool bAddUndo, bool bPaint);
  bool Backspace(bool bAddUndo, bool bPaint);
  void SetCaret(const CPVT_WordPlace& place);

  CFX_PointF VTToEdit(const CFX_PointF& point) const;

 private:
  void RearrangeAll();
  void RearrangePart(const CPVT_WordRange& range);
  void ScrollToCaret();
  void SetScrollInfo();
  void SetScrollPosX(float fx);
  void SetScrollPosY(float fy);
  void SetScrollLimit();
  void SetContentChanged();

  void PaintInsertText(const CPVT_WordPlace& wpOld,
                       const CPVT_WordPlace& wpNew);

  CFX_PointF EditToVT(const CFX_PointF& point) const;
  CFX_FloatRect VTToEdit(const CFX_FloatRect& rect) const;

  void Refresh();
  void RefreshPushLineRects(const CPVT_WordRange& wr);

  void SetCaretInfo();
  void SetCaretOrigin();

  void AddEditUndoItem(std::unique_ptr<IFX_Edit_UndoItem> pEditUndoItem);

  std::unique_ptr<CPWL_EditImpl_Provider> m_pVTProvider;
  std::unique_ptr<CPDF_VariableText> m_pVT;  // Must outlive |m_pVTProvider|.
  UnownedPtr<CPWL_EditCtrl> m_pNotify;
  UnownedPtr<CPWL_Edit> m_pOperationNotify;
  CPVT_WordPlace m_wpCaret;
  CPVT_WordPlace m_wpOldCaret;
  CPWL_EditImpl_Select m_SelState;
  CFX_PointF m_ptScrollPos;
  CFX_PointF m_ptRefreshScrollPos;
  bool m_bEnableScroll;
  std::unique_ptr<CPWL_EditImpl_Iterator> m_pIterator;
  CPWL_EditImpl_Refresh m_Refresh;
  CFX_PointF m_ptCaret;
  CPWL_EditImpl_Undo m_Undo;
  int32_t m_nAlignment;
  bool m_bNotifyFlag;
  bool m_bEnableOverflow;
  bool m_bEnableRefresh;
  CFX_FloatRect m_rcOldContent;
  bool m_bEnableUndo;
};

class CPWL_EditImpl_Iterator {
 public:
  CPWL_EditImpl_Iterator(CPWL_EditImpl* pEdit,
                         CPDF_VariableText::Iterator* pVTIterator);
  ~CPWL_EditImpl_Iterator();

  bool NextWord();
  bool PrevWord();
  bool GetWord(CPVT_Word& word) const;
  bool GetLine(CPVT_Line& line) const;
  void SetAt(int32_t nWordIndex);
  void SetAt(const CPVT_WordPlace& place);
  const CPVT_WordPlace& GetAt() const;

 private:
  UnownedPtr<CPWL_EditImpl> m_pEdit;
  CPDF_VariableText::Iterator* m_pVTIterator;
};

class CPWL_EditImpl_Provider final : public CPDF_VariableText::Provider {
 public:
  explicit CPWL_EditImpl_Provider(IPVT_FontMap* pFontMap);
  ~CPWL_EditImpl_Provider() override;

  IPVT_FontMap* GetFontMap() const;

  // CPDF_VariableText::Provider:
  uint32_t GetCharWidth(int32_t nFontIndex, uint16_t word) override;
  int32_t GetTypeAscent(int32_t nFontIndex) override;
  int32_t GetTypeDescent(int32_t nFontIndex) override;
  int32_t GetWordFontIndex(uint16_t word,
                           int32_t charset,
                           int32_t nFontIndex) override;
  int32_t GetDefaultFontIndex() override;
  bool IsLatinWord(uint16_t word) override;

 private:
  IPVT_FontMap* m_pFontMap;
};

#endif  // FPDFSDK_PWL_CPWL_EDIT_IMPL_H_
