// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_MODEL_H_
#define UI_VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_MODEL_H_

#include <list>
#include <vector>

#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string16.h"
#include "ui/base/ime/composition_text.h"
#include "ui/gfx/render_text.h"
#include "ui/gfx/text_constants.h"
#include "ui/views/views_export.h"

namespace views {

namespace internal {
// Internal Edit class that keeps track of edits for undo/redo.
class Edit;

// The types of merge behavior implemented by Edit operations.
enum MergeType {
  // The edit should not usually be merged with next edit.
  DO_NOT_MERGE,
  // The edit should be merged with next edit when possible.
  MERGEABLE,
  // The edit should be merged with the prior edit, even if marked DO_NOT_MERGE.
  FORCE_MERGE,
};

}  // namespace internal

// A model that represents text content for a views::Textfield.
// It supports editing, selection and cursor manipulation.
class VIEWS_EXPORT TextfieldModel {
 public:
  // Delegate interface implemented by the textfield view class to provide
  // additional functionalities required by the model.
  class VIEWS_EXPORT Delegate {
   public:
    // Called when the current composition text is confirmed or cleared.
    virtual void OnCompositionTextConfirmedOrCleared() = 0;

   protected:
    virtual ~Delegate();
  };

  explicit TextfieldModel(Delegate* delegate);
  virtual ~TextfieldModel();

  // Edit related methods.

  const base::string16& text() const { return render_text_->text(); }
  // Sets the text. Returns true if the text has been modified.  The current
  // composition text will be confirmed first.  Setting the same text will not
  // add edit history because it's not user visible change nor user-initiated
  // change. This allow a client code to set the same text multiple times
  // without worrying about messing edit history.
  bool SetText(const base::string16& new_text);

  gfx::RenderText* render_text() { return render_text_.get(); }

  // Inserts given |new_text| at the current cursor position.
  // The current composition text will be cleared.
  void InsertText(const base::string16& new_text) {
    InsertTextInternal(new_text, false);
  }

  // Inserts a character at the current cursor position.
  void InsertChar(base::char16 c) {
    InsertTextInternal(base::string16(&c, 1), true);
  }

  // Replaces characters at the current position with characters in given text.
  // The current composition text will be cleared.
  void ReplaceText(const base::string16& new_text) {
    ReplaceTextInternal(new_text, false);
  }

  // Replaces the char at the current position with given character.
  void ReplaceChar(base::char16 c) {
    ReplaceTextInternal(base::string16(&c, 1), true);
  }

  // Appends the text.
  // The current composition text will be confirmed.
  void Append(const base::string16& new_text);

  // Deletes the first character after the current cursor position (as if, the
  // the user has pressed delete key in the textfield). Returns true if
  // the deletion is successful.
  // If there is composition text, it'll be deleted instead.
  bool Delete();

  // Deletes the first character before the current cursor position (as if, the
  // the user has pressed backspace key in the textfield). Returns true if
  // the removal is successful.
  // If there is composition text, it'll be deleted instead.
  bool Backspace();

  // Cursor related methods.

  // Returns the current cursor position.
  size_t GetCursorPosition() const;

  // Moves the cursor, see RenderText for additional details.
  // The current composition text will be confirmed.
  void MoveCursor(gfx::BreakType break_type,
                  gfx::VisualCursorDirection direction,
                  bool select);

  // Updates the cursor to the specified selection model. Any composition text
  // will be confirmed, which may alter the specified selection range start.
  bool MoveCursorTo(const gfx::SelectionModel& cursor);

  // Helper function to call MoveCursorTo on the TextfieldModel.
  bool MoveCursorTo(const gfx::Point& point, bool select);

  // Selection related methods.

  // Returns the selected text.
  base::string16 GetSelectedText() const;

  // The current composition text will be confirmed. The selection starts with
  // the range's start position, and ends with the range's end position,
  // therefore the cursor position becomes the end position.
  void SelectRange(const gfx::Range& range);

  // The current composition text will be confirmed.
  // render_text_'s selection model is set to |sel|.
  void SelectSelectionModel(const gfx::SelectionModel& sel);

  // Select the entire text range. If |reversed| is true, the range will end at
  // the logical beginning of the text; this generally shows the leading portion
  // of text that overflows its display area.
  // The current composition text will be confirmed.
  void SelectAll(bool reversed);

  // Selects the word at which the cursor is currently positioned. If there is a
  // non-empty selection, the selection bounds are extended to their nearest
  // word boundaries.
  // The current composition text will be confirmed.
  void SelectWord();

  // Clears selection.
  // The current composition text will be confirmed.
  void ClearSelection();

  // Returns true if there is an undoable edit.
  bool CanUndo();

  // Returns true if there is an redoable edit.
  bool CanRedo();

  // Undo edit. Returns true if undo changed the text.
  bool Undo();

