// Copyright (c) 2011 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 VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_VIEWS_MODEL_H_
#define VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_VIEWS_MODEL_H_
#pragma once

#include <list>
#include <vector>

#include "base/gtest_prod_util.h"
#include "base/memory/scoped_ptr.h"
#include "base/string16.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/ime/composition_text.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/render_text.h"
#include "views/views_export.h"

namespace gfx {
class RenderText;
}  // namespace gfx

namespace ui {
class Range;
}  // namespace ui

namespace views {

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

// C++ doesn't allow forward decl enum, so let's define here.
enum MergeType {
  // The edit should not be merged with next edit. It still may
  // be merged with an edit with MERGE_WITH_PREVIOUS.
  DO_NOT_MERGE,
  // The edit can be merged with next edit when possible.
  MERGEABLE,
  // Does the edit have to be merged with previous edit?
  // This forces the merge even if the previous edit is marked
  // as DO_NOT_MERGE.
  MERGE_WITH_PREVIOUS,
};

}  // namespace internal

// A model that represents a text content for TextfieldViews.
// It supports editing, selection and cursor manipulation.
class VIEWS_EXPORT TextfieldViewsModel {
 public:
  // Delegate interface implemented by the textfield view class to provided
  // 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 TextfieldViewsModel(Delegate* delegate);
  virtual ~TextfieldViewsModel();

  void set_is_password(bool is_password) {
    is_password_ = is_password;
  }

  // Edit related methods.

  const string16& GetText() const;
  // 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 string16& text);

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

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

  // Inserts a character at the current cursor position.
  void InsertChar(char16 c) {
    InsertTextInternal(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 string16& text) {
    ReplaceTextInternal(text, false);
  }

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

  // Appends the text.
  // The current composition text will be confirmed.
  void Append(const string16& 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 MoveCursorLeft(gfx::BreakType break_type, bool select);
  void MoveCursorRight(gfx::BreakType break_type, bool select);

  // Moves the selection to the specified selection in |selection|.
  // If there is composition text, it will be confirmed, which will update the
  // selection range, and it overrides the selection_start to which the
  // selection will move to.
  bool MoveCursorTo(const gfx::SelectionModel& selection);

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

  // Selection related method

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

  // Gets the selected range.
  void GetSelectedRange(ui::Range* range) 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 ui::Range& range);

  void GetSelectionModel(gfx::SelectionModel* sel) const;

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

  // Selects all text.
  // The current composition text will be confirmed.
  void SelectAll();

  // Selects the word at which the cursor is currently positioned.
  // 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();

  // Returns visible text. If the field is password, it returns the
  // sequence of "*".
  string16 GetVisibleText() const;

  // 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.
  void Copy();

  // Pastes text from the clipboard at current cursor position. Returns true
  // if text has changed after pasting.
  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 string16& text, size_t position);

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

  // Retrieves the range containing all text in the model.
  void GetTextRange(ui::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(ui::Range* range) const;

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

 private:
  friend class NativeTextfieldViews;
  friend class NativeTextfieldViewsTest;
  friend class TextfieldViewsModelTest;
  friend class UndoRedo_BasicTest;
  friend class UndoRedo_CutCopyPasteTest;
  friend class UndoRedo_ReplaceTest;
  friend class internal::Edit;

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

  // Returns the visible text given |start| and |end|.
  string16 GetVisibleText(size_t start, size_t end) const;

  // Insert the given |text|. |mergeable| indicates if this insert
  // operation can be merged to previous edit in the edit history.
  void InsertTextInternal(const string16& text, bool mergeable);

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

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

  // Clears redo history.
  void ClearRedoHistory();

  // Executes and records edit operations.
  void ExecuteAndRecordDelete(size_t from, size_t to, bool mergeable);
  void ExecuteAndRecordReplaceSelection(internal::MergeType merge_type,
                                        const string16& text);
  void ExecuteAndRecordReplace(internal::MergeType merge_type,
                               size_t old_cursor_pos,
                               size_t new_cursor_pos,
                               const string16& text,
                               size_t new_text_start);
  void ExecuteAndRecordInsert(const string16& 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 string16& new_text,
                  size_t new_text_insert_at,
                  size_t new_cursor_pos);

  void ClearComposition();

  // Pointer to a TextfieldViewsModel::Delegate instance, should be provided by
  // the View object.
  Delegate* delegate_;

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

  // True if the text is the password.
  bool is_password_;

  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(TextfieldViewsModel);
};

}  // namespace views

#endif  // VIEWS_CONTROLS_TEXTFIELD_TEXTFIELD_VIEWS_MODEL_H_
