// 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_FDE_CFDE_TEXTEDITENGINE_H_
#define XFA_FDE_CFDE_TEXTEDITENGINE_H_

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

#include "core/fxcrt/fx_string.h"
#include "core/fxcrt/retain_ptr.h"
#include "core/fxge/cfx_renderdevice.h"
#include "core/fxge/fx_dib.h"
#include "xfa/fgas/font/cfgas_gefont.h"
#include "xfa/fgas/layout/cfx_txtbreak.h"

struct FDE_TEXTEDITPIECE {
  FDE_TEXTEDITPIECE();
  FDE_TEXTEDITPIECE(const FDE_TEXTEDITPIECE& that);
  ~FDE_TEXTEDITPIECE();

  int32_t nStart = 0;
  int32_t nCount = 0;
  int32_t nBidiLevel = 0;
  CFX_RectF rtPiece;
  uint32_t dwCharStyles = 0;
};

inline FDE_TEXTEDITPIECE::FDE_TEXTEDITPIECE() = default;
inline FDE_TEXTEDITPIECE::FDE_TEXTEDITPIECE(const FDE_TEXTEDITPIECE& that) =
    default;
inline FDE_TEXTEDITPIECE::~FDE_TEXTEDITPIECE() = default;

class CFDE_TextEditEngine {
 public:
  class Iterator {
   public:
    explicit Iterator(const CFDE_TextEditEngine* engine);
    ~Iterator();

    void Next(bool bPrev);
    wchar_t GetChar() const;
    void SetAt(size_t nIndex);
    size_t FindNextBreakPos(bool bPrev);
    bool IsEOF(bool bPrev) const;

   private:
    UnownedPtr<const CFDE_TextEditEngine> engine_;
    int32_t current_position_;
  };

  class Operation {
   public:
    virtual ~Operation() = default;
    virtual void Redo() const = 0;
    virtual void Undo() const = 0;
  };

  class Delegate {
   public:
    virtual ~Delegate() = default;
    virtual void NotifyTextFull() = 0;
    virtual void OnCaretChanged() = 0;
    virtual void OnTextChanged(const WideString& prevText) = 0;
    virtual void OnSelChanged() = 0;
    virtual bool OnValidate(const WideString& wsText) = 0;
    virtual void SetScrollOffset(float fScrollOffset) = 0;
  };

  enum class RecordOperation {
    kInsertRecord,
    kSkipRecord,
  };

  CFDE_TextEditEngine();
  ~CFDE_TextEditEngine();

  void SetDelegate(Delegate* delegate) { delegate_ = delegate; }
  void Clear();

  void Insert(size_t idx,
              const WideString& text,
              RecordOperation add_operation = RecordOperation::kInsertRecord);
  WideString Delete(
      size_t start_idx,
      size_t length,
      RecordOperation add_operation = RecordOperation::kInsertRecord);
  WideString GetText() const;
  size_t GetLength() const;

  // Non-const so we can force a layout.
  CFX_RectF GetContentsBoundingBox();
  void SetAvailableWidth(size_t width);

  void SetFont(RetainPtr<CFGAS_GEFont> font);
  RetainPtr<CFGAS_GEFont> GetFont() const { return font_; }
  void SetFontSize(float size);
  float GetFontSize() const { return font_size_; }
  void SetFontColor(FX_ARGB color) { font_color_ = color; }
  FX_ARGB GetFontColor() const { return font_color_; }
  float GetFontAscent() const {
    return (static_cast<float>(font_->GetAscent()) * font_size_) / 1000;
  }

  void SetAlignment(uint32_t alignment);
  float GetLineSpace() const { return line_spacing_; }
  void SetLineSpace(float space) { line_spacing_ = space; }
  void SetAliasChar(wchar_t alias) { password_alias_ = alias; }
  void SetHasCharacterLimit(bool limit);
  void SetCharacterLimit(size_t limit);
  void SetCombText(bool enable);
  void SetTabWidth(float width);
  void SetVisibleLineCount(size_t lines);

  void EnableValidation(bool val) { validation_enabled_ = val; }
  void EnablePasswordMode(bool val) { password_mode_ = val; }
  void EnableMultiLine(bool val);
  void EnableLineWrap(bool val);
  void LimitHorizontalScroll(bool val);
  void LimitVerticalScroll(bool val);