  // Redo edit. Returns true if redo changed the text.
  bool Redo();

  // Cuts the currently selected text and puts it to clipboard. Returns true
  // if text has changed after cutting.
  bool Cut();

  // Copies the currently selected text and puts it to clipboard. Returns true
  // if something was copied to the clipboard.
  bool Copy();

  // Pastes text from the clipboard at current cursor position. Returns true
  // if any text is pasted.
  bool Paste();

  // Tells if any text is selected, even if the selection is in composition
  // text.
  bool HasSelection() const;

  // Deletes the selected text. This method shouldn't be called with
  // composition text.
  void DeleteSelection();

  // Deletes the selected text (if any) and insert text at given position.
  void DeleteSelectionAndInsertTextAt(const base::string16& new_text,
                                      size_t position);

  // Retrieves the text content in a given range.
  base::string16 GetTextFromRange(const gfx::Range& range) const;

  // Retrieves the range containing all text in the model.
  void GetTextRange(gfx::Range* range) const;

  // Sets composition text and attributes. If there is composition text already,
  // it'll be replaced by the new one. Otherwise, current selection will be
  // replaced. If there is no selection, the composition text will be inserted
  // at the insertion point.
  // Any changes to the model except text insertion will confirm the current
  // composition text.
  void SetCompositionText(const ui::CompositionText& composition);

  // Converts current composition text into final content.
  void ConfirmCompositionText();

  // Removes current composition text.
  void CancelCompositionText();

  // Retrieves the range of current composition text.
  void GetCompositionTextRange(gfx::Range* range) const;

  // Returns true if there is composition text.
  bool HasCompositionText() const;

  // Clears all edit history.
  void ClearEditHistory();

 private:
  friend class internal::Edit;

  FRIEND_TEST_ALL_PREFIXES(TextfieldModelTest, UndoRedo_BasicTest);
  FRIEND_TEST_ALL_PREFIXES(TextfieldModelTest, UndoRedo_CutCopyPasteTest);
  FRIEND_TEST_ALL_PREFIXES(TextfieldModelTest, UndoRedo_ReplaceTest);

  // Insert the given |new_text|. |mergeable| indicates if this insert operation
  // can be merged with previous edits in the history.
  void InsertTextInternal(const base::string16& new_text, bool mergeable);

  // Replace the current text with the given |new_text|. |mergeable| indicates
  // if this replace operation can be merged with previous edits in the history.
  void ReplaceTextInternal(const base::string16& new_text, bool mergeable);

  // Clears redo history.
  void ClearRedoHistory();

  // Executes and records edit operations.
  void ExecuteAndRecordDelete(gfx::Range range, bool mergeable);
  void ExecuteAndRecordReplaceSelection(internal::MergeType merge_type,
                                        const base::string16& new_text);
  void ExecuteAndRecordReplace(internal::MergeType merge_type,
                               size_t old_cursor_pos,
                               size_t new_cursor_pos,
                               const base::string16& new_text,
                               size_t new_text_start);
  void ExecuteAndRecordInsert(const base::string16& new_text, bool mergeable);

  // Adds or merge |edit| into edit history. Return true if the edit
  // has been merged and must be deleted after redo.
  bool AddOrMergeEditHistory(internal::Edit* edit);

  // Modify the text buffer in following way:
  // 1) Delete the string from |delete_from| to |delte_to|.
  // 2) Insert the |new_text| at the index |new_text_insert_at|.
  //    Note that the index is after deletion.
  // 3) Move the cursor to |new_cursor_pos|.
  void ModifyText(size_t delete_from,
                  size_t delete_to,
                  const base::string16& new_text,
                  size_t new_text_insert_at,
                  size_t new_cursor_pos);

  void ClearComposition();

  // The TextfieldModel::Delegate instance should be provided by the owner.
  Delegate* delegate_;

  // The stylized text, cursor, selection, and the visual layout model.
  scoped_ptr<gfx::RenderText> render_text_;

  typedef std::list<internal::Edit*> EditHistory;
  EditHistory edit_history_;

  // An iterator that points to the current edit that can be undone.
  // This iterator moves from the |end()|, meaining no edit to undo,
  // to the last element (one before |end()|), meaning no edit to redo.
  //
  // There is no edit to undo (== end()) when:
  //   1) in initial state. (nothing to undo)
  //   2) very 1st edit is undone.
  //   3) all edit history is removed.
  // There is no edit to redo (== last element or no element) when:
  //   1) in initial state. (nothing to redo)
  //   2) new edit is added. (redo history is cleared)
  //   3) redone all undone edits.
  EditHistory::iterator current_edit_;

  DISALLOW_COPY_AND_ASSIGN(TextfieldModel);
};

}  // namespace views

#endif  // UI_VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_MODEL_H_