  bool CanUndo() const;
  bool CanRedo() const;
  bool Redo();
  bool Undo();
  void ClearOperationRecords();

  // This is not const it can trigger a |Layout|.
  size_t GetIndexBefore(size_t pos);
  size_t GetIndexLeft(size_t pos) const;
  size_t GetIndexRight(size_t pos) const;
  size_t GetIndexUp(size_t pos) const;
  size_t GetIndexDown(size_t pos) const;
  size_t GetIndexAtStartOfLine(size_t pos) const;
  size_t GetIndexAtEndOfLine(size_t pos) const;

  void SelectAll();
  void SetSelection(size_t start_idx, size_t count);
  void ClearSelection();
  bool HasSelection() const { return has_selection_; }
  // Returns <start_idx, count> of the selection.
  std::pair<size_t, size_t> GetSelection() const {
    return {selection_.start_idx, selection_.count};
  }
  WideString GetSelectedText() const;
  WideString DeleteSelectedText(
      RecordOperation add_operation = RecordOperation::kInsertRecord);
  void ReplaceSelectedText(const WideString& str);

  void Layout();

  wchar_t GetChar(size_t idx) const;
  // Non-const so we can force a Layout() if needed.
  size_t GetWidthOfChar(size_t idx);
  // Non-const so we can force a Layout() if needed.
  size_t GetIndexForPoint(const CFX_PointF& point);
  // <start_idx, count>
  std::pair<size_t, size_t> BoundsForWordAt(size_t idx) const;

  // Returns <bidi level, character rect>
  std::pair<int32_t, CFX_RectF> GetCharacterInfo(int32_t start_idx);
  std::vector<CFX_RectF> GetCharacterRectsInRange(int32_t start_idx,
                                                  int32_t count);

  CFX_TxtBreak* GetTextBreak() { return &text_break_; }

  const std::vector<FDE_TEXTEDITPIECE>& GetTextPieces() {
    // Force a layout if needed.
    Layout();
    return text_piece_info_;
  }

  std::vector<FXTEXT_CHARPOS> GetDisplayPos(const FDE_TEXTEDITPIECE& info);

  void SetMaxEditOperationsForTesting(size_t max);

 private:
  void SetCombTextWidth();
  void AdjustGap(size_t idx, size_t length);
  void RebuildPieces();
  size_t CountCharsExceedingSize(const WideString& str, size_t num_to_check);
  void AddOperationRecord(std::unique_ptr<Operation> op);

  bool IsAlignedRight() const {
    return !!(character_alignment_ & CFX_TxtLineAlignment_Left);
  }

  bool IsAlignedCenter() const {
    return !!(character_alignment_ & CFX_TxtLineAlignment_Center);
  }
  std::vector<CFX_RectF> GetCharRects(const FDE_TEXTEDITPIECE& piece);

  struct Selection {
    size_t start_idx;
    size_t count;
  };

  CFX_RectF contents_bounding_box_;
  UnownedPtr<Delegate> delegate_;
  std::vector<FDE_TEXTEDITPIECE> text_piece_info_;
  std::vector<size_t> char_widths_;
  CFX_TxtBreak text_break_;
  RetainPtr<CFGAS_GEFont> font_;
  FX_ARGB font_color_;
  float font_size_;
  float line_spacing_;
  std::vector<WideString::CharType> content_;
  size_t text_length_;
  size_t gap_position_;
  size_t gap_size_;
  size_t available_width_;
  size_t character_limit_;
  size_t visible_line_count_;
  // Ring buffer of edit operations
  std::vector<std::unique_ptr<Operation>> operation_buffer_;
  // Next edit operation to undo.
  size_t next_operation_index_to_undo_;
  // Next index to insert an edit operation into.
  size_t next_operation_index_to_insert_;
  size_t max_edit_operations_;
  uint32_t character_alignment_;
  bool has_character_limit_;
  bool is_comb_text_;
  bool is_dirty_;
  bool validation_enabled_;
  bool is_multiline_;
  bool is_linewrap_enabled_;
  bool limit_horizontal_area_;
  bool limit_vertical_area_;
  bool password_mode_;
  wchar_t password_alias_;
  bool has_selection_;
  Selection selection_;
};

#endif  // XFA_FDE_CFDE_TEXTEDITENGINE_H_
